package demos.nurbs.surfaceapp; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.AbstractAction; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JSeparator; import javax.swing.JSlider; import javax.swing.JSpinner; import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.SpinnerNumberModel; import javax.swing.ToolTipManager; import demos.nurbs.icons.*; import demos.nurbs.knotslidercomponent.JKnotSlider; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; /** * Main class for application demostrating capabilitues of JOGL library extend by NURBS surface functionalities * Hlavní třída aplikace demonstrující shopnosti knihovny JOGL při práci s NURBS * plochami * * @author Tomáš Hráský * */ @SuppressWarnings("serial") public class SurfaceApp extends JFrame implements ActionListener { /** * X-coord editing component name * Jméno komponenty pro editaci X-ové souřadnice aktuálního bodu */ public static final String X_SPINNER_NAME = "xspinner"; /** * Y-coord editing component name * Jméno komponenty pro editaci Y-ové souřadnice aktuálního bodu */ public static final String Y_SPINNER_NAME = "yspinner"; /** * Z-coord editing component name * Jméno komponenty pro editaci Z-ové souřadnice aktuálního bodu */ public static final String Z_SPINNER_NAME = "zspinner"; /** * Weight editing component name * Jméno komponenty pro editaci váhy aktuálního bodu */ public static final String W_SPINNER_NAME = "wspinner"; /** * U direction knotvector editing component * Jméno komponenty pro editaci uzlového vektoru ve směru parametru U */ private static final String U_KNOTSLIDER = "Uknotspinner"; /** * V direction knotvector editing component * Jméno komponenty pro editaci uzlového vektoru ve směru parametru V */ private static final String V_KNOTSLIDER = "Vknotspinner"; /** * New control point action name * Jméno události přidání řídícího bodu */ public static final String PRIDAT_AC = "PRIDAT"; /** * Degree set event name * Jméno události zadání stupně křivky */ public static final String STUPEN_AC = "STUPEN"; /** * Delete control point event name * Jméno události smazání řídícího bodu */ public static final String SMAZAT_AC = "SMAZAT"; /** * New clamped knotvector event name * Jméno události vytvoření uzavřeného uzlového vektoru */ public static final String UZAVRENY_AC = "UZAVRENY"; /** * New uniform knotvector event name * Jméno události vytvoření otevřeného (uniformního) uzlového vektoru */ public static final String OTEVRENY_AC = "OTEVRENY"; /** * Save surface event name * Jméno události uložení plochy */ public static final String ULOZIT_AC = "ULOZIT"; /** * Load surface event name * Jméno události načetení uložené definice plochy */ public static final String NACIST_AC = "NACIST"; /** * Move control point event name * Jméno události pohybu řídícího bodu */ private static final String MOVE_AC = "MOVE"; /** * New surface event name * Jméno události vytvoření nové plochy */ static final String NOVA_AC = "NEWSURFACE"; /** * Exit app event name * Jméno události ukončení aplikace */ public static final String EXIT_AC = "EXIT"; /** * Show about event name * Jméno události zobrazení okna o aplikaci */ public static final String INFO_AC = "INFO"; /** * Add column of control points event name * Jméno události přidání sloupce řídících bodů */ public static final String PRIDAT_AC_SLOUPEC = "ADDCOL"; /** * Add row of control points event name * Jméno události přidání řádku řídících bodů */ public static final String PRIDAT_AC_RADEK = "ADDROW"; /** * Remove row of control points event name * Jméno události smazání řádku řídících bodů */ public static final String SMAZAT_AC_RADEK = "DELROW"; /** * Remove column of control points event name * Jméno události smazání sloupce řídících bodů */ public static final String SMAZAT_AC_SLOUPEC = "DELCOL"; /** * OpenGL drawing canvas * Plátno pro vykreslování pomocí OpenGL */ private GLCanvas glCanvas; /** * X-coord editing component * Komponenta pro editaci X-ové souřadnice aktuálního bodu */ private JSpinner xSpinner; /** * Y-coord editing component * Komponenta pro editaci Y-ové souřadnice aktuálního bodu */ private JSpinner ySpinner; /** * Weight editing component * Komponenta pro editaci váhy aktuálního bodu */ private JSpinner wSpinner; /** * Z-coord editing component * Komponenta pro editaci Z-ové souřadnice aktuálního bodu */ private JSpinner zSpinner; /** * Mouse listener * Listener událostí myši */ private SurfaceMouseListener mouseListener; /** * U direction knotvector editing component * Komponenta pro editaci uzlového vektoru ve směru parametru U */ private JKnotSlider knotSlider; /** * V direction knotvector editing component * Komponenta pro editaci uzlového vektoru ve směru parametru V */ private JKnotSlider knotSlider2; /** * Set move points mode * Tlačítko pro zapnutí módu pohybu řídících bodů */ private JToggleButton moveTB; /** * X rotation component * Komponenta ovládající otočení definované plochy kolem osy X */ private JSlider rotaceXSlider; /** * Y rotation component * Komponenta ovládající otočení definované plochy kolem osy Y */ private JSlider rotaceYSlider; /** * Z rotation component * Komponenta ovládající otočení definované plochy kolem osy Z */ private JSlider rotaceZSlider; /** * Label for X rotation editing component * Nadpis komponenty ovládající otočení definované plochy kolem osy X */ private JLabel rotaceXLabel; /** * Label for Y rotation editing component * Nadpis komponenty ovládající otočení definované plochy kolem osy Y */ private JLabel rotaceYLabel; /** * Label for Z rotation editing component * Nadpis komponenty ovládající otočení definované plochy kolem osy Z */ private JLabel rotaceZLabel; /** * GL events listener * Objekt reagující na události OpenGL plátna */ private GLListener glListener; /** * Use lighting checkbox * Checkbox použití nasvícení objektu */ private JCheckBox lightingChBox; /** * Constructor, creates GUI * Konstruktor, vytvoří grafické uživatelské rozhraní */ public SurfaceApp() { //super( "Tomáš Hráský - ukázková aplikace funkcionality GLU NURBS funkcí - JOGL"); super( "Tomáš Hráský - example application of GLU NURBS in JOGL"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initGUI(); } /** * GUI initialization * Inicializace grafického uživatelského rozhraní */ private void initGUI() { JPopupMenu.setDefaultLightWeightPopupEnabled(false); ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false); this.glCanvas = new GLCanvas(); glCanvas.setSize(new Dimension(750, 500)); this.glListener=new GLListener(this); glCanvas.addGLEventListener(glListener); mouseListener = new SurfaceMouseListener(this); glCanvas.addMouseListener(mouseListener); glCanvas.addMouseMotionListener(mouseListener); setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.gridy = 0; c.gridwidth = GridBagConstraints.REMAINDER; ActListener listener = new ActListener(this); JMenuBar menuBar = new JMenuBar(); getContentPane().add(menuBar, c); JMenu aplikaceMenu = new JMenu("Aplication"); menuBar.add(aplikaceMenu); JMenuItem aboutMI = new JMenuItem("About"); aboutMI.setActionCommand(INFO_AC); aboutMI.addActionListener(listener); aplikaceMenu.add(aboutMI); aplikaceMenu.add(new JSeparator()); JMenuItem konecMI = new JMenuItem("Exit"); konecMI.addActionListener(listener); konecMI.setActionCommand(EXIT_AC); aplikaceMenu.add(konecMI); JMenu krivkaMenu = new JMenu("Surface"); menuBar.add(krivkaMenu); JMenu pridatBodyM = new JMenu("Add points"); krivkaMenu.add(pridatBodyM); // pridatBodyM.addActionListener(listener); // pridatBodyM.setActionCommand(PRIDAT_AC); JMenuItem pridatRadkyMI=new JMenuItem("Points row"); pridatRadkyMI.setActionCommand(PRIDAT_AC_RADEK); pridatRadkyMI.addActionListener(listener); JMenuItem pridatSloupceMI=new JMenuItem("Points column"); pridatSloupceMI.setActionCommand(PRIDAT_AC_SLOUPEC); pridatSloupceMI.addActionListener(listener); pridatBodyM.add(pridatRadkyMI); pridatBodyM.add(pridatSloupceMI); JMenu smazatBodyM = new JMenu("Delete points"); krivkaMenu.add(smazatBodyM); // smazatBodyM.addActionListener(listener); // smazatBodyM.setActionCommand(SMAZAT_AC); JMenuItem smazatRadkyMI=new JMenuItem("Points row"); smazatRadkyMI.setActionCommand(SMAZAT_AC_RADEK); smazatRadkyMI.addActionListener(listener); smazatBodyM.add(smazatRadkyMI); JMenuItem smazatSloupceMI=new JMenuItem("Points column"); smazatSloupceMI.setActionCommand(SMAZAT_AC_SLOUPEC); smazatSloupceMI.addActionListener(listener); smazatBodyM.add(smazatSloupceMI); JMenuItem stupenMI = new JMenuItem("Set surface degree"); krivkaMenu.add(stupenMI); stupenMI.addActionListener(listener); stupenMI.setActionCommand(STUPEN_AC); JMenu knotVecMenu = new JMenu("Create knotvectors"); krivkaMenu.add(knotVecMenu); JMenuItem clampedKVMI = new JMenuItem("Clamped"); knotVecMenu.add(clampedKVMI); clampedKVMI.setActionCommand(UZAVRENY_AC); clampedKVMI.addActionListener(listener); JMenuItem unclampedKVMI = new JMenuItem("Uniform"); knotVecMenu.add(unclampedKVMI); unclampedKVMI.setActionCommand(OTEVRENY_AC); unclampedKVMI.addActionListener(listener); JMenuItem moveMI = new JMenuItem("Move points"); krivkaMenu.add(moveMI); moveMI.setActionCommand(MOVE_AC); moveMI.addActionListener(listener); krivkaMenu.add(new JSeparator()); krivkaMenu.add(new JSeparator()); JMenuItem novaMI = new JMenuItem("New surface"); krivkaMenu.add(novaMI); novaMI.setActionCommand(NOVA_AC); novaMI.addActionListener(listener); JMenuItem ulozitMI = new JMenuItem("Safe surface as..."); krivkaMenu.add(ulozitMI); ulozitMI.setActionCommand(ULOZIT_AC); ulozitMI.addActionListener(listener); JMenuItem nacistMI = new JMenuItem("Load surface"); krivkaMenu.add(nacistMI); nacistMI.setActionCommand(NACIST_AC); nacistMI.addActionListener(listener); c.gridy++; JToolBar toolBar = new JToolBar(); getContentPane().add(toolBar, c); ButtonGroup bg = new ButtonGroup(); JButton novaB = new JButton(); // novaB.setText("Nová"); novaB.setToolTipText("New surface"); novaB.setIcon(IconFactory.getIcon("demos/nurbs/icons/folder_new.png")); novaB.setActionCommand(NOVA_AC); novaB.addActionListener(listener); toolBar.add(novaB); JButton ulozitB = new JButton(); ulozitB.setIcon(IconFactory.getIcon("demos/nurbs/icons/adept_sourceseditor.png")); // ulozitB.setText("Uložit"); ulozitB.setToolTipText("Save"); ulozitB.setActionCommand(ULOZIT_AC); ulozitB.addActionListener(listener); toolBar.add(ulozitB); JButton nahratB = new JButton(); // nahratB.setText("Nahrát"); nahratB.setToolTipText("Load surface"); nahratB.setIcon(IconFactory.getIcon("demos/nurbs/icons/fileimport.png")); nahratB.setActionCommand(NACIST_AC); nahratB.addActionListener(listener); toolBar.add(nahratB); toolBar.add(new JToolBar.Separator()); JToggleButton pridatTB = new JToggleButton(); // pridatTB.setText("Přidat body"); pridatTB.setToolTipText("Add contol points"); toolBar.add(pridatTB); pridatTB.setIcon(IconFactory.getIcon("demos/nurbs/icons/add.png")); // pridatTB.setActionCommand(PRIDAT_AC); // pridatTB.addActionListener(listener); bg.add(pridatTB); final JPopupMenu popup2=new JPopupMenu(); JMenuItem radkyPopupMI=new JMenuItem("Poits row"); radkyPopupMI.setActionCommand(PRIDAT_AC_RADEK); JMenuItem sloupcePopupMI=new JMenuItem("Points column"); sloupcePopupMI.setActionCommand(PRIDAT_AC_SLOUPEC); radkyPopupMI.addActionListener(listener); sloupcePopupMI.addActionListener(listener); popup2.add(radkyPopupMI); popup2.add(sloupcePopupMI); pridatTB.addMouseListener(new /** * CLass to add context menu to toolbar button * Třída pro připojení kontextového menu na * tlačítko na liště nástrojů * @author Tomáš Hráský */ MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); e.isPopupTrigger(); popup2.show(e.getComponent(), e.getX(), e.getY()); } }); JToggleButton smazatTB = new JToggleButton(); // smazatTB.setText("Smazat body"); smazatTB.setToolTipText("Delete points"); toolBar.add(smazatTB); smazatTB.setIcon(IconFactory.getIcon("demos/nurbs/icons/fileclose.png")); // smazatTB.setActionCommand(SMAZAT_AC); // smazatTB.addActionListener(listener); bg.add(smazatTB); final JPopupMenu popup3=new JPopupMenu(); JMenuItem radky2PopupMI=new JMenuItem("Points row"); radky2PopupMI.setActionCommand(SMAZAT_AC_RADEK); JMenuItem sloupce2PopupMI=new JMenuItem("Points column"); sloupce2PopupMI.setActionCommand(SMAZAT_AC_SLOUPEC); radky2PopupMI.addActionListener(listener); sloupce2PopupMI.addActionListener(listener); popup3.add(radky2PopupMI); popup3.add(sloupce2PopupMI); smazatTB.addMouseListener(new /** * CLass to add context menu to toolbar button * Třída pro připojení kontextového menu na * tlačítko na liště nástrojů * @author Tomáš Hráský */ MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); e.isPopupTrigger(); popup3.show(e.getComponent(), e.getX(), e.getY()); } }); JToggleButton stupenTB = new JToggleButton(); // stupenTB.setText("Smazat body"); stupenTB.setToolTipText("Set surface degree"); toolBar.add(stupenTB); stupenTB.setIcon(IconFactory.getIcon("demos/nurbs/icons/math_rsup.png")); stupenTB.setActionCommand(STUPEN_AC); stupenTB.addActionListener(listener); bg.add(stupenTB); final JPopupMenu popup = new JPopupMenu(); JMenuItem uzavrenyPopupMI = new JMenuItem("Clamped"); popup.add(uzavrenyPopupMI); uzavrenyPopupMI.setActionCommand(UZAVRENY_AC); uzavrenyPopupMI.addActionListener(listener); JMenuItem otevrenyPopupMI = new JMenuItem("Uniform"); popup.add(otevrenyPopupMI); otevrenyPopupMI.setActionCommand(OTEVRENY_AC); otevrenyPopupMI.addActionListener(listener); JToggleButton vytvoritButton = new JToggleButton(); // vytvoritButton.setText("Vytvořit uzlový vektor"); vytvoritButton.setToolTipText("Create knotvectors"); vytvoritButton.setIcon(IconFactory.getIcon("demos/nurbs/icons/newfunction.png")); bg.add(vytvoritButton); vytvoritButton.addMouseListener(new /** * CLass to add context menu to toolbar button * Třída pro připojení kontextového menu na * tlačítko na liště nástrojů * @author Tomáš Hráský */ MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); e.isPopupTrigger(); popup.show(e.getComponent(), e.getX(), e.getY()); } }); popup.setInvoker(vytvoritButton); toolBar.add(vytvoritButton); moveTB = new JToggleButton(); // moveTB.setText("Hýbat body"); moveTB.setToolTipText("Move points"); moveTB.setIcon(IconFactory.getIcon("demos/nurbs/icons/mouse.png")); toolBar.add(moveTB); moveTB.setActionCommand(MOVE_AC); moveTB.addActionListener(listener); bg.add(moveTB); toolBar.add(new JToolBar.Separator()); JButton infoB = new JButton(); // infoB.setText("Ukončit"); infoB.setToolTipText("About"); infoB.setIcon(IconFactory.getIcon("demos/nurbs/icons/info.png")); toolBar.add(infoB); infoB.setActionCommand(INFO_AC); infoB.addActionListener(listener); toolBar.add(new JToolBar.Separator()); JButton exitB = new JButton(); // exitB.setText("Ukončit"); exitB.setToolTipText("Exit"); exitB.setIcon(IconFactory.getIcon("demos/nurbs/icons/exit.png")); toolBar.add(exitB); exitB.setActionCommand(EXIT_AC); exitB.addActionListener(listener); c.gridwidth = 1; c.gridx = 0; c.gridy = 2; c.weightx = 1; c.weighty = 1; getContentPane().add(glCanvas, c); c.gridx = 1; JPanel rightPanel = new JPanel(new GridBagLayout()); GridBagConstraints cc = new GridBagConstraints(); cc.insets = new Insets(5, 5, 5, 5); xSpinner = new JSpinner(new SpinnerNumberModel(0, -10000, 10000.0, 1)); ySpinner = new JSpinner(new SpinnerNumberModel(0, -10000.0, 10000.0, 1)); zSpinner = new JSpinner(new SpinnerNumberModel(0, -10000.0, 10000.0, 1)); wSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 10000.0, .05)); SpinnerListener spinnerListener = new SpinnerListener(this); SliderListener sliderListener=new SliderListener(this); xSpinner.addChangeListener(spinnerListener); xSpinner.setName(X_SPINNER_NAME); ySpinner.addChangeListener(spinnerListener); ySpinner.setName(Y_SPINNER_NAME); wSpinner.addChangeListener(spinnerListener); wSpinner.setName(W_SPINNER_NAME); zSpinner.setName(Z_SPINNER_NAME); zSpinner.addChangeListener(spinnerListener); cc.gridx = 0; cc.gridy = 0; cc.gridwidth = 2; cc.weighty = 0; rotaceXLabel = new JLabel(); rightPanel.add(rotaceXLabel, cc); cc.gridy++; rotaceXSlider = new JSlider(-180, 180, 0); rotaceXSlider.addChangeListener(sliderListener); rightPanel.add(rotaceXSlider, cc); cc.gridy++; rotaceYLabel = new JLabel(); rightPanel.add(rotaceYLabel, cc); cc.gridy++; rotaceYSlider = new JSlider(-180, 180, 0); rotaceYSlider.addChangeListener(sliderListener); rightPanel.add(rotaceYSlider, cc); cc.gridy++; rotaceZLabel = new JLabel(); rightPanel.add(rotaceZLabel, cc); cc.gridy++; rotaceZSlider = new JSlider(-180, 180, 0); rotaceZSlider.addChangeListener(sliderListener); rightPanel.add(rotaceZSlider, cc); cc.gridy++; lightingChBox=new JCheckBox(new /** * Class for easy reaction to checkbox event * Třída pro jendoduché zpracování akce na checkboxu * @author Tomáš Hráský */ AbstractAction("Show Bézier plates"){ public void actionPerformed(ActionEvent e) { updateGLCanvas(); } }); lightingChBox.setSelected(false); rightPanel.add(lightingChBox,cc); cc.gridy++; updateRotationLabels(); cc.weighty = 1; rightPanel.add(new JPanel(), cc); cc.weighty = 0; cc.gridwidth = 1; cc.gridy++; rightPanel.add(new JLabel("X"), cc); cc.gridy++; rightPanel.add(new JLabel("Y"), cc); cc.gridy++; rightPanel.add(new JLabel("Z"), cc); cc.gridy++; rightPanel.add(new JLabel("W"), cc); cc.gridx = 1; cc.gridy -= 3; rightPanel.add(xSpinner, cc); cc.gridy++; rightPanel.add(ySpinner, cc); cc.gridy++; rightPanel.add(zSpinner, cc); cc.gridy++; rightPanel.add(wSpinner, cc); xSpinner.setEnabled(false); ySpinner.setEnabled(false); zSpinner.setEnabled(false); wSpinner.setEnabled(false); c.weightx = 0; c.weighty = 0; getContentPane().add(rightPanel, c); c.gridx = 0; c.gridy++; knotSlider = new JKnotSlider(Surface.getInstance().getKnotsU()); knotSlider.addActionListener(this); knotSlider.setName(U_KNOTSLIDER); getContentPane().add(knotSlider, c); c.gridy++; knotSlider2 = new JKnotSlider(Surface.getInstance().getKnotsU()); knotSlider2.addActionListener(this); knotSlider2.setName(V_KNOTSLIDER); getContentPane().add(knotSlider2, c); pack(); invalidate(); setVisible(true); } /** * Method for running application * Metoda pro spuštění aplikace * * @param args * no arguments from command line * */ public static void main(String[] args) { // set argument 'NotFirstUIActionOnProcess' in the JNLP's application-desc tag for example // // NotFirstUIActionOnProcess // boolean firstUIActionOnProcess = 0==args.length || !args[0].equals("NotFirstUIActionOnProcess") ; GLProfile.initSingleton(firstUIActionOnProcess); new SurfaceApp(); } /** * Reaction to reqest for canvas redraw - redraws canvas and sets coords of actually selected control point to editing components * Reakce na požadavek překreslení OpenGL plátna, překreslí plátno a nastaví * souřadnice aktuálního vybraného bodu do editačních komponent */ public void updateGLCanvas() { glCanvas.repaint(); if (Surface.getInstance().getBodIndex() >= 0) { xSpinner.setEnabled(true); ySpinner.setEnabled(true); zSpinner.setEnabled(true); wSpinner.setEnabled(true); xSpinner.setValue(Double.valueOf(Math.round(Surface.getInstance() .getActiveX()))); ySpinner.setValue(Double.valueOf(Math.round(Surface.getInstance() .getActiveY()))); zSpinner.setValue(Double.valueOf(Math.round(Surface.getInstance() .getActiveZ()))); wSpinner.setValue(Double .valueOf(Surface.getInstance().getActiveW())); } else { xSpinner.setEnabled(false); ySpinner.setEnabled(false); zSpinner.setEnabled(false); wSpinner.setEnabled(false); } } /* * (non-Javadoc) * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JKnotSlider) { JKnotSlider src = (JKnotSlider) e.getSource(); if (src.getName().equals(U_KNOTSLIDER)) { if(src.checkKnotMulti(Surface.getInstance().getOrderU())){ Surface.getInstance().setKnotsU(src.getKnotsFloat()); }else{ JOptionPane.showMessageDialog(this,"Maximum knot multiplicity exceeded","Error",JOptionPane.ERROR_MESSAGE); src.setKnots(Surface.getInstance().getKnotsU()); } } else { if(src.checkKnotMulti(Surface.getInstance().getOrderV())){ Surface.getInstance().setKnotsV(src.getKnotsFloat()); }else{ JOptionPane.showMessageDialog(this,"Maximum knot multiplicity exceeded","Error",JOptionPane.ERROR_MESSAGE); //JOptionPane.showMessageDialog(this,"Překročení maximální násobnosti uzlu","Chyba",JOptionPane.ERROR_MESSAGE); src.setKnots(Surface.getInstance().getKnotsV()); } } updateGLCanvas(); } } /** * Returns OpenGL canvas * Vrací OpenGL plátno * * @return OpenGL canvas */ public GLCanvas getGlCanvas() { return glCanvas; } /** * Returns mouse listener * Vrací listener událostí myši * * @return mouse listener */ public SurfaceMouseListener getMouseListener() { return mouseListener; } /** * Creates NURBS surface with clamped knotvectors * Vytvoří NURBS plochu s okrajovými uzlovými vektory */ public void uzavernyKV() { int stupen; int pocetBodu; boolean isOK=true; float[] newKnots = null,newKnotsV = null; stupen= Surface.getInstance().getOrderU(); pocetBodu= Surface.getInstance().getPointsInU(); if (stupen <= pocetBodu) { int knotCount = stupen + pocetBodu; int middlePartSize = knotCount - 2 * stupen; newKnots = new float[knotCount]; int i; int j = 0; float middleStep = 1f / (middlePartSize + 2); float knot = middleStep; // knot=.5f; for (i = 0; i < stupen; i++) newKnots[j++] = 0; for (i = 0; i < middlePartSize; i++) { newKnots[j++] = knot; knot += middleStep; } for (i = 0; i < stupen; i++) newKnots[j++] = 1; } else{ isOK=false; //errorMessage("Malý počet řídících bodů ve směru paramteru U vzhledem k zadanému stupni plochy"); errorMessage("Too few control points as of U degree"); } stupen= Surface.getInstance().getOrderV(); pocetBodu= Surface.getInstance().getPointsInV(); if (stupen <= pocetBodu) { int knotCount = stupen + pocetBodu; int middlePartSize = knotCount - 2 * stupen; newKnotsV = new float[knotCount]; int i; int j = 0; float middleStep = 1f / (middlePartSize + 2); float knot = middleStep; // knot=.5f; for (i = 0; i < stupen; i++) newKnotsV[j++] = 0; for (i = 0; i < middlePartSize; i++) { newKnotsV[j++] = knot; knot += middleStep; } for (i = 0; i < stupen; i++) newKnotsV[j++] = 1; } else{ isOK=false; //errorMessage("Malý počet řídících bodů ve směru paramteru V vzhledem k zadanému stupni plochy"); errorMessage("Too few control points as of V degree"); } if(isOK) postNewKnot(newKnots,newKnotsV); } /** * Shows modal window with error report * Zobrazí modální okno s hlášením chyby * * @param error * error report */ public void errorMessage(String error) { JOptionPane.showMessageDialog(this, error, "Error!", JOptionPane.ERROR_MESSAGE); } /** * Creates NURBS surface with uniform knotvectors * Vytvoří NURBS plochu s uniformními uzlovými vektory */ public void otevrenyKV() { int stupen,pocetBodu; boolean isOK=true; float[] newKnots = null,newKnotsV = null; stupen = Surface.getInstance().getOrderU(); pocetBodu = Surface.getInstance().getPointsInU(); if (stupen <= pocetBodu) { int knotCount = stupen + pocetBodu; int middlePartSize = knotCount; newKnots = new float[knotCount]; int i; int j = 0; float middleStep = 1f / (middlePartSize - 1); float knot = 0; for (i = 0; i < middlePartSize; i++) { newKnots[j++] = knot; knot += middleStep; } } else{ isOK=false; //errorMessage("Malý počet řídících bodů ve směru parametru U vzhledem k zadanému stupni plochy"); errorMessage("Too few control points as of U degree"); } stupen = Surface.getInstance().getOrderV(); pocetBodu = Surface.getInstance().getPointsInV(); if (stupen <= pocetBodu) { int knotCount = stupen + pocetBodu; int middlePartSize = knotCount; newKnotsV = new float[knotCount]; int i; int j = 0; float middleStep = 1f / (middlePartSize - 1); float knot = 0; for (i = 0; i < middlePartSize; i++) { newKnotsV[j++] = knot; knot += middleStep; } } else{ isOK=false; //errorMessage("Malý počet řídících bodů ve směru parametru V vzhledem k zadanému stupni plochy"); errorMessage("Too few control points as of V degree"); } if(isOK) postNewKnot(newKnots,newKnotsV); } /** * Method called after adding new knot * Metoda volaná po přidání nového uzlu * @param newKnots new U knotvector * @param newKnotsV new V knotvector */ private void postNewKnot(float[] newKnots,float[] newKnotsV) { Surface.getInstance().setKnotsU(newKnots); Surface.getInstance().setKnotsV(newKnotsV); knotSlider.setKnots(newKnots); knotSlider2.setKnots(newKnotsV); Surface.getInstance().setIsSurfaceFinished(true); updateGLCanvas(); moveTB.setSelected(true); } /** * Activates move mode button * Aktivuje tlačítko módu pohybu řícími body */ public void selectMoveButt() { moveTB.setSelected(true); } /** * Sets datasource for editation of knotvectors from surface definition object * Nastaví zdroje dat komponent pro editaci uzlových vektorů podle uz. * vektorů v objektu plochy */ public void updateJKnotSlider() { knotSlider.setKnots(Surface.getInstance().getKnotsU()); knotSlider2.setKnots(Surface.getInstance().getKnotsV()); } /** * Returns value of X axe rotation set in editing component * Vrací hodnotu rotace kolem osy X nastavenou v editační komponentě * @return X rotation */ public float getXrotation() { return rotaceXSlider.getValue(); } /** * Returns value of Y axe rotation set in editing component * Vrací hodnotu rotace kolem osy Y nastavenou v editační komponentě * @return Y rotation */ public float getYrotation() { return rotaceYSlider.getValue(); } /** * Returns value of Z axe rotation set in editing component * Vrací hodnotu rotace kolem osy Z nastavenou v editační komponentě * @return Z rotation */ public float getZrotation() { return rotaceZSlider.getValue(); } /** * Updates labels's text according to their actual state * Upraví text popisků prvků pro ovládání rotace podle jejich aktuálního stavu */ public void updateRotationLabels(){ String zakladniText = "Rotation by axe "; PrintfFormat format=new PrintfFormat("%0.3d"); String add; if(rotaceXSlider.getValue()<0)add="-"; else add="+"; rotaceXLabel.setText(zakladniText+"X "+add+format.sprintf(Math.abs(rotaceXSlider.getValue()))+"˚"); if(rotaceYSlider.getValue()<0)add="-"; else add="+"; rotaceYLabel.setText(zakladniText+"Y "+add+format.sprintf(Math.abs(rotaceYSlider.getValue()))+"˚"); if(rotaceZSlider.getValue()<0)add="-"; else add="+"; rotaceZLabel.setText(zakladniText+"Z "+add+format.sprintf(Math.abs(rotaceZSlider.getValue()))+"˚"); } /** * Return OpenGL canvas listener * Vrací listener OpenGL plátna * @return OpenGL canvas listener */ public GLListener getGlListener() { return glListener; } /** * Notifies about reqest to light surface * Informuje o požadavku na nasvětlení tělesa * @return true if lighting is enabled */ public boolean isLightingEnabled() { return !lightingChBox.isSelected(); } }