summaryrefslogtreecommitdiff
path: root/trunk/reprap/miscellaneous/adrians-java/User-interface/Sources/RepRapBuild.java
blob: f8c9e70ef80b046ccafdc3bb637c7c9e8df38919 (plain)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
/*
 
RepRap
------
 
The Replicating Rapid Prototyper Project
 
 
Copyright (C) 2006
Adrian Bowyer & The University of Bath
 
http://reprap.org
 
Principal author:
 
Adrian Bowyer
Department of Mechanical Engineering
Faculty of Engineering and Design
University of Bath
Bath BA2 7AY
U.K.
 
e-mail: A.Bowyer@bath.ac.uk
 
RepRap is free; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
Licence as published by the Free Software Foundation; either
version 2 of the Licence, or (at your option) any later version.
 
RepRap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public Licence for more details.
 
For this purpose the words "software" and "library" in the GNU Library
General Public Licence are taken to mean any and all computer programs
computer files data results documents and other copyright information
available from the RepRap project.
 
You should have received a copy of the GNU Library General Public
Licence along with RepRap; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA,
or see
 
http://www.gnu.org/
 
=====================================================================
 
This program loads STL files of objects, orients them, and builds them
in the RepRap machine.
 
It is based on one of the open-source examples in Daniel Selman's excellent
Java3D book, and his notice is immediately below.
 
First version 2 April 2006
This version: 16 April 2006
 
 */



/**********************************************************
 * VrmlPickingTest.java Copyright (C) 2001 	Daniel Selman
 *
 * First distributed with the book "Java 3D Programming"
 * by Daniel Selman and published by Manning Publications.
 * http://manning.com/selman
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * The license can be found on the WWW at:
 * http://www.fsf.org/copyleft/gpl.html
 *
 * Or by writing to:
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * Authors can be contacted at:
 * Daniel Selman: daniel@selman.org
 *
 * If you make changes you think others would like, please
 * contact one of the authors or someone at the
 * www.j3d.org web site.
 **************************************************************/

//package org.reprap;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.behaviors.mouse.MouseZoom;
import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.audioengines.javasound.JavaSoundMixer;

//************************************************************************

// This is the main public class that creates a virtual world of the RepRap
// working volume, allows you to put STL-file objects in it, move them about
// to arrange them, (and builds them in the machine - one day soon).

public class RepRapBuild extends Applet implements MouseListener 
{
    // ------------------------
    // Most of the stuff that follows will be read from
    // a configuration file ultimately.
    
    private static final double xwv = 300;  // The RepRap machine...
    private static final double ywv = 300;  // ...working volume in mm.
    private static final double zwv = 300;
    
    // The relative location of the STL model of the working volume
    // And the offset of the origin in it.
    
    private static final String wv_location = "RepRap-data/RepRap-wv.stl";
    private static final String worldName = "RepRap World";
    private static final Vector3d wv_offset = new Vector3d(-17.3, -24.85, -2);
    
    // Translate and zoom scaling factors
    
    private static final double mouse_tf = 10;
    private static final double mouse_zf = 10;
    
    // Factors for front and back clipping planes and so on
    
    private static final double RADFAC = 0.7;
    private static final double BACKFAC = 2.0;
    private static final double FRONTFAC = 0.025;
    private static final double BOUNDFAC = 3.0;
    
    // Black, the background, and other colours
    
    private static final Color3f black = new Color3f(0, 0, 0);
    private static final Color3f bgColour = new Color3f( 0.9f, 0.9f, 0.9f );
    private static final Color3f rrRed = new Color3f( 0.6f, 0.2f, 0.2f );
    private static final Color3f rrGreen = new Color3f( 0.3f, 0.4f, 0.3f );
    private static final Color3f rrGrey = new Color3f( 0.3f, 0.3f, 0.3f );
          
    private static int m_kWidth = 600;                    // Window size
    private static int m_kHeight = 400;
    
