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