summaryrefslogtreecommitdiffstats
path: root/src/demos/nurbs/knotslidercomponent
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2007-10-09 07:38:25 +0000
committerKenneth Russel <[email protected]>2007-10-09 07:38:25 +0000
commitc8e0d487886dbec1e3a994ea36724bbf59f5122a (patch)
tree0b9588684708a2429b8252ca367777d0b9125bf6 /src/demos/nurbs/knotslidercomponent
parent2bdf0b792c0b89cde549087af1676ee558e37aa6 (diff)
Integration of Tomas Hrasky's port of basic GLU NURBS functionality
from C++ to Java, plus example applications, done as part of his Bachelor of Science degree at the University of Hradec Králové, Faculty of Informatics and Management. Current state of code is documented in src/classes/com/sun/opengl/impl/nurbs/README.txt. Example applications require Java 1.5 and are not currently built by default. Specify -Djogl.nurbs=1 during jogl-demos build with a 1.5 javac on the PATH to build them. Dependent jars are copied to build output directory. Deleted old partially-complete GLU NURBS port. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/jogl-demos/trunk@223 3298f667-5e0e-4b4a-8ed4-a3559d26a5f4
Diffstat (limited to 'src/demos/nurbs/knotslidercomponent')
-rwxr-xr-xsrc/demos/nurbs/knotslidercomponent/JKnotSlider.java468
-rwxr-xr-xsrc/demos/nurbs/knotslidercomponent/KnotPolygon.java159
2 files changed, 627 insertions, 0 deletions
diff --git a/src/demos/nurbs/knotslidercomponent/JKnotSlider.java b/src/demos/nurbs/knotslidercomponent/JKnotSlider.java
new file mode 100755
index 0000000..02da402
--- /dev/null
+++ b/src/demos/nurbs/knotslidercomponent/JKnotSlider.java
@@ -0,0 +1,468 @@
+package demos.nurbs.knotslidercomponent;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Vector;
+
+import javax.swing.JComponent;
+
+/**
+ * GUI component for editing NURBS curve/surface knotvector
+ * Komponenta grafického uživatelského rozhraní pro editaci uzlového vektoru NURBS křivky
+ * @author Tomáš Hráský
+ *
+ */
+@SuppressWarnings("serial")
+public class JKnotSlider extends JComponent implements ComponentListener,
+ MouseMotionListener, MouseListener {
+
+ /**
+ * Knot value change event
+ * Událost změny hodoty prvku uzlového vektoru
+ */
+ private static final String KNOT_MOVED = "KnotMoved";
+
+ /**
+ * Vector representing knots
+ * Vektor objektů reprezentujících prvky uzlového vektoru
+ */
+ private Vector<KnotPolygon> knots;
+
+ /**
+ * Previous knot vector (for recovery after user wrong setting)
+ * Předchozí vektor objektů reprezentujících prvky uzlového vektoru - pro obnovení při chybě uživatele
+ */
+ private Vector<KnotPolygon> previousState;
+
+ /**
+ * List of listeners attached to component
+ * Seznam ActionListenerů navázaných na komponentu
+ */
+ private LinkedList<ActionListener> actionListeners;
+
+ /**
+ * Value of one pixel movement
+ * Hodnota posunu o jeden pixel
+ */
+ private double oneStep;
+
+ /**
+ * Side space
+ * Mezera na straně osy
+ */
+ private int side;
+
+ /**
+ * Top space
+ * Mezera nad osou
+ */
+ private int top;
+
+ /**
+ * Actually selected knot index
+ * Index aktuálně vybraného prvku uzlového vektoru
+ */
+ private int activeKnot;
+
+// private Vector<Integer> xVector;
+
+
+ /**
+ * Creates component
+ * Vytvoří komponentu
+ */
+ public JKnotSlider() {
+ oneStep = 0;
+ top = 0;
+ side = 0;
+ knots = new Vector<KnotPolygon>();
+ previousState=new Vector<KnotPolygon>();
+// xVector=new Vector<Integer>();
+
+ actionListeners = new LinkedList<ActionListener>();
+ this.addComponentListener(this);
+ this.addMouseMotionListener(this);
+ this.addMouseListener(this);
+ }
+
+ /**
+ * Adds listener to notified list. list
+ * Přidá zadaný listener do seznamu naslouchajících objektů
+ * @param listener added listener
+ */
+ public void addActionListener(ActionListener listener) {
+ actionListeners.add(listener);
+ }
+
+ /**
+ * Creates component with given knotvector knots
+ * Vytvoří komponentu se zadanými hodnotami uzlového vektoru
+ * @param knots knot vector
+ */
+ public JKnotSlider(double[] knots) {
+ this();
+ for (double d : knots) {
+ addKnot(new Double(d));
+ }
+ }
+
+ /**
+ * Creates component with given knotvector knots
+ * Vytvoří komponentu se zadanými hodnotami uzlového vektoru
+ * @param knots knot vector
+ */
+ public JKnotSlider(Vector<Double> knots) {
+ this();
+ for (Double d : knots) {
+ addKnot(d);
+ }
+ }
+ /**
+ * Creates component with given knotvector knots
+ * Vytvoří komponentu se zadanými hodnotami uzlového vektoru
+ * @param knots uzlový vektor
+ */
+ public JKnotSlider(float[] knots) {
+ this();
+ if(knots!=null)
+ for(double d:knots)
+ addKnot(new Double(d));
+ }
+
+ /**
+ * Adds a knot
+ * Přidá uzel do uzlového vektoru
+ * @param d knot
+ */
+ public void addKnot(Double d) {
+// preserveState();
+ knots.add(new KnotPolygon(d, oneStep, top, side));
+ }
+
+
+ /**
+ * Saves actual knotvector for later recovery
+ * Uloží aktuální uzlový vektor pro pozdější obnovení
+ */
+ private void preserveState(){
+ previousState.clear();
+ previousState.addAll(knots);
+ }
+
+// /**
+// * Přidá uzel do uzlového vektoru
+// * @param d hodnota přidávaného uzlu
+// */
+// public void addKnot(double d) {
+// addKnot(new Double(d));
+// }
+
+ /**
+ * Returns knotvector
+ * Vrací uzlový vektor
+ * @return knotvector array
+ */
+ @SuppressWarnings("unchecked")
+ public double[] getKnots() {
+ double[] output = new double[knots.size()];
+ int i = 0;
+ if (activeKnot >= 0) {
+ Double d = knots.get(activeKnot).getValue();
+ Collections.sort(knots);
+ for (int j = 0; j < knots.size(); j++)
+ if (knots.get(j).getValue().equals(d)) {
+ activeKnot = j;
+ break;
+ }
+ } else
+ Collections.sort(knots);
+ for (KnotPolygon p : knots)
+ output[i++] = p.getValue().doubleValue();
+ return output;
+ }
+ /**
+ * Returns knotvector
+ * Vrací uzlový vektor
+ * @return knotvector array
+ */
+ public float[] getKnotsFloat(){
+ float[] output=new float[knots.size()];
+ int i=0;
+ for(double d:getKnots()){
+ output[i++]=(float) d;
+ }
+ return output;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
+ */
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ drawBaseLine((Graphics2D) g);
+ updateMultis((Graphics2D)g);
+ drawKnots((Graphics2D) g);
+ }
+
+ /**
+ * Draws info about knot multiplicity
+ * Vykreslí informaci o násobnosti uzlů
+ * @param graphics2D object to draw to
+ */
+ private void updateMultis(Graphics2D graphics2D) {
+ Vector<Integer> vrcholy=new Vector<Integer>();
+ for(int i=0;i<knots.size();i++){
+ knots.get(i).setMulti(0);
+ vrcholy.add(knots.get(i).xpoints[0]);
+ }
+
+ for(int i=0;i<knots.size();i++){
+ //k.xpoints[0] //hodnota na X -> počet stejných hodnot nám zjistí multiplicitu
+ for(Integer ii:vrcholy)
+ if(ii.intValue()==knots.get(i).xpoints[0])
+ knots.get(i).setMulti(knots.get(i).getMulti()+1);
+ }
+ }
+
+ /**
+ * Sends event to all notified listeners
+ * Pošle všem navešeným listenerům událost
+ * @param ae event being sent
+ */
+ private void notificateActionListeners(ActionEvent ae) {
+ for (ActionListener a : actionListeners)
+ a.actionPerformed(ae);
+ }
+
+ /**
+ * "Draws" knotvector
+ * Vykreslí reprezentaci uzlového vektoru
+ * @param g object to draw to
+ */
+ private void drawKnots(Graphics2D g) {
+ String txt;
+// int freq;
+ for (KnotPolygon p : knots) {
+ g.drawPolygon(p);
+ g.drawString(p.getMulti()+"x",p.xpoints[1],top);
+// freq=Collections.frequency(xVector,Integer.valueOf(p.xpoints[0]));
+// g.drawString(freq+"x",p.xpoints[1],top-8);
+ }
+ g.rotate(Math.PI / 2);
+ for (KnotPolygon p : knots) {
+ txt = p.getValue().toString();
+ if (txt.length() > 5)
+ txt = txt.substring(0, 4);
+ g.translate(top + 15, -p.xpoints[1]);
+ g.drawString(txt, 0, 0);
+ g.translate(-(top + 15), p.xpoints[1]);
+ }
+ }
+
+
+ /**
+ * Draws baseline
+ * Vykreslí základní linku
+ * @param g object to draw to
+ */
+ private void drawBaseLine(Graphics2D g) {
+ g.drawLine(side, top, (int) (side + (this.getWidth() * .8)), top);
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.Component#getMinimumSize()
+ */
+ @Override
+ public Dimension getMinimumSize() {
+ return new Dimension(100, 60);
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.Component#getPreferredSize()
+ */
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(250, 60);
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
+ */
+ public void componentResized(ComponentEvent e) {
+ int width = this.getWidth();
+ int height = this.getHeight();
+
+ side = (int) (width * .1);
+ top = (int) (height * .3);
+
+ width *= .8;
+ height *= .8;
+
+ oneStep = 1d / (width);
+
+ updateKnotPolygons();
+ repaint();
+ }
+
+ /**
+ * Updates all objects representing knots
+ * Aktualizuje nastavení všech objektů reprezentujících uzly
+ */
+ private void updateKnotPolygons() {
+ for (KnotPolygon p : knots) {
+ p.update(oneStep, top, side);
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
+ */
+ public void componentMoved(ComponentEvent e) {
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
+ */
+ public void componentShown(ComponentEvent e) {
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
+ */
+ public void componentHidden(ComponentEvent e) {
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
+ */
+ public void mouseDragged(MouseEvent e) {
+
+ if (activeKnot >= 0) {
+// preserveState();
+
+ if (e.getX() >= side && e.getX() <= (getWidth() * .8 + side)) {
+ knots.get(activeKnot).updateByX(e.getX());
+ } else if (e.getX() < side)
+ knots.get(activeKnot).updateByValue(new Double(0));
+ else
+ knots.get(activeKnot).updateByValue(new Double(1));
+
+ notificateActionListeners(new ActionEvent(this,
+ ActionEvent.ACTION_PERFORMED, KNOT_MOVED));
+ repaint();
+ }
+ }
+
+// private void updateXVector() {
+// xVector.clear();
+// for(KnotPolygon p:knots){
+// xVector.add(Integer.valueOf(p.xpoints[0]));
+// }
+// }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
+ */
+ public void mouseMoved(MouseEvent e) {
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
+ */
+ public void mouseClicked(MouseEvent e) {
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
+ */
+ public void mousePressed(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ KnotPolygon p;
+ this.activeKnot = -1;
+ for (int i = 0; i < knots.size(); i++) {
+ p = knots.get(i);
+ if (p.contains(x, y)) {
+ activeKnot = i;
+ break;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
+ */
+ public void mouseReleased(MouseEvent e) {
+ this.activeKnot = -1;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
+ */
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
+ */
+ public void mouseExited(MouseEvent e) {
+ }
+
+// /**
+// * Nastaví uzlový vektor
+// * @param knots nový uzlový vektor
+// */
+// public void setKnots(double[] knots) {
+// preserveState();
+// for(double d:knots)
+// addKnot(new Double(d));
+// repaint();
+// }
+ /**
+ * Sets knotvector
+ * Nastaví uzlový vektor
+ * @param knots new knotvector
+ */
+ public void setKnots(float[] knots) {
+// preserveState();
+ this.knots.clear();
+ for(double d:knots)
+ addKnot(new Double(d));
+ repaint();
+ }
+
+ /**
+ * Checks whether knot multiplicity is not bigger than given value
+ * Zkontroluje, zda násobnost uzlů nepřekročila zadanou hodnotu
+ * @param maxMulti maximum multiplicity
+ * @return true if multiplicity is NOT bigger
+ */
+ public boolean checkKnotMulti(int maxMulti) {
+ updateMultis((Graphics2D) this.getGraphics());
+ for(KnotPolygon p:knots)
+ if(p.getMulti()>maxMulti)
+ return false;
+ return true;
+ }
+
+// /**
+// * Obnosví poslední uložený stav uzlového vektoru
+// */
+// public void restoreState() {
+// knots.clear();
+// knots.addAll(previousState);
+// repaint();
+// }
+}
diff --git a/src/demos/nurbs/knotslidercomponent/KnotPolygon.java b/src/demos/nurbs/knotslidercomponent/KnotPolygon.java
new file mode 100755
index 0000000..5665392
--- /dev/null
+++ b/src/demos/nurbs/knotslidercomponent/KnotPolygon.java
@@ -0,0 +1,159 @@
+package demos.nurbs.knotslidercomponent;
+
+import java.awt.Polygon;
+
+/**
+ * Object representing knot
+ * Objekt reprezentující uzel v uzlovém vektoru
+ * @author Tomáš Hráský
+ *
+ */
+@SuppressWarnings("serial")
+class KnotPolygon extends Polygon implements Comparable {
+ /**
+ * Knot value
+ * Hodnota uzlu
+ */
+ private Double value;
+
+ /**
+ * Size of change when moved by one pixel
+ * Velikost změny při posunu o jeden pixel
+ */
+ private double oneStep;
+
+ /**
+ * Top space
+ * Horní mezera osy
+ */
+ private int top;
+
+ /**
+ * Side space
+ * Boční mezera osy
+ */
+ private int side;
+
+ /**
+ * Knot multiplicity
+ * Násobnost uzlu
+ */
+ private int multi;
+
+ /**
+ * Creates new instance with given values
+ * Vytvoří instanci se zadanými hodnotami
+ * @param d knot value
+ * @param oneStep change of one pixel movement
+ * @param top top space
+ * @param side side space
+ */
+ public KnotPolygon(Double d, double oneStep, int top, int side) {
+ this.value = d;
+ xpoints = new int[3];
+ ypoints = new int[3];
+ npoints = 3;
+ multi=1;
+ makeCoords(oneStep, top, side);
+ }
+
+ /**
+ * Computes coords of polygon representing knot
+ * Vypočte souřadnice polygonu reprezentujícího uzel
+ * @param oneStep change of one pixel movement
+ * @param top top space
+ * @param side side space
+ */
+ private void makeCoords(double oneStep, int top, int side) {
+ this.oneStep = oneStep;
+ this.top = top;
+ this.side = side;
+
+ int x = (int) (value / oneStep);
+ x += side;
+
+ xpoints[0] = x;
+ xpoints[1] = x - 4;
+ xpoints[2] = x + 4;
+ ypoints[0] = top + 2;
+ ypoints[1] = top + 12;
+ ypoints[2] = top + 12;
+
+ invalidate();
+ }
+
+ /**
+ * Computes coords from set values
+ * Vypočte souřadnice podle nastavených hodont
+ */
+ private void makeCoords() {
+ makeCoords(oneStep, top, side);
+ }
+
+ /**
+ * Computes coords from given values
+ * Vypočte souřadnice podle zadaných hodont
+ * @param oneStep step of one pixel movement
+ * @param top top space
+ * @param side side space
+ */
+ public void update(double oneStep, int top, int side) {
+ makeCoords(oneStep, top, side);
+ }
+
+ /**
+ * Updates coords from given coord of polygon top
+ * Upraví souřadnice podle nové zadané souřadnice vrcholu polygonu
+ * @param x nová souřadnice vrcholu
+ */
+ public void updateByX(int x) {
+ value = oneStep * (x - side);
+ makeCoords();
+ }
+
+ /**
+ * Updates coords from given value of knot
+ * Upraví souřadnice polygonu podle nové hodnoty
+ * @param d nová hodnota
+ */
+ public void updateByValue(Double d){
+ value=d;
+ makeCoords();
+ }
+
+ public int compareTo(Object o) {
+ if (o instanceof KnotPolygon) {
+ KnotPolygon kp = (KnotPolygon) o;
+ return getValue().compareTo(kp.getValue());
+ } else
+ return 0;
+ }
+
+ /**
+ * Returns knot value
+ * Vrací hodnotu uzlu
+ * @return knot value
+ */
+ public Double getValue() {
+ return value;
+ }
+
+ /**
+ * Returns knot multiplicity
+ * Vrací násobnost uzlu
+ * @return knot multiplicity
+ */
+ public int getMulti() {
+ return multi;
+ }
+
+ /**
+ * Sets knot multiplicity
+ * Nastavuje násobnost uzlu
+ * @param multi knot multiplicity
+ */
+ public void setMulti(int multi) {
+ this.multi = multi;
+ }
+
+}