    //---- End of stuff to be loaded from config file
    
    private PickCanvas pickCanvas = null;   // The thing picked by a mouse click
    
    private Appearance default_app = null;  // Colour for unselected parts
    private Appearance picked_app = null;   // Colour for the selected part
    private Appearance wv_app = null;       // Colour for the working volume
    
    private MouseObject mouse = null;
    private BranchGroup wv_and_stls = new BranchGroup();  // Where in the scene the 
                                                          // working volume and STLs
                                                          // are joined on.
                                                          
    private STLObject world = null;                      // Everything  
    private STLObject workingVolume = null;              // The RepRap machine itself.
    private STLObject lastPicked = null;                 // The last thing picked
    private java.util.List stls = new ArrayList();       // All the STLs to be built
    private int objectIndex = 0;                         // Counter for STLs as they
                                                         // are loaded

    // The world in the Applet
    
    protected String[] m_szCommandLineArray = null;  // Store for command string
    protected VirtualUniverse m_Universe = null;
    protected BranchGroup m_SceneBranchGroup = null;
    protected Bounds m_ApplicationBounds = null;

    
    // Constructors
    
    public RepRapBuild( ) 
    {   
    }
    
    public RepRapBuild( String[] args ) 
    {
        saveCommandLineArguments( args );
        initialise();
    }
    
    // (About) how big is the world?
    
    protected float getViewPlatformActivationRadius( ) 
    {
        return (float)(RADFAC*Math.sqrt(xwv*xwv + ywv*ywv + zwv*zwv));
    }
    
    // How far away is the back?
    
    protected double getBackClipDistance( ) 
    {
        return BACKFAC*getViewPlatformActivationRadius( );
    }
    
    // How close is the front?
    
    protected double getFrontClipDistance( ) 
    {
        return FRONTFAC*getViewPlatformActivationRadius( );
    }
    
    // Set up the size of the world
    
    protected Bounds createApplicationBounds( ) 
    {
        m_ApplicationBounds = new BoundingSphere(new
                Point3d(xwv*0.5, ywv*0.5, zwv*0.5),
                BOUNDFAC*getViewPlatformActivationRadius( )
                );
        return m_ApplicationBounds;
    }
    
    // Running as an applet?
    
    public boolean isApplet( ) 
    {
        try 
        {
            System.getProperty( "user.dir" );
            return false;
        } catch( Exception e ) 
        {
        }
        
        return true;
    }
    
    
    // Where are we in the file system?
    
    public static URL getWorkingDirectory( ) throws java.net.MalformedURLException 
    {
        URL url = null;
        
        try 
        {
            File file = new File( System.getProperty("user.dir") );
            return file.toURL( );
        } catch( Exception e ) 
        {
            System.err.println("getWorkingDirectory( ): can't get user dir.");
        }
                
        //return getCodeBase( );
        return null;
    }
    
    // Return handles on big things above where we are interested
    
    public VirtualUniverse getVirtualUniverse( ) 
    {
        return m_Universe;
    }
    
    
    public javax.media.j3d.Locale getFirstLocale( ) 
    {
        java.util.Enumeration en = m_Universe.getAllLocales( );
        
        if( en.hasMoreElements( ) != false )
            return ( javax.media.j3d.Locale ) en.nextElement( );
        
        return null;
    }
    
    // The size of the world
    
    protected Bounds getApplicationBounds( ) 
    {
        if( m_ApplicationBounds == null )
            m_ApplicationBounds = createApplicationBounds( );
        
        return m_ApplicationBounds;
    }
    
    // Set bg light grey
    
    protected Background createBackground( ) 
    {
        Background back = new Background( bgColour );
        back.setApplicationBounds( createApplicationBounds( ) );
        return back;
    }
    
    // Fire up Java3D
    
