1- 'use strict' ;
2-
31/**
42 * THREE.GCodeLoader is used to load gcode files usually used for 3D printing or CNC applications.
53 *
108 * @author tentone
119 * @author joewalnes
1210 */
11+
1312THREE . GCodeLoader = function ( manager ) {
1413
1514 this . manager = ( manager !== undefined ) ? manager : THREE . DefaultLoadingManager ;
@@ -18,208 +17,214 @@ THREE.GCodeLoader = function ( manager ) {
1817
1918} ;
2019
21- THREE . GCodeLoader . prototype . load = function ( url , onLoad , onProgress , onError ) {
20+ THREE . GCodeLoader . prototype = {
2221
23- var self = this ;
22+ constructor : THREE . GCodeLoader ,
2423
25- var loader = new THREE . FileLoader ( self . manager ) ;
26- loader . setPath ( self . path ) ;
27- loader . load ( url , function ( text ) {
24+ load : function ( url , onLoad , onProgress , onError ) {
2825
29- onLoad ( self . parse ( text ) ) ;
26+ var self = this ;
3027
31- } , onProgress , onError ) ;
28+ var loader = new THREE . FileLoader ( self . manager ) ;
29+ loader . setPath ( self . path ) ;
30+ loader . load ( url , function ( text ) {
3231
33- } ;
32+ onLoad ( self . parse ( text ) ) ;
3433
35- THREE . GCodeLoader . prototype . setPath = function ( value ) {
34+ } , onProgress , onError ) ;
3635
37- this . path = value ;
38- return this ;
36+ } ,
3937
40- } ;
38+ setPath : function ( value ) {
4139
42- THREE . GCodeLoader . prototype . parse = function ( data ) {
40+ this . path = value ;
41+ return this ;
4342
44- var state = { x : 0 , y : 0 , z : 0 , e : 0 , f : 0 , extruding : false , relative : false } ;
45- var layers = [ ] ;
43+ } ,
4644
47- var currentLayer = undefined ;
45+ parse : function ( data ) {
4846
49- var pathMaterial = new THREE . LineBasicMaterial ( { color : 0xFF0000 } ) ;
50- pathMaterial . name = 'path' ;
47+ var state = { x : 0 , y : 0 , z : 0 , e : 0 , f : 0 , extruding : false , relative : false } ;
48+ var layers = [ ] ;
5149
52- var extrudingMaterial = new THREE . LineBasicMaterial ( { color : 0x00FF00 } ) ;
53- extrudingMaterial . name = 'extruded' ;
50+ var currentLayer = undefined ;
5451
55- function newLayer ( line ) {
52+ var pathMaterial = new THREE . LineBasicMaterial ( { color : 0xFF0000 } ) ;
53+ pathMaterial . name = 'path' ;
5654
57- currentLayer = { vertex : [ ] , pathVertex : [ ] , z : line . z } ;
58- layers . push ( currentLayer ) ;
55+ var extrudingMaterial = new THREE . LineBasicMaterial ( { color : 0x00FF00 } ) ;
56+ extrudingMaterial . name = 'extruded' ;
5957
60- }
58+ function newLayer ( line ) {
6159
62- //Create lie segment between p1 and p2
63- function addSegment ( p1 , p2 ) {
60+ currentLayer = { vertex : [ ] , pathVertex : [ ] , z : line . z } ;
61+ layers . push ( currentLayer ) ;
6462
65- if ( currentLayer === undefined ) {
63+ }
6664
67- newLayer ( p1 ) ;
65+ //Create lie segment between p1 and p2
66+ function addSegment ( p1 , p2 ) {
6867
69- }
68+ if ( currentLayer === undefined ) {
7069
71- if ( line . extruding ) {
70+ newLayer ( p1 ) ;
7271
73- currentLayer . vertex . push ( p1 . x , p1 . y , p1 . z ) ;
74- currentLayer . vertex . push ( p2 . x , p2 . y , p2 . z ) ;
72+ }
7573
76- } else {
74+ if ( line . extruding ) {
7775
78- currentLayer . pathVertex . push ( p1 . x , p1 . y , p1 . z ) ;
79- currentLayer . pathVertex . push ( p2 . x , p2 . y , p2 . z ) ;
76+ currentLayer . vertex . push ( p1 . x , p1 . y , p1 . z ) ;
77+ currentLayer . vertex . push ( p2 . x , p2 . y , p2 . z ) ;
78+
79+ } else {
80+
81+ currentLayer . pathVertex . push ( p1 . x , p1 . y , p1 . z ) ;
82+ currentLayer . pathVertex . push ( p2 . x , p2 . y , p2 . z ) ;
83+
84+ }
8085
8186 }
8287
83- }
88+ function delta ( v1 , v2 ) {
8489
85- function delta ( v1 , v2 ) {
90+ return state . relative ? v2 : v2 - v1 ;
8691
87- return state . relative ? v2 : v2 - v1 ;
92+ }
8893
89- }
94+ function absolute ( v1 , v2 ) {
9095
91- function absolute ( v1 , v2 ) {
96+ return state . relative ? v1 + v2 : v2 ;
9297
93- return state . relative ? v1 + v2 : v2 ;
98+ }
9499
95- }
100+ var lines = data . replace ( / ; . + / g , '' ) . split ( '\n' ) ;
96101
97- var lines = data . replace ( / ; . + / g , '' ) . split ( '\n' ) ;
102+ for ( var i = 0 ; i < lines . length ; i ++ ) {
98103
99- for ( var i = 0 ; i < lines . length ; i ++ ) {
104+ var tokens = lines [ i ] . split ( ' ' ) ;
105+ var cmd = tokens [ 0 ] . toUpperCase ( ) ;
100106
101- var tokens = lines [ i ] . split ( ' ' ) ;
102- var cmd = tokens [ 0 ] . toUpperCase ( ) ;
107+ //Argumments
108+ var args = { } ;
109+ tokens . splice ( 1 ) . forEach ( function ( token ) {
103110
104- //Argumments
105- var args = { } ;
106- tokens . splice ( 1 ) . forEach ( function ( token ) {
111+ if ( token [ 0 ] !== undefined ) {
107112
108- if ( token [ 0 ] !== undefined ) {
113+ var key = token [ 0 ] . toLowerCase ( ) ;
114+ var value = parseFloat ( token . substring ( 1 ) ) ;
115+ args [ key ] = value ;
109116
110- var key = token [ 0 ] . toLowerCase ( ) ;
111- var value = parseFloat ( token . substring ( 1 ) ) ;
112- args [ key ] = value ;
117+ }
113118
114- }
119+ } ) ;
115120
116- } ) ;
121+ //Process commands
122+ //G0/G1 – Linear Movement
123+ if ( cmd === 'G0' || cmd === 'G1' ) {
117124
118- //Process commands
119- //G0/G1 – Linear Movement
120- if ( cmd === 'G0' || cmd === 'G1' ) {
125+ var line = {
126+ x : args . x !== undefined ? absolute ( state . x , args . x ) : state . x ,
127+ y : args . y !== undefined ? absolute ( state . y , args . y ) : state . y ,
128+ z : args . z !== undefined ? absolute ( state . z , args . z ) : state . z ,
129+ e : args . e !== undefined ? absolute ( state . e , args . e ) : state . e ,
130+ f : args . f !== undefined ? absolute ( state . f , args . f ) : state . f ,
131+ } ;
121132
122- var line = {
123- x : args . x !== undefined ? absolute ( state . x , args . x ) : state . x ,
124- y : args . y !== undefined ? absolute ( state . y , args . y ) : state . y ,
125- z : args . z !== undefined ? absolute ( state . z , args . z ) : state . z ,
126- e : args . e !== undefined ? absolute ( state . e , args . e ) : state . e ,
127- f : args . f !== undefined ? absolute ( state . f , args . f ) : state . f ,
128- } ;
133+ //Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position
134+ if ( delta ( state . e , line . e ) > 0 ) {
129135
130- //Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position
131- if ( delta ( state . e , line . e ) > 0 ) {
136+ line . extruding = delta ( state . e , line . e ) > 0 ;
132137
133- line . extruding = delta ( state . e , line . e ) > 0 ;
138+ if ( currentLayer == undefined || line . z != currentLayer . z ) {
134139
135- if ( currentLayer == undefined || line . z != currentLayer . z ) {
140+ newLayer ( line ) ;
136141
137- newLayer ( line ) ;
142+ }
138143
139144 }
140145
141- }
146+ addSegment ( state , line ) ;
147+ state = line ;
142148
143- addSegment ( state , line ) ;
144- state = line ;
149+ } else if ( cmd === 'G2' || cmd === 'G3' ) {
145150
146- } else if ( cmd === 'G2' || cmd === 'G3' ) {
151+ //G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise )
152+ //console.warn( 'THREE.GCodeLoader: Arc command not supported' );
147153
148- //G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise )
149- //console.warn( 'THREE.GCodeLoader: Arc command not supported' );
154+ } else if ( cmd === 'G90' ) {
150155
151- } else if ( cmd === 'G90' ) {
156+ //G90: Set to Absolute Positioning
157+ state . relative = false ;
152158
153- //G90: Set to Absolute Positioning
154- state . relative = false ;
159+ } else if ( cmd === 'G91' ) {
155160
156- } else if ( cmd === 'G91' ) {
161+ //G91: Set to state.relative Positioning
162+ state . relative = true ;
157163
158- //G91: Set to state.relative Positioning
159- state . relative = true ;
164+ } else if ( cmd === 'G92' ) {
160165
161- } else if ( cmd === 'G92' ) {
166+ //G92: Set Position
167+ var line = state ;
168+ line . x = args . x !== undefined ? args . x : line . x ;
169+ line . y = args . y !== undefined ? args . y : line . y ;
170+ line . z = args . z !== undefined ? args . z : line . z ;
171+ line . e = args . e !== undefined ? args . e : line . e ;
172+ state = line ;
162173
163- //G92: Set Position
164- var line = state ;
165- line . x = args . x !== undefined ? args . x : line . x ;
166- line . y = args . y !== undefined ? args . y : line . y ;
167- line . z = args . z !== undefined ? args . z : line . z ;
168- line . e = args . e !== undefined ? args . e : line . e ;
169- state = line ;
174+ } else {
170175
171- } else {
176+ //console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd );
172177
173- //console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd );
178+ }
174179
175180 }
176181
177- }
182+ function addObject ( vertex , extruding ) {
178183
179- function addObject ( vertex , extruding ) {
184+ var geometry = new THREE . BufferGeometry ( ) ;
185+ geometry . addAttribute ( 'position' , new THREE . Float32BufferAttribute ( vertex , 3 ) ) ;
180186
181- var geometry = new THREE . BufferGeometry ( ) ;
182- geometry . addAttribute ( 'position' , new THREE . Float32BufferAttribute ( vertex , 3 ) ) ;
187+ var segments = new THREE . LineSegments ( geometry , extruding ? extrudingMaterial : pathMaterial ) ;
188+ segments . name = 'layer' + i ;
189+ object . add ( segments ) ;
183190
184- var segments = new THREE . LineSegments ( geometry , extruding ? extrudingMaterial : pathMaterial ) ;
185- segments . name = 'layer' + i ;
186- object . add ( segments ) ;
191+ }
187192
188- }
193+ var object = new THREE . Group ( ) ;
194+ object . name = 'gcode' ;
189195
190- var object = new THREE . Group ( ) ;
191- object . name = 'gcode' ;
196+ if ( this . splitLayer ) {
192197
193- if ( this . splitLayer ) {
198+ for ( var i = 0 ; i < layers . length ; i ++ ) {
194199
195- for ( var i = 0 ; i < layers . length ; i ++ ) {
200+ var layer = layers [ i ] ;
201+ addObject ( layer . vertex , true ) ;
202+ addObject ( layer . pathVertex , false ) ;
196203
197- var layer = layers [ i ] ;
198- addObject ( layer . vertex , true ) ;
199- addObject ( layer . pathVertex , false ) ;
204+ }
200205
201- }
206+ } else {
207+
208+ var vertex = [ ] , pathVertex = [ ] ;
202209
203- } else {
210+ for ( var i = 0 ; i < layers . length ; i ++ ) {
204211
205- var vertex = [ ] , pathVertex = [ ] ;
212+ var layer = layers [ i ] ;
206213
207- for ( var i = 0 ; i < layers . length ; i ++ ) {
214+ vertex = vertex . concat ( layer . vertex ) ;
215+ pathVertex = pathVertex . concat ( layer . pathVertex ) ;
208216
209- var layer = layers [ i ] ;
217+ }
210218
211- vertex = vertex . concat ( layer . vertex ) ;
212- pathVertex = pathVertex . concat ( layer . pathVertex ) ;
219+ addObject ( vertex , true ) ;
220+ addObject ( pathVertex , false ) ;
213221
214222 }
215223
216- addObject ( vertex , true ) ;
217- addObject ( pathVertex , false ) ;
218-
219- }
224+ object . quaternion . setFromEuler ( new THREE . Euler ( - Math . PI / 2 , 0 , 0 ) ) ;
220225
221- object . quaternion . setFromEuler ( new THREE . Euler ( - Math . PI / 2 , 0 , 0 ) ) ;
226+ return object ;
222227
223- return object ;
228+ }
224229
225230} ;
0 commit comments