1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License as
4  * published by the Free Software Foundation; either version 2 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful, but
8  * WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOUSE. See the GNU
10  * General Public License for more details.
11  *
12  * You should have recieved a copy of the GNU General Public License
13  * along with this program; if not write to the Free Software
14  * Foundation, inc., 59 Temple Place, Suite 330, Boston MA 02111-1307
15  * USA */
16 
17 /*
18  * author  Jonas Forssell
19  */
20 package j3d;
21 import java.awt.*;
22 import java.io.*;
23 import javax.swing.tree.*;
24 import javax.swing.*;
25 import java.util.*;
26 
27 import com.stevesoft.pat.Regex;
28 
29 import java.awt.event.*;
30 
31 import gui.*;
32 
33 /**
34  * Creates a nurb surface defined by four edge curves
35  * @author   Jonas Forssell, Yuriy Mikhaylovskiy
36  */
37 public class _SurfFill extends _NurbSurface implements Serializable{
38   private _NurbCurve[] curve = new _NurbCurve[4];
39 
40   JTextField jTextField1, jTextField2, jTextField3, jTextField4, jTextField5, jTextField6, jTextField7;
41   JButton jButton2, jButton3, jButton4, jButton5;
42   JComboBox jComboBox1, jComboBox2;
43 
44   private static Regex r_index = new Regex("^ *([0-9]+) *");
45   private static Regex r_curve = new Regex("(?i)CURVES *= *\\[ *([0-9, ]+) *\\]");
46   private static Regex r_indexer = new Regex("\\G,? *([0-9]+) *,?");
47 
48   /**
49    * Constructs a NURB surface defined by four corner curves
50    *
51    *
52    */
_SurfFill(boolean add, Canvas3D J3D)53   public _SurfFill(boolean add, Canvas3D J3D) {
54     super(add, J3D);
55   }
56 
writeObject()57   public String writeObject() {
58       String st = new String(Id);
59       st += "  CURVES = [";
60       for (int i=0; i<curve.length; i++) {
61           st += ((_NurbCurve)curve[i]).get_Id();
62           if (i < curve.length-1) st += ", ";
63       }
64       st += "] ";
65       st += super.writeObject();
66       return st;
67     }
68 
readObject(String st, Hashtable geo)69   public void readObject(String st, Hashtable geo) {
70       int i=0;
71       if (r_index.search(st)) Id = r_index.stringMatched(1);
72       if (r_curve.search(st))
73           while (r_indexer.search(r_curve.stringMatched(1)))
74               curve[i++] = (_NurbCurve)geo.get(r_indexer.stringMatched(1));
75       super.readObject(st);
76     }
77 
readObject(ObjectInputStream in)78   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
79       curve = (_NurbCurve[])in.readObject();
80     }
81 
reset(boolean do_mesh)82   public void reset(boolean do_mesh) {
83     int i,j;
84     _NurbCurve tcurve[];
85     _SurfRul A,B;
86     _SurfBil C;
87     _Point[] tmp, pnt;
88     int li,lj;
89     float[] muknt, mvknt ;
90 
91 
92     // 0. Initialize
93 //    tcurve = new _NurbCurve[curve.length];
94 //    for (i=0; i<curve.length; i++)
95 //        tcurve[i] = (_NurbCurve)curve[i].copy();
96 
97     // Make sure the curves are in right order and direction
98     pnt = new _Point[4];
99 
100     tmp = curve[0].getEndPoints();
101     pnt[0] = tmp[0];
102     pnt[1] = tmp[1];
103 
104     tmp = curve[1].getEndPoints();
105 
106     if (!lib3D.isClose(pnt[1],tmp[0],J3D.getGeometricTolerance()) && !lib3D.isClose(pnt[1],tmp[1], J3D.getGeometricTolerance())) {
107         curve[0].reverseDirection();
108         tmp = curve[0].getEndPoints();
109         pnt[0] = tmp[0];
110         pnt[1] = tmp[1];
111     }
112 
113     for (i=1; i<4; i++) {
114         tmp = curve[i].getEndPoints();
115 
116         if (!lib3D.isClose(pnt[1],tmp[0],J3D.getGeometricTolerance()) && !lib3D.isClose(pnt[1],tmp[1],J3D.getGeometricTolerance()))
117             throw new IllegalArgumentException("Illegal input of curves. Must be in a circle");
118 
119         if (lib3D.isClose(pnt[1],tmp[1],J3D.getGeometricTolerance())) {
120             curve[i].reverseDirection();
121             tmp = curve[i].getEndPoints();
122         }
123 
124         pnt[0] = tmp[0];
125         pnt[1] = tmp[1];
126     }
127 
128     curve[3].reverseDirection();
129     curve[2].reverseDirection();
130 
131     tmp = curve[0].getEndPoints();
132     pnt[0] = tmp[0];
133     pnt[1] = tmp[1];
134 
135     tmp = curve[2].getEndPoints();
136     pnt[2] = tmp[0];
137     pnt[3] = tmp[1];
138 
139 
140     // 1. Generate a lofted surface A
141     A = new _SurfRul(curve[0],curve[2],Canvas3D.MESH_Dummy_4,thickness,material, J3D);
142 
143     // 2. Generate a lofted surface B
144     B = new _SurfRul(curve[1],curve[3],Canvas3D.MESH_Dummy_4,thickness,material, J3D);
145 
146     // 3. Generate a bilinear surface C
147     C = new _SurfBil(pnt,Canvas3D.MESH_Dummy_4,thickness,material, J3D);
148 
149     // 4. Degree elevete surface A to surface B u-direction degree
150     A.elevate(B.uorder - A.vorder, false);
151 
152     // 5. Degree elevate surface B to surface A u-direction degree
153     B.elevate(A.uorder - B.vorder, false);
154 
155     // 6. Degree elevate surface C in both directions to A & B degrees
156     C.elevate(A.uorder - C.uorder, true);
157     C.elevate(B.uorder - C.vorder, false);
158 
159     // 7. Merge knot vectors to obtain a common vector in u and v direction
160     muknt = lib3D.mergeKnots(A.uknots, B.vknots);
161     muknt = lib3D.mergeKnots(muknt, C.uknots);
162 
163     mvknt = lib3D.mergeKnots(A.vknots, B.uknots);
164     mvknt = lib3D.mergeKnots(mvknt, C.vknots);
165 
166     // 8. Insert missing knots into surface A
167     A.insertKnots(lib3D.diffKnots(muknt,A.uknots),true);
168     A.insertKnots(lib3D.diffKnots(mvknt,A.vknots),false);
169 
170     // 9. Insert missing knots into surface B - reversed due to orientation
171     B.insertKnots(lib3D.diffKnots(muknt,B.vknots),false);
172     B.insertKnots(lib3D.diffKnots(mvknt,B.uknots),true);
173 
174     // 10. Insert missing knots into surface C
175     C.insertKnots(lib3D.diffKnots(muknt,C.uknots),true);
176     C.insertKnots(lib3D.diffKnots(mvknt,C.vknots),false);
177 
178     // 11. S(u,v) = S1(u,v) + S2(u,v) - T(u,v)  (do this on the control points)
179     //     Note the reversed index on surface B since the orientation is different
180     li = A.controlPoints.length;
181     lj = A.controlPoints[0].length;
182     controlPoints = new _CtrlPoint[li][lj];
183     for (i = 0; i < li; i++)
184     	for (j=0; j < lj; j++)
185     		controlPoints[i][j] = new _CtrlPoint( A.controlPoints[i][j].x + B.controlPoints[j][i].x - C.controlPoints[i][j].x
186     				                            , A.controlPoints[i][j].y + B.controlPoints[j][i].y - C.controlPoints[i][j].y
187     				                            , A.controlPoints[i][j].z + B.controlPoints[j][i].z - C.controlPoints[i][j].z
188     				                            , A.controlPoints[i][j].w * B.controlPoints[j][i].w * C.controlPoints[i][j].w
189     				                            , Color.GRAY);
190 
191     // 12. Generate the knots
192     uorder = A.uorder;
193     uknots = muknt;
194 
195     vorder = A.vorder;
196     vknots = mvknt;
197 
198     // 13. Set mesh data
199     mesh_div[0] = curve[0].mesh_div;
200     mesh_div[1] = curve[3].mesh_div;
201     mesh_div[2] = curve[2].mesh_div;
202     mesh_div[3] = curve[1].mesh_div;
203 
204 
205     // 14. Generate geometry & mesh
206     super.reset(do_mesh);
207 }
208 
toString()209 public String toString(){ return "FillSurface ID="+Id;}
210 
get_TreeNode()211   public MutableTreeNode get_TreeNode(){
212     DefaultMutableTreeNode node = new DefaultMutableTreeNode(this);
213 
214     // Add unique data for this class
215     for (int i=0; i<4; i++)
216         node.add(curve[i].get_TreeNode());
217 
218     // Add mesh data from _NurbCurve
219     node.add(super.get_TreeNode());
220 
221     return node;
222   }
223 
getEditPanel(Canvas3D j3d, PreProcessor pp)224   public JPanel getEditPanel(Canvas3D j3d, PreProcessor pp){
225       this.J3D = j3d;
226       this.PreP = pp;
227 
228       JPanel jPanel0 = new JPanel();
229       JPanel jPanel1 = new JPanel();
230       JPanel jPanel7 = new JPanel();
231       jButton1 = new JButton(add == true?"Add":"Update");
232       jButton2 = new JButton("<<");
233       jButton3 = new JButton("<<");
234       jButton4 = new JButton("<<");
235       jButton5 = new JButton("<<");
236       jTextField1 = new JTextField((curve[0] != null ? curve[0].toString() : "")+"",3);
237       jTextField2 = new JTextField((curve[1] != null ? curve[1].toString() : "")+"",3);
238       jTextField3 = new JTextField((curve[2] != null ? curve[2].toString() : "")+"",3);
239       jTextField4 = new JTextField((curve[3] != null ? curve[3].toString() : "")+"",3);
240 
241       jPanel0.setLayout(new BoxLayout(jPanel0, BoxLayout.Y_AXIS));
242       jPanel0.add(jPanel1);
243       	jPanel1.setLayout(new GridLayout(4,3));
244 
245       jPanel1.add(new JLabel("Curve 1"), null);
246       jPanel1.add(jTextField1, null);
247       	jTextField1.setEditable(false);
248       jPanel1.add(jButton2, null);
249       	jButton2.addActionListener(new java.awt.event.ActionListener() {
250           public void actionPerformed(ActionEvent e) {
251             jButton2_actionPerformed(e);
252           }
253         });
254         jButton2.addKeyListener(new KeyAdapter() {
255             public void keyPressed(KeyEvent e) {
256                 checkDefaultKey(e);
257             }
258             public void keyReleased(KeyEvent e) {
259                 int c = e.getKeyCode();
260 
261                 if (c == KeyEvent.VK_ENTER) {
262                     jButton2_actionPerformed(null);
263                 }
264             }
265         });
266       jPanel1.add(new JLabel("Curve 2"), null);
267       jPanel1.add(jTextField2, null);
268       	jTextField2.setEditable(false);
269       jPanel1.add(jButton3, null);
270       	jButton3.addActionListener(new java.awt.event.ActionListener() {
271       	    public void actionPerformed(ActionEvent e) {
272       	        jButton3_actionPerformed(e);
273       	    }
274       	});
275         jButton3.addKeyListener(new KeyAdapter() {
276             public void keyPressed(KeyEvent e) {
277                 checkDefaultKey(e);
278             }
279             public void keyReleased(KeyEvent e) {
280                 int c = e.getKeyCode();
281 
282                 if (c == KeyEvent.VK_ENTER) {
283                     jButton3_actionPerformed(null);
284                 }
285             }
286         });
287         jPanel1.add(new JLabel("Curve 3"), null);
288         jPanel1.add(jTextField3, null);
289             jTextField3.setEditable(false);
290         jPanel1.add(jButton4, null);
291             jButton4.addActionListener(new java.awt.event.ActionListener() {
292                 public void actionPerformed(ActionEvent e) {
293                     jButton4_actionPerformed(e);
294                 }
295             });
296           jButton4.addKeyListener(new KeyAdapter() {
297               public void keyPressed(KeyEvent e) {
298                   checkDefaultKey(e);
299               }
300               public void keyReleased(KeyEvent e) {
301                   int c = e.getKeyCode();
302 
303                   if (c == KeyEvent.VK_ENTER) {
304                       jButton4_actionPerformed(null);
305                   }
306               }
307           });
308           jPanel1.add(new JLabel("Curve 4"), null);
309           jPanel1.add(jTextField4, null);
310             jTextField4.setEditable(false);
311           jPanel1.add(jButton5, null);
312             jButton5.addActionListener(new java.awt.event.ActionListener() {
313                 public void actionPerformed(ActionEvent e) {
314                     jButton5_actionPerformed(e);
315                 }
316             });
317             jButton5.addKeyListener(new KeyAdapter() {
318                 public void keyPressed(KeyEvent e) {
319                     checkDefaultKey(e);
320                 }
321                 public void keyReleased(KeyEvent e) {
322                     int c = e.getKeyCode();
323 
324                     if (c == KeyEvent.VK_ENTER) {
325                         jButton5_actionPerformed(null);
326                     }
327                 }
328             });
329 
330       jPanel0.add(super.getEditPanel(j3d,pp));
331 
332       jPanel0.add(jPanel7);
333         jPanel7.add(jButton1);
334       jButton1.addActionListener(new java.awt.event.ActionListener() {
335         public void actionPerformed(ActionEvent e) {
336           jButton1_actionPerformed(e);
337         }
338       });
339       jButton1.addKeyListener(new KeyAdapter() {
340           public void keyPressed(KeyEvent e) {
341               checkDefaultKey(e);
342           }
343           public void keyReleased(KeyEvent e) {
344               int c = e.getKeyCode();
345 
346               if (c == KeyEvent.VK_ENTER) {
347                   jButton1_actionPerformed(null);
348               }
349           }
350       });
351 
352       jPanel0.validate();
353 
354       return jPanel0;
355   }
356 
jButton1_actionPerformed(ActionEvent e)357   void jButton1_actionPerformed(ActionEvent e) {
358       _SurfFill tmp = this;
359 
360         if(curve[0]==null || curve[1]==null || curve[2]==null || curve[3]==null) return;
361 
362         tmp.update(e);
363 
364         if(add == true) {
365             try {
366                 tmp = (_SurfFill)this.clone();
367                 tmp.prepareGroups();
368                 J3D.add3D(tmp);
369               } catch (CloneNotSupportedException e1) {
370                   e1.printStackTrace();
371               }
372 
373             tmp.add = false;
374             jButton2.requestFocus();
375 
376             curve = new _NurbCurve[4];
377 
378         } else
379             tmp.reset(true);
380 
381         J3D.tree_reset();
382         J3D.view_reset();
383         J3D.repaint();
384     }
385 
386 
jButton2_actionPerformed(ActionEvent e)387   void jButton2_actionPerformed(ActionEvent e) {
388       boolean set = false;
389       Object[] obj = J3D.getSelectedObjects3D();
390       for (int i=0; i< obj.length; i++)
391           if(obj[i] !=null && obj[i] instanceof _NurbCurve){
392               curve[0]=(_NurbCurve)obj[i];
393               jTextField1.setText(obj[i].toString());
394               set = true;
395               jButton3.requestFocus();
396           }
397 
398       if (!set) {
399               curve[0]=null;
400               jTextField1.setText("");
401           }
402     }
403 
jButton3_actionPerformed(ActionEvent e)404     void jButton3_actionPerformed(ActionEvent e) {
405         boolean set = false;
406         Object[] obj = J3D.getSelectedObjects3D();
407         for (int i=0; i< obj.length; i++)
408             if(obj[i] !=null && obj[i] instanceof _NurbCurve){
409                 curve[1]=(_NurbCurve)obj[i];
410                 jTextField2.setText(obj[i].toString());
411                 set = true;
412                 jButton4.requestFocus();
413             }
414 
415         if (!set) {
416                 curve[1]=null;
417                 jTextField2.setText("");
418             }
419     }
420 
jButton4_actionPerformed(ActionEvent e)421     void jButton4_actionPerformed(ActionEvent e) {
422         boolean set = false;
423         Object[] obj = J3D.getSelectedObjects3D();
424         for (int i=0; i< obj.length; i++)
425             if(obj[i] !=null && obj[i] instanceof _NurbCurve){
426                 curve[2]=(_NurbCurve)obj[i];
427                 jTextField3.setText(obj[i].toString());
428                 set = true;
429                 jButton5.requestFocus();
430             }
431 
432         if (!set) {
433                 curve[2]=null;
434                 jTextField3.setText("");
435             }
436     }
437 
jButton5_actionPerformed(ActionEvent e)438     void jButton5_actionPerformed(ActionEvent e) {
439         boolean set = false;
440         Object[] obj = J3D.getSelectedObjects3D();
441         for (int i=0; i< obj.length; i++)
442             if(obj[i] !=null && obj[i] instanceof _NurbCurve){
443                 curve[3]=(_NurbCurve)obj[i];
444                 jTextField4.setText(obj[i].toString());
445                 set = true;
446                 cComboBox1.requestFocus();
447             }
448 
449         if (!set) {
450                 curve[3]=null;
451                 jTextField4.setText("");
452             }
453     }
454 
requestFocus()455     public void requestFocus() {
456         jButton2.requestFocus();
457     }
458 
requestAction()459     public void requestAction() {
460         if (add == true)
461             if (jButton2.hasFocus())
462                 jButton2_actionPerformed(null);
463             else if (jButton3.hasFocus())
464                 jButton3_actionPerformed(null);
465             else if (jButton4.hasFocus())
466                 jButton4_actionPerformed(null);
467             else if (jButton5.hasFocus())
468                 jButton5_actionPerformed(null);
469     }
470 
471 
duplicate(Canvas3D out, boolean add)472     public _Object duplicate(Canvas3D out, boolean add){
473         _SurfFill o = null;
474         try {
475           o = (_SurfFill)this.clone();
476       } catch (CloneNotSupportedException e) {
477           e.printStackTrace();
478       }
479 
480       o.curve = new _NurbCurve[4];
481       for (int i=0; i<4; i++)
482           o.curve[i] = (_NurbCurve)curve[i].duplicate(out,add);
483 
484       if (add) out.add3D(o);
485 
486       return o;
487     }
488 
transform3D(Matrix3D t)489     public void transform3D(Matrix3D t){
490         if(!selected || processed)return;
491         super.transform3D(t);
492         for (int i=0; i<4; i++) {
493           curve[i].setSelected(true);
494           curve[i].transform3D(t);
495           curve[i].setSelected(true);
496           curve[i].setProcessed(true);
497         }
498           reset(true);
499       }
500 
deselectRequiredObjects()501     public void deselectRequiredObjects() {
502         if (!selected)
503             for (int i=0; i<curve.length; i++) {
504                 curve[i].setSelected(false);
505                 curve[i].deselectRequiredObjects();
506             }
507     }
508 
replaceObjectWith(_Object o, _Object replacement)509     public void replaceObjectWith(_Object o, _Object replacement) {
510         if (!(o instanceof _NurbCurve) || !(replacement instanceof _NurbCurve)) return;
511 
512         for (int i=0; i<curve.length; i++)
513             if (curve[i] == o) curve[i] = (_NurbCurve)replacement;
514 
515     }
516 
517 }
518 
519