    public void initJava3d( ) 
    {
        m_Universe = createVirtualUniverse( );
        
        javax.media.j3d.Locale locale = createLocale( m_Universe );
        
        BranchGroup sceneBranchGroup = createSceneBranchGroup( );
        
        ViewPlatform vp = createViewPlatform( );
        BranchGroup viewBranchGroup = createViewBranchGroup( getViewTransformGroupArray( ), vp );
        
        createView( vp );
        
        Background background = createBackground( );
        
        if( background != null )
            sceneBranchGroup.addChild( background );
        
        locale.addBranchGraph( sceneBranchGroup );
        addViewBranchGroup( locale, viewBranchGroup );
        
        //onDoneInit( );
    }
    
//    protected void onDoneInit( ) 
//    {
//    }
    
    protected double getScale( ) 
    {
        return 1.0;
    }
    
    
    protected void addViewBranchGroup( javax.media.j3d.Locale locale, BranchGroup bg ) 
    {
        locale.addBranchGraph( bg );
    }
    
    protected javax.media.j3d.Locale createLocale( VirtualUniverse u ) 
    {
        return new javax.media.j3d.Locale( u );
    }

    
    protected View createView( ViewPlatform vp ) 
    {
        View view = new View( );
        
        PhysicalBody pb = createPhysicalBody( );
        PhysicalEnvironment pe = createPhysicalEnvironment( );
        
        AudioDevice audioDevice = createAudioDevice( pe );
        
        if( audioDevice != null ) 
        {
            pe.setAudioDevice( audioDevice );
            audioDevice.initialize( );
        }
        
        view.setPhysicalEnvironment( pe );
        view.setPhysicalBody( pb );
        
        if( vp != null )
            view.attachViewPlatform( vp );
        
        view.setBackClipDistance( getBackClipDistance( ) );
        view.setFrontClipDistance( getFrontClipDistance( ) );
        
        Canvas3D c3d = createCanvas3D( );
        view.addCanvas3D( c3d );
        addCanvas3D( c3d );
        
        return view;
    }
    
    protected PhysicalBody createPhysicalBody( ) 
    {
        return new PhysicalBody( );
    }
    
    protected AudioDevice createAudioDevice( PhysicalEnvironment pe ) 
    {
        JavaSoundMixer javaSoundMixer = new JavaSoundMixer( pe );
        
        if (javaSoundMixer == null)
            System.out.println( "create of audiodevice failed" );
        
        return javaSoundMixer;
    }
    
    protected PhysicalEnvironment createPhysicalEnvironment( ) 
    {
        return new PhysicalEnvironment( );
    }
    
    
    protected ViewPlatform createViewPlatform( ) 
    {
        ViewPlatform vp = new ViewPlatform( );
        vp.setViewAttachPolicy( View.RELATIVE_TO_FIELD_OF_VIEW );
        vp.setActivationRadius( getViewPlatformActivationRadius( ) );
        
        return vp;
    }
    
    protected Canvas3D createCanvas3D( ) 
    {
        GraphicsConfigTemplate3D gc3D = new GraphicsConfigTemplate3D( );
        gc3D.setSceneAntialiasing( GraphicsConfigTemplate.PREFERRED );
        GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment( ).getScreenDevices( );
        
        Canvas3D c3d = new Canvas3D( gd[0].getBestConfiguration( gc3D ) );
        c3d.setSize( getCanvas3dWidth( c3d ), getCanvas3dHeight( c3d ) );
        
        return c3d;
    }
    
    // These two are probably wrong.
    
    protected int getCanvas3dWidth( Canvas3D c3d ) 
    {
        return m_kWidth;
    }
    
    protected int getCanvas3dHeight( Canvas3D c3d ) 
    {
        return m_kHeight;
    }
    
        
    protected BranchGroup createViewBranchGroup( TransformGroup[] tgArray, 
            ViewPlatform vp ) 
    {
        BranchGroup vpBranchGroup = new BranchGroup( );
        
        if( tgArray != null && tgArray.length > 0 ) 
        {
            Group parentGroup = vpBranchGroup;
            TransformGroup curTg = null;
            
            for( int n = 0; n < tgArray.length; n++ ) 
            {
                curTg = tgArray[n];
                parentGroup.addChild( curTg );
                parentGroup = curTg;
            }
            
            tgArray[tgArray.length-1].addChild( vp );
        } else
            vpBranchGroup.addChild( vp );
        
        return vpBranchGroup;
    }
    
    
    protected VirtualUniverse createVirtualUniverse( ) 
    {
        return new VirtualUniverse( );
    }
    
    protected void saveCommandLineArguments( String[] szArgs ) 
    {
        m_szCommandLineArray = szArgs;
    }
    
    protected String[] getCommandLineArguments( ) 
    {
        return m_szCommandLineArray;
    }
    
    // Set stuff up for the constructors - called by all of them that actually
    // do anything.
    
    private void initialise() 
    {
        default_app = new Appearance();
        default_app.setMaterial(new Material(rrGrey, black, rrGrey, black, 0f));
        
        picked_app = new Appearance();
        picked_app.setMaterial(new Material(rrRed, black, rrRed, black, 0f));
        
        wv_app = new Appearance();
        wv_app.setMaterial(new Material(rrGreen, black, rrGreen, black, 0f));
                
        initJava3d( );
        
        // Add the control panel
        
        RepRapBuildPanel.makePanel(this);
    }
    
    // Are we live?  If not, vivfy.
    
    public void start( ) 
    {
        if( pickCanvas == null )
            initialise( );
    }
    
    protected void addCanvas3D( Canvas3D c3d ) 
    {
        setLayout( new BorderLayout( ) );
        add( c3d, BorderLayout.CENTER );
        doLayout( );
        
        if ( m_SceneBranchGroup != null ) {
            c3d.addMouseListener( this );
            
            pickCanvas = new PickCanvas( c3d, m_SceneBranchGroup );
            pickCanvas.setMode( PickTool.GEOMETRY_INTERSECT_INFO );
            pickCanvas.setTolerance( 4.0f );
        }
        
        c3d.setCursor( new Cursor( Cursor.DEFAULT_CURSOR ) );
    }
    
    public TransformGroup[] getViewTransformGroupArray( ) 
    {
        TransformGroup[] tgArray = new TransformGroup[1];
        tgArray[0] = new TransformGroup( );
        
        Transform3D viewTrans = new Transform3D( );
        Transform3D eyeTrans = new Transform3D( );
        
        BoundingSphere sceneBounds = (BoundingSphere) m_SceneBranchGroup.getBounds( );
        
        // point the view at the center of the object
        
        Point3d center = new Point3d( );
        sceneBounds.getCenter( center);
        double radius = sceneBounds.getRadius( );
        Vector3d temp = new Vector3d( center );
        viewTrans.set( temp );
        
        // pull the eye back far enough to see the whole object
        
        double eyeDist = radius / Math.tan( Math.toRadians( 40 ) / 2.0 );
        temp.x = 0.0;
        temp.y = 0.0;
        temp.z = eyeDist;
        eyeTrans.set( temp );
        viewTrans.mul( eyeTrans );
        
        // set the view transform
        
        tgArray[0].setTransform( viewTrans );
        
        return tgArray;
    }
    
    // Set up the RepRap working volume
    
    protected BranchGroup createSceneBranchGroup( ) 
    {       
        m_SceneBranchGroup = new BranchGroup( );
        
        BranchGroup objRoot = m_SceneBranchGroup;
        
        Bounds lightBounds = getApplicationBounds( );
        
        AmbientLight ambLight = new AmbientLight( true, new Color3f( 1.0f, 1.0f, 1.0f ) );
        ambLight.setInfluencingBounds( lightBounds );
        objRoot.addChild( ambLight );
        
        DirectionalLight headLight = new DirectionalLight( );
        headLight.setInfluencingBounds( lightBounds );
        objRoot.addChild( headLight );
        
        mouse = new MouseObject(getApplicationBounds( ), mouse_tf, mouse_zf);
        
        wv_and_stls.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
        
        // Load the STL file for the working volume
        
        world = new STLObject(wv_and_stls, worldName);
        
        URL codebase = null;
        
        String stlFile = null;
        
        try 
        {
            codebase = RepRapBuild.getWorkingDirectory();
            stlFile = codebase.toExternalForm( ) + wv_location;
        } catch( Exception e ) 
        {
            System.err.println( "createSceneBranchGroup(): Exception finding working directory: " +
                    codebase.toExternalForm( ));
            e.printStackTrace();
        }
        
        workingVolume = new STLObject( stlFile, wv_offset, objectIndex, wv_app );
        wv_and_stls.addChild(workingVolume.top);
        
        // Set the mouse to move everything
        
        mouse.move(world, false);
        objRoot.addChild(world.top);
        
        return objRoot;
    }
    

    
    // Find the stl object in the scene with the given name
    
    private STLObject findSTL(String name)
    {
        STLObject stl;
        for (int i = 0; i < stls.size(); i++)
        {
            stl = (STLObject)stls.get(i);
            if(stl.name == name)
                return stl;
        }
        return null;
    }
    
    // Action on mouse click
    
    public void mouseClicked( MouseEvent e ) 
    {        
        pickCanvas.setShapeLocation( e );
        
        PickResult pickResult = pickCanvas.pickClosest( );
        boolean valid_object = false;
        STLObject picked = null;
        
        if( pickResult != null ) // Got anything?
        {    
            Node actualNode = pickResult.getObject( );
            String name = (String)actualNode.getUserData( );
            if( name != null ) // Really got something?
            {
                if( name != workingVolume.name ) // STL object picked?
                {
                    picked = findSTL(name);
                    if(picked != null)
                    {
                        picked.setAppearance(picked_app); // Highlight it
                        if(lastPicked != null)
                            lastPicked.setAppearance(default_app); // lowlight the last one
                        mouse.move(picked, true);  // Set the mouse to move it
                        lastPicked = picked;  // Remember it
                    }
                } else
                {   // Picked the working volume - deselect all and...
                    if(lastPicked != null)
                            lastPicked.setAppearance(default_app);
                    mouse.move(world, false); // ...switch the mouse to moving the world
                    lastPicked = null;
                }
            }
        }
    }
    
    public void mouseEntered( MouseEvent e ) 
    {
    }
    
    public void mouseExited( MouseEvent e ) 
    {
    }
    
    public void mousePressed( MouseEvent e ) 
    {
    }
    
    public void mouseReleased( MouseEvent e ) 
    {
    }
    
    // Callback for when the user selects an STL file to load
    
    public void anotherSTLFile(String s) 
    {
        if (s == null)
            return;
        objectIndex++;
        STLObject stl = new STLObject(s, null, objectIndex, default_app);
        if(stl != null) 
        {
            wv_and_stls.addChild( stl.top );
            stls.add(stl);
        }
    }
    
    // Callbacks for when the user rotates the selected object
    
    public void xRotate() 
    {
        if(lastPicked != null)
            lastPicked.xClick();
    }
    
    public void yRotate() 
    {
        if(lastPicked != null)
            lastPicked.yClick();
    }
    
    public void zRotate() 
    {    
        if(lastPicked != null)
            lastPicked.zClick();
    }
    
    // Callback to build the objects - work needed here...
    
    public void build()
    {
        System.out.println(
                "Now build the STL object(s); a bit more needed than this message...");
    }
    
    // Create the world and all that's in it...
    
    public static void main( String[] args ) 
    {
        RepRapBuild rr_build = new RepRapBuild( args );
        
        new MainFrame( rr_build, rr_build.m_kWidth, rr_build.m_kHeight );

    }
}