Loading FaceData/src/main/java/cz/fidentis/analyst/data/face/HumanFace.java +6 −0 Original line number Diff line number Diff line Loading @@ -201,4 +201,10 @@ public interface HumanFace extends HumanFaceEventBus, Serializable { * @return {@code true}, if the bounding box exists */ boolean hasBoundingBox(); /** * Set a surface mask. * @param surfaceMask surfaceMask or {@code null} */ void setSurfaceMask(SurfaceMask surfaceMask); } FaceData/src/main/java/cz/fidentis/analyst/data/face/impl/HumanFaceImpl.java +6 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ public class HumanFaceImpl implements HumanFace { private final String id; private final transient SurfaceMask surfaceMask = new SurfaceMask(); private transient SurfaceMask surfaceMask = new SurfaceMask(); private List<Glyph> glyphs; Loading Loading @@ -314,6 +314,11 @@ public class HumanFaceImpl implements HumanFace { return boundingBox != null; } @Override public void setSurfaceMask(SurfaceMask surfaceMask) { this.surfaceMask = surfaceMask; } @Override public int hashCode() { return id.hashCode(); Loading GUI/src/main/java/cz/fidentis/analyst/gui/elements/SurfaceMaskPanel.java 0 → 100644 +216 −0 Original line number Diff line number Diff line /* * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template */ package cz.fidentis.analyst.gui.elements; import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.data.face.HumanFace; import cz.fidentis.analyst.data.shapes.SurfaceMask; import cz.fidentis.analyst.data.shapes.SurfaceMask2D; import cz.fidentis.analyst.gui.task.interactivemask.InteractiveMaskTaskNoParallel; import java.awt.Graphics; import java.awt.Color; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseEvent; /** * A panel to draw an interacitve mask on. * @author Mario Chromik */ public class SurfaceMaskPanel extends CurveRenderingPanel { /**private Canvas canvas; private HumanFace face; */ private final SurfaceMask2D surfaceMask = new SurfaceMask2D(); private ActionListener panelListener; /** * Constructor setting mouse listeners and drawing an initial mask. */ public SurfaceMaskPanel() { setBackground(Color.WHITE); Adapter ml = new Adapter(); addMouseListener(ml); addMouseMotionListener(new MotionAdapter()); drawInitialRectangleSM(); } /** /** * Sets canvas and face * @param canvas input canvas * @param face input face * public void setCanvasAndFace(Canvas canvas, HumanFace face) { this.canvas = canvas; this.face = face; } */ public SurfaceMask2D getSurfaceMask() { return surfaceMask; } /** * Draws an initial shape for surface mask */ private void drawInitialRectangleSM(){ surfaceMask.addPoint(new Point(100, 100)); surfaceMask.addPoint(new Point(100, 200)); surfaceMask.addPoint(new Point(200, 200)); surfaceMask.addPoint(new Point(200, 100)); repaint(); } /** * Draws the shape of an interactive mask * @param g panel graphics */ private void drawMaskLines(Graphics g) { for (int i = 0; i < surfaceMask.getMaskPoints().size() - 1; i++) { g.drawLine(surfaceMask.getMaskPoints().get(i).x, surfaceMask.getMaskPoints().get(i).y, surfaceMask.getMaskPoints().get(i + 1).x, surfaceMask.getMaskPoints().get(i + 1).y); g.drawOval(surfaceMask.getMaskPoints().get(i).x - 5, surfaceMask.getMaskPoints().get(i).y - 5, 10, 10); } //Close the mask g.drawOval(surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).x - 5, surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).y - 5, 10, 10); if (surfaceMask.getMaskPoints().size() >= 3) { g.drawLine(surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).x, surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).y, surfaceMask.getMaskPoints().get(0).x, surfaceMask.getMaskPoints().get(0).y); } } /** * Draws curves between points * @param g panel graphics * @param controlPoints a list of control points private void drawCurves(Graphics g, ArrayList<Point> controlPoints) { int n = controlPoints.size(); if (n >= 3) { for (int i = 0; i < n - 3; i += 3) { g.setColor(Color.RED); // Set your desired color for Bezier curves drawCurve(g, controlPoints.get(i).x, controlPoints.get(i).y, controlPoints.get(i+1).x, controlPoints.get(i+1).y, controlPoints.get(i+2).x, controlPoints.get(i+2).y); } } } * Draws a single curve * @param g panel graphics * @param x the X coordinate of the start point y1 * @param y the Y coordinate of the start point * @param x1 the X coordinate of the control point * @param y1 the Y coordinate of the control point * @param x2 the X coordinate of the end point * @param y2 the Y coordinate of the end point private void drawCurve(Graphics g, int x, int y, int x1, int y1, int x2, int y2) { Graphics2D g2 = (Graphics2D) g; QuadCurve2D q = new QuadCurve2D.Float(); q.setCurve(x, y, x1, y1, x2, y2); g2.draw(q); } /** * Projects points onto face using asynchronous thread / private void project() { /** Code used to intialize task and project points in parellel //cancel if task is already running task.cancel(false); task = new InteractiveMaskTask(canvas, pointsToProject, getPanelWidth(), getPanelHeight()); task.execute(); / InteractiveMaskTaskNoParallel task = new InteractiveMaskTaskNoParallel(canvas, surfaceMask.getPointsToProject(), getPanelWidth(), getPanelHeight()); task.project(); } */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); //face.setSurfaceMask(new SurfaceMask()); g.setColor(Color.BLACK); if (surfaceMask.getMaskPoints().size() >= 2) { drawMaskLines(g); } } /** * Gets panel width * @return integer panel width */ public int getPanelWidth() { return (int)this.getSize().getWidth(); } /** * Gets panel height * @return integer panel height */ public int getPanelHeight() { return (int)this.getSize().getHeight(); } public void addActionListener(ActionListener listener) { this.panelListener = listener; } /** * Custom mouse listener to handle drawing a mask * @author Mario Chromik */ class Adapter extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { if (! surfaceMask.selectPoint(e.getPoint())) { surfaceMask.addPoint(e.getPoint()); repaint(); } } @Override public void mouseReleased(MouseEvent e) { surfaceMask.setSelectedPoint(null); //project(); panelListener.actionPerformed( new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null)); } } /** * Custom mouse motion listener to hande dragging a point * @author Mario Chromik */ class MotionAdapter extends MouseMotionAdapter { @Override public void mouseDragged(MouseEvent e) { if (surfaceMask.getSelectedPoint() != null) { surfaceMask.getSelectedPoint().setLocation(e.getPoint()); repaint(); } } } } GUI/src/main/java/cz/fidentis/analyst/gui/task/featurepoints/FeaturePointsAction.java +1 −1 Original line number Diff line number Diff line Loading @@ -365,9 +365,9 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel> } } } } renderScene(); } } /** * Changes the colors of standard feature points (ON_THE_MESH_COLOR, CLOSE_TO_MESH_COLOR, customFpColor) and custom feature points Loading GUI/src/main/java/cz/fidentis/analyst/gui/task/interactivemask/InteractiveMaskAction.java +34 −42 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.task.interactivemask; import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.engines.face.events.HumanFaceSelectedEvent; import cz.fidentis.analyst.data.face.HumanFaceEvent; import cz.fidentis.analyst.data.face.HumanFaceListener; import cz.fidentis.analyst.data.shapes.SurfaceMask2D; import cz.fidentis.analyst.engines.face.FaceStateServices; import cz.fidentis.analyst.engines.interactivemask.MaskProjector; import cz.fidentis.analyst.engines.interactivemask.MaskProjectorConfig; import cz.fidentis.analyst.gui.task.ControlPanelAction; import cz.fidentis.analyst.project.FacesProxy; import cz.fidentis.analyst.data.ray.RayIntersection; import cz.fidentis.analyst.rendering.Camera; import javax.swing.*; import java.awt.event.ActionEvent; /** * * @author Mario Chromik */ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPanel> implements HumanFaceListener { public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPanel> { private String mode = InteractiveMaskPanel.ACTION_VIEW; private String mode = InteractiveMaskPanel.ACTION_DRAW; /** * Constructor Loading @@ -29,7 +31,9 @@ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPan */ public InteractiveMaskAction(Canvas canvas, FacesProxy faces, JTabbedPane topControlPane) { super(canvas, faces, topControlPane); setControlPanel(new InteractiveMaskPanel(this)); InteractiveMaskPanel pl = new InteractiveMaskPanel(this); setControlPanel(pl); setShowHideCode( () -> { // SHOW getCanvas().getScene().showInteractiveMask(getCanvas().getScene().getPrimaryFaceSlot(), true); Loading @@ -40,17 +44,30 @@ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPan getCanvas().getScene().showInteractiveMask(getCanvas().getScene().getSecondaryFaceSlot(), false); } ); getPrimaryDrawableFace().getHumanFace().registerListener(this); if (getSecondaryDrawableFace() != null) { getSecondaryDrawableFace().getHumanFace().registerListener(this); } private void project() { FaceStateServices.updateOctree(getPrimaryFace(), FaceStateServices.Mode.COMPUTE_IF_ABSENT); SurfaceMask2D mask = getControlPanel().getSurfaceMask(); MaskProjectorConfig config = new MaskProjectorConfig(getCanvas().getWidth(), getCanvas().getHeight(), getControlPanel().getSurfaceMaskPanel1().getPanelWidth(), getControlPanel().getSurfaceMaskPanel1().getPanelHeight(),Camera.FIELD_OF_VIEW, getCanvas().getCamera().getPosition(), getCanvas().getCamera().getCenter(), getCanvas().getCamera().getUpDirection()); MaskProjector mp = new MaskProjector(config, mask); getPrimaryFace().getOctree().accept(mp); getScene().setDrawableInteractiveMask(getScene().getPrimaryFaceSlot(), mp.getResult()); renderScene(); } @Override public void actionPerformed(ActionEvent ae) { String action = ae.getActionCommand(); switch (action) { case InteractiveMaskPanel.ACTION_PROJECT: project(); break; case InteractiveMaskPanel.ACTION_DRAW: mode = InteractiveMaskPanel.ACTION_DRAW; break; Loading @@ -62,29 +79,4 @@ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPan } } @Override public void acceptEvent(HumanFaceEvent event) { if (event instanceof HumanFaceSelectedEvent huEvent) { if (huEvent.getFace().equals(getPrimaryFace()) && getPrimaryInteractiveMask() == null) { getScene().setDrawableInteractiveMask(getScene().getPrimaryFaceSlot(), huEvent.getFace()); } if(huEvent.getFace().equals(getSecondaryFace()) && getSecondaryInteractiveMask() == null) { getScene().setDrawableInteractiveMask(getScene().getSecondaryFaceSlot(), huEvent.getFace()); } RayIntersection closestIntersection = huEvent.getIntersection(); if (mode.equals(InteractiveMaskPanel.ACTION_DRAW) && closestIntersection != null && huEvent.getFace().getSurfaceMask() != null) { huEvent.getFace().getSurfaceMask().addPoint( huEvent.getIntersection().getPosition(), huEvent.getIntersection().getHitTriangle().getFacet() ); } renderScene(); } } } Loading
FaceData/src/main/java/cz/fidentis/analyst/data/face/HumanFace.java +6 −0 Original line number Diff line number Diff line Loading @@ -201,4 +201,10 @@ public interface HumanFace extends HumanFaceEventBus, Serializable { * @return {@code true}, if the bounding box exists */ boolean hasBoundingBox(); /** * Set a surface mask. * @param surfaceMask surfaceMask or {@code null} */ void setSurfaceMask(SurfaceMask surfaceMask); }
FaceData/src/main/java/cz/fidentis/analyst/data/face/impl/HumanFaceImpl.java +6 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ public class HumanFaceImpl implements HumanFace { private final String id; private final transient SurfaceMask surfaceMask = new SurfaceMask(); private transient SurfaceMask surfaceMask = new SurfaceMask(); private List<Glyph> glyphs; Loading Loading @@ -314,6 +314,11 @@ public class HumanFaceImpl implements HumanFace { return boundingBox != null; } @Override public void setSurfaceMask(SurfaceMask surfaceMask) { this.surfaceMask = surfaceMask; } @Override public int hashCode() { return id.hashCode(); Loading
GUI/src/main/java/cz/fidentis/analyst/gui/elements/SurfaceMaskPanel.java 0 → 100644 +216 −0 Original line number Diff line number Diff line /* * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template */ package cz.fidentis.analyst.gui.elements; import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.data.face.HumanFace; import cz.fidentis.analyst.data.shapes.SurfaceMask; import cz.fidentis.analyst.data.shapes.SurfaceMask2D; import cz.fidentis.analyst.gui.task.interactivemask.InteractiveMaskTaskNoParallel; import java.awt.Graphics; import java.awt.Color; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseEvent; /** * A panel to draw an interacitve mask on. * @author Mario Chromik */ public class SurfaceMaskPanel extends CurveRenderingPanel { /**private Canvas canvas; private HumanFace face; */ private final SurfaceMask2D surfaceMask = new SurfaceMask2D(); private ActionListener panelListener; /** * Constructor setting mouse listeners and drawing an initial mask. */ public SurfaceMaskPanel() { setBackground(Color.WHITE); Adapter ml = new Adapter(); addMouseListener(ml); addMouseMotionListener(new MotionAdapter()); drawInitialRectangleSM(); } /** /** * Sets canvas and face * @param canvas input canvas * @param face input face * public void setCanvasAndFace(Canvas canvas, HumanFace face) { this.canvas = canvas; this.face = face; } */ public SurfaceMask2D getSurfaceMask() { return surfaceMask; } /** * Draws an initial shape for surface mask */ private void drawInitialRectangleSM(){ surfaceMask.addPoint(new Point(100, 100)); surfaceMask.addPoint(new Point(100, 200)); surfaceMask.addPoint(new Point(200, 200)); surfaceMask.addPoint(new Point(200, 100)); repaint(); } /** * Draws the shape of an interactive mask * @param g panel graphics */ private void drawMaskLines(Graphics g) { for (int i = 0; i < surfaceMask.getMaskPoints().size() - 1; i++) { g.drawLine(surfaceMask.getMaskPoints().get(i).x, surfaceMask.getMaskPoints().get(i).y, surfaceMask.getMaskPoints().get(i + 1).x, surfaceMask.getMaskPoints().get(i + 1).y); g.drawOval(surfaceMask.getMaskPoints().get(i).x - 5, surfaceMask.getMaskPoints().get(i).y - 5, 10, 10); } //Close the mask g.drawOval(surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).x - 5, surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).y - 5, 10, 10); if (surfaceMask.getMaskPoints().size() >= 3) { g.drawLine(surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).x, surfaceMask.getMaskPoints().get(surfaceMask.getMaskPoints().size() - 1).y, surfaceMask.getMaskPoints().get(0).x, surfaceMask.getMaskPoints().get(0).y); } } /** * Draws curves between points * @param g panel graphics * @param controlPoints a list of control points private void drawCurves(Graphics g, ArrayList<Point> controlPoints) { int n = controlPoints.size(); if (n >= 3) { for (int i = 0; i < n - 3; i += 3) { g.setColor(Color.RED); // Set your desired color for Bezier curves drawCurve(g, controlPoints.get(i).x, controlPoints.get(i).y, controlPoints.get(i+1).x, controlPoints.get(i+1).y, controlPoints.get(i+2).x, controlPoints.get(i+2).y); } } } * Draws a single curve * @param g panel graphics * @param x the X coordinate of the start point y1 * @param y the Y coordinate of the start point * @param x1 the X coordinate of the control point * @param y1 the Y coordinate of the control point * @param x2 the X coordinate of the end point * @param y2 the Y coordinate of the end point private void drawCurve(Graphics g, int x, int y, int x1, int y1, int x2, int y2) { Graphics2D g2 = (Graphics2D) g; QuadCurve2D q = new QuadCurve2D.Float(); q.setCurve(x, y, x1, y1, x2, y2); g2.draw(q); } /** * Projects points onto face using asynchronous thread / private void project() { /** Code used to intialize task and project points in parellel //cancel if task is already running task.cancel(false); task = new InteractiveMaskTask(canvas, pointsToProject, getPanelWidth(), getPanelHeight()); task.execute(); / InteractiveMaskTaskNoParallel task = new InteractiveMaskTaskNoParallel(canvas, surfaceMask.getPointsToProject(), getPanelWidth(), getPanelHeight()); task.project(); } */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); //face.setSurfaceMask(new SurfaceMask()); g.setColor(Color.BLACK); if (surfaceMask.getMaskPoints().size() >= 2) { drawMaskLines(g); } } /** * Gets panel width * @return integer panel width */ public int getPanelWidth() { return (int)this.getSize().getWidth(); } /** * Gets panel height * @return integer panel height */ public int getPanelHeight() { return (int)this.getSize().getHeight(); } public void addActionListener(ActionListener listener) { this.panelListener = listener; } /** * Custom mouse listener to handle drawing a mask * @author Mario Chromik */ class Adapter extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { if (! surfaceMask.selectPoint(e.getPoint())) { surfaceMask.addPoint(e.getPoint()); repaint(); } } @Override public void mouseReleased(MouseEvent e) { surfaceMask.setSelectedPoint(null); //project(); panelListener.actionPerformed( new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null)); } } /** * Custom mouse motion listener to hande dragging a point * @author Mario Chromik */ class MotionAdapter extends MouseMotionAdapter { @Override public void mouseDragged(MouseEvent e) { if (surfaceMask.getSelectedPoint() != null) { surfaceMask.getSelectedPoint().setLocation(e.getPoint()); repaint(); } } } }
GUI/src/main/java/cz/fidentis/analyst/gui/task/featurepoints/FeaturePointsAction.java +1 −1 Original line number Diff line number Diff line Loading @@ -365,9 +365,9 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel> } } } } renderScene(); } } /** * Changes the colors of standard feature points (ON_THE_MESH_COLOR, CLOSE_TO_MESH_COLOR, customFpColor) and custom feature points Loading
GUI/src/main/java/cz/fidentis/analyst/gui/task/interactivemask/InteractiveMaskAction.java +34 −42 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.task.interactivemask; import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.engines.face.events.HumanFaceSelectedEvent; import cz.fidentis.analyst.data.face.HumanFaceEvent; import cz.fidentis.analyst.data.face.HumanFaceListener; import cz.fidentis.analyst.data.shapes.SurfaceMask2D; import cz.fidentis.analyst.engines.face.FaceStateServices; import cz.fidentis.analyst.engines.interactivemask.MaskProjector; import cz.fidentis.analyst.engines.interactivemask.MaskProjectorConfig; import cz.fidentis.analyst.gui.task.ControlPanelAction; import cz.fidentis.analyst.project.FacesProxy; import cz.fidentis.analyst.data.ray.RayIntersection; import cz.fidentis.analyst.rendering.Camera; import javax.swing.*; import java.awt.event.ActionEvent; /** * * @author Mario Chromik */ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPanel> implements HumanFaceListener { public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPanel> { private String mode = InteractiveMaskPanel.ACTION_VIEW; private String mode = InteractiveMaskPanel.ACTION_DRAW; /** * Constructor Loading @@ -29,7 +31,9 @@ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPan */ public InteractiveMaskAction(Canvas canvas, FacesProxy faces, JTabbedPane topControlPane) { super(canvas, faces, topControlPane); setControlPanel(new InteractiveMaskPanel(this)); InteractiveMaskPanel pl = new InteractiveMaskPanel(this); setControlPanel(pl); setShowHideCode( () -> { // SHOW getCanvas().getScene().showInteractiveMask(getCanvas().getScene().getPrimaryFaceSlot(), true); Loading @@ -40,17 +44,30 @@ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPan getCanvas().getScene().showInteractiveMask(getCanvas().getScene().getSecondaryFaceSlot(), false); } ); getPrimaryDrawableFace().getHumanFace().registerListener(this); if (getSecondaryDrawableFace() != null) { getSecondaryDrawableFace().getHumanFace().registerListener(this); } private void project() { FaceStateServices.updateOctree(getPrimaryFace(), FaceStateServices.Mode.COMPUTE_IF_ABSENT); SurfaceMask2D mask = getControlPanel().getSurfaceMask(); MaskProjectorConfig config = new MaskProjectorConfig(getCanvas().getWidth(), getCanvas().getHeight(), getControlPanel().getSurfaceMaskPanel1().getPanelWidth(), getControlPanel().getSurfaceMaskPanel1().getPanelHeight(),Camera.FIELD_OF_VIEW, getCanvas().getCamera().getPosition(), getCanvas().getCamera().getCenter(), getCanvas().getCamera().getUpDirection()); MaskProjector mp = new MaskProjector(config, mask); getPrimaryFace().getOctree().accept(mp); getScene().setDrawableInteractiveMask(getScene().getPrimaryFaceSlot(), mp.getResult()); renderScene(); } @Override public void actionPerformed(ActionEvent ae) { String action = ae.getActionCommand(); switch (action) { case InteractiveMaskPanel.ACTION_PROJECT: project(); break; case InteractiveMaskPanel.ACTION_DRAW: mode = InteractiveMaskPanel.ACTION_DRAW; break; Loading @@ -62,29 +79,4 @@ public class InteractiveMaskAction extends ControlPanelAction<InteractiveMaskPan } } @Override public void acceptEvent(HumanFaceEvent event) { if (event instanceof HumanFaceSelectedEvent huEvent) { if (huEvent.getFace().equals(getPrimaryFace()) && getPrimaryInteractiveMask() == null) { getScene().setDrawableInteractiveMask(getScene().getPrimaryFaceSlot(), huEvent.getFace()); } if(huEvent.getFace().equals(getSecondaryFace()) && getSecondaryInteractiveMask() == null) { getScene().setDrawableInteractiveMask(getScene().getSecondaryFaceSlot(), huEvent.getFace()); } RayIntersection closestIntersection = huEvent.getIntersection(); if (mode.equals(InteractiveMaskPanel.ACTION_DRAW) && closestIntersection != null && huEvent.getFace().getSurfaceMask() != null) { huEvent.getFace().getSurfaceMask().addPoint( huEvent.getIntersection().getPosition(), huEvent.getIntersection().getHitTriangle().getFacet() ); } renderScene(); } } }