From 3956ed7f4c52740c38179dc69880455b61862ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20O=C5=A1lej=C5=A1ek?= <oslejsek@fi.muni.cz> Date: Tue, 25 Jan 2022 14:48:17 +0100 Subject: [PATCH] Resolve "Compute HD batch finalization by using OpenCL" --- GUI/pom.xml | 5 + .../batch/ApproxHausdorffDistTask.java | 104 ++---- .../batch/ApproxHausdorffDistTaskGPU.java | 352 ++++++++++++++++++ .../fidentis/analyst/batch/BatchAction.java | 4 +- .../cz/fidentis/analyst/batch/IcpTask.java | 2 +- .../cz/fidentis/analyst/canvas/Canvas.java | 8 +- .../canvas/toolbar/RenderingModeToolbox.java | 6 +- .../toolbar/SceneToolboxFaceToFace.java | 30 +- .../toolbar/SceneToolboxSingleFace.java | 6 +- .../analyst/core/ControlPanelAction.java | 8 +- .../analyst/distance/DistanceAction.java | 2 +- .../java/cz/fidentis/analyst/scene/Scene.java | 205 +++++----- .../analyst/symmetry/ProfilesAction.java | 8 +- .../analyst/symmetry/SymmetryAction.java | 24 +- 14 files changed, 542 insertions(+), 222 deletions(-) create mode 100644 GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTaskGPU.java diff --git a/GUI/pom.xml b/GUI/pom.xml index 5caa94cf..4a1aeea3 100644 --- a/GUI/pom.xml +++ b/GUI/pom.xml @@ -97,6 +97,11 @@ <artifactId>jogl-all-main</artifactId> <version>2.3.2</version> </dependency> + <dependency> + <groupId>org.jocl</groupId> + <artifactId>jocl</artifactId> + <version>2.0.4</version> + </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>MeshModel</artifactId> diff --git a/GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTask.java b/GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTask.java index 12ff1ab8..b904a525 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTask.java +++ b/GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTask.java @@ -21,8 +21,11 @@ import java.util.stream.DoubleStream; * A task that computes similarity of a set of faces by computing * the distance of faces to an average face and then combining these values * to get mutual similarity for all pairs. + * <p> + * The computation is accelerated by using multiple CPU cores concurrently. * The exact computation parameters are taken from the {@code BatchPanel}. - * + * </p> + * * @author Radek Oslejsek */ public class ApproxHausdorffDistTask extends SimilarityTask { @@ -97,7 +100,7 @@ public class ApproxHausdorffDistTask extends SimilarityTask { ); templateFace.getMeshModel().compute(hd, true); - // Store relative distances of individual vertices to the cache + // Store relative distances of individual vertices to the cache distCache.add(hd.getDistances() .values() .stream() @@ -105,7 +108,6 @@ public class ApproxHausdorffDistTask extends SimilarityTask { .collect(Collectors.toList())); face.removeKdTree(); // TO BE TESTED - //dist[i] = hd.getStats().getAverage(); hdComputationTime.stop(); } else { distCache.add(DoubleStream.generate(() -> 0.0d) @@ -142,10 +144,6 @@ public class ApproxHausdorffDistTask extends SimilarityTask { Logger.print(totalTime.toString()); } - protected double numCycles(int nFaces) { - return 0.5 * nFaces * (nFaces + 1); - } - @Deprecated protected void finalizeHD(List<List<Double>> distCache, long numVertices) { for (int i = 0; i < distCache.size(); i++) { @@ -174,11 +172,34 @@ public class ApproxHausdorffDistTask extends SimilarityTask { protected void finalizeHdConcurrently(List<List<Double>> distCache, long numVertices) { ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); - final List<Future<PairComparisonResult>> results = new ArrayList<>(); + final List<Future<Void>> results = new ArrayList<>(); for (int i = 0; i < distCache.size(); i++) { for (int j = i; j < distCache.size(); j++) { - results.add(executor.submit(new CallableHd(i, j, distCache.get(i), distCache.get(j)))); + assert(distCache.get(i).size() == distCache.get(i).size()); // should never happen + + final int fi = i; + final int fj = j; + + // Compute average HD for the pair of faces in a separate threat: + results.add(executor.submit(new Callable<Void>() { + @Override + public Void call() throws Exception { + double sum = 0.0; + int counter = 0; + for (int k = 0; k < distCache.get(fi).size(); k++) { + double d1 = distCache.get(fi).get(k); + double d2 = distCache.get(fj).get(k); + if (Double.isFinite(d1) && Double.isFinite(d2)) { + sum += Math.abs(d1 - d2); + counter++; + } + } + setDistSimilarity(fi, fj, sum / counter); + setDistSimilarity(fj, fi, sum / counter); + return null; + } + })); } } @@ -186,13 +207,9 @@ public class ApproxHausdorffDistTask extends SimilarityTask { while (!executor.isTerminated()){} try { int i = 0; - for (Future<PairComparisonResult> res: results) { - final PairComparisonResult hd = (PairComparisonResult) res.get(); // waits until all computations are finished - setDistSimilarity(hd.i, hd.j, hd.val); - setDistSimilarity(hd.j, hd.i, hd.val); - - // update progress bar - int progress = (int) Math.round(100.0 * (++i) / distCache.size()); + for (Future<Void> res: results) { + res.get(); // waits until all computations are finished + int progress = (int) Math.round(100.0 * (i+1) / results.size()); getProgressDialog().setValue(progress); } } catch (final InterruptedException | ExecutionException ex) { @@ -200,59 +217,4 @@ public class ApproxHausdorffDistTask extends SimilarityTask { } } - /** - * @author Radek Oslejsek - */ - private class PairComparisonResult { - public final int i; - public final int j; - public final double val; - - PairComparisonResult(int i, int j, double val) { - this.i = i; - this.j = j; - this.val = val; - } - } - - /** - * @author Radek Oslejsek - */ - private class CallableHd implements Callable<PairComparisonResult> { - private final List<Double> distancesI; - private final List<Double> distancesJ; - private final int i; - private final int j; - - /** - * Constructor. - * - * @param i index of the fist face - * @param j index of the second face - * @param distancesI distances of the first face vertices to the template face - * @param distancesJ distances of the second face vertices to the template face - */ - CallableHd(int i, int j, List<Double> distancesI, List<Double> distancesJ) { - this.i = i; - this.j = j; - this.distancesI = distancesI; - this.distancesJ = distancesJ; - } - - @Override - public PairComparisonResult call() throws Exception { - assert(distancesI.size() == distancesJ.size()); // should never happen - double sum = 0.0; - int counter = 0; - for (int k = 0; k < distancesI.size(); k++) { - double d1 = distancesI.get(k); - double d2 = distancesJ.get(k); - if (Double.isFinite(d1) && Double.isFinite(d2)) { - sum += Math.abs(d1 - d2); - counter++; - } - } - return new PairComparisonResult(i, j, sum / counter); - } - } } diff --git a/GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTaskGPU.java b/GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTaskGPU.java new file mode 100644 index 00000000..b95faa4a --- /dev/null +++ b/GUI/src/main/java/cz/fidentis/analyst/batch/ApproxHausdorffDistTaskGPU.java @@ -0,0 +1,352 @@ +package cz.fidentis.analyst.batch; + +import cz.fidentis.analyst.Logger; +import cz.fidentis.analyst.core.ProgressDialog; +import cz.fidentis.analyst.face.HumanFace; +import cz.fidentis.analyst.face.HumanFaceFactory; +import cz.fidentis.analyst.visitors.mesh.HausdorffDistance; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import java.util.stream.Collectors; +import org.jocl.CL; +import org.jocl.Pointer; +import org.jocl.Sizeof; +import org.jocl.cl_command_queue; +import org.jocl.cl_context; +import org.jocl.cl_context_properties; +import org.jocl.cl_device_id; +import org.jocl.cl_kernel; +import org.jocl.cl_mem; +import org.jocl.cl_platform_id; +import org.jocl.cl_program; +import org.jocl.cl_queue_properties; + +/** + * A GPU accelerated variant of {@link ApproxHausdorffDistTask}. + * The computation is accelerated by using both the CPU and GPU parallelism. + * The OpenCL code is based on + * {@see https://github.com/gpu/JOCLSamples/blob/master/src/main/java/org/jocl/samples/JOCLSample.java}. + * However, the computation is slower than using CPU-based multitasking only + * (For 500 faces, 40 seconds of the HD finalization phase on GPU compared to 18 second on 8-core CPU) + * This class is marked as deprecated for this reason. + * Use {@link ApproxHausdorffDistTask} instead. + * <p> + * The exact computation parameters are taken from the {@code BatchPanel}. + * </p> + * + * @author Radek Oslejsek + */ +@Deprecated +public class ApproxHausdorffDistTaskGPU extends SimilarityTask { + + /** + * OpenCL device + */ + private cl_device_id device; + + /** + * OpenCL context + */ + private cl_context context; + + /** + * OpenCL command queue + */ + private cl_command_queue commandQueue; + + /** + * Built OpenCL program + */ + private cl_program program; + + /** + * GPU memory where the distances of faces to the template face are stored + */ + private cl_mem[] srcArrays; + + private final Stopwatch totalTime = new Stopwatch("Total computation time:\t\t"); + private final Stopwatch hdComputationTime = new Stopwatch("Hausdorff distance preparation time:\t"); + private final Stopwatch loadTime = new Stopwatch("Disk access time:\t\t"); + private final Stopwatch kdTreeConstructionTime = new Stopwatch("KD trees construction time:\t\t"); + private final Stopwatch finalHdComputationTime = new Stopwatch("Hausdorff distance finalization time:\t"); + + private final int templateFaceIndex; + + /** + * The source code of the OpenCL program to execute + */ + private static final String PROGRAM_SOURCE = + "__kernel void "+ + "hdKernel(__global const float *a,"+ + " __global const float *b,"+ + " __global float *c)"+ + "{"+ + " int gid = get_global_id(0);"+ + " c[gid] = fabs(a[gid] - b[gid]);"+ + "}"; + + /** + * Constructor. + * + * @param progressDialog A window that show the progress of the computation. Must not be {@code null} + * @param controlPanel A control panel with computation parameters. Must not be {@code null} + * @param avgFace average face + */ + public ApproxHausdorffDistTaskGPU(ProgressDialog progressDialog, BatchPanel controlPanel, int templateFaceIndex) { + super(progressDialog, controlPanel); + this.templateFaceIndex = templateFaceIndex; + } + + @Override + protected Void doInBackground() throws Exception { + initOpenCL(); + + HumanFaceFactory factory = getControlPanel().getHumanFaceFactory(); + List<Path> faces = getControlPanel().getFacePaths(); + + totalTime.start(); + + factory.setReuseDumpFile(true); // it's safe because no changes are made to models + factory.setStrategy(HumanFaceFactory.Strategy.MRU); // keep first X faces in the memory + + // We don't need to reaload the initFace periodically for two reasons: + // - It is never dumped from memory to disk because we use MRU + // - Even if dumped, the face keeps in the mempry until we hold the pointer to it + loadTime.start(); + String templateFaceId = factory.loadFace(faces.get(templateFaceIndex).toFile()); + HumanFace templateFace = factory.getFace(templateFaceId); + loadTime.stop(); + + // Cache of distances of individual vertices in the GPU memory + // srcArrays[i] stores distance of vertices of i-th face to the template face + srcArrays = new cl_mem[faces.size()]; + int numVertices = (int) templateFace.getMeshModel().getNumVertices(); + + for (int i = 0; i < faces.size(); i++) { + + if (isCancelled()) { // the user canceled the process + return null; + } + + if (i != templateFaceIndex) { + + loadTime.start(); + String faceId = factory.loadFace(faces.get(i).toFile()); + HumanFace face = factory.getFace(faceId); + loadTime.stop(); + + kdTreeConstructionTime.start(); + face.computeKdTree(false); + kdTreeConstructionTime.stop(); + + hdComputationTime.start(); + HausdorffDistance hd = new HausdorffDistance( + face.getKdTree(), + HausdorffDistance.Strategy.POINT_TO_POINT, + true, // relative + true, // parallel + true // crop + ); + templateFace.getMeshModel().compute(hd, true); + + // Copy commputed distances into the GPU memory: + float[] auxDist = new float[numVertices]; + int k = 0; + for (float val: hd.getDistances().values().stream().flatMap(List::stream) + .map(x -> x.floatValue()).collect(Collectors.toList())) { + auxDist[k++] = val; + } + Pointer arrayP = Pointer.to(auxDist); + srcArrays[i] = CL.clCreateBuffer(context, + CL.CL_MEM_READ_ONLY | CL.CL_MEM_COPY_HOST_PTR, + Sizeof.cl_float * numVertices, arrayP, null); + + face.removeKdTree(); // TO BE TESTED + + hdComputationTime.stop(); + } else { // distance to template face itself is zero + float[] auxDist = new float[numVertices]; // filled by zeros by default + Pointer arrayP = Pointer.to(auxDist); + srcArrays[i] = CL.clCreateBuffer(context, + CL.CL_MEM_READ_ONLY | CL.CL_MEM_COPY_HOST_PTR, + Sizeof.cl_float * numVertices, arrayP, null); + } + + // update progress bar + int progress = (int) Math.round(100.0 * (i+1) / faces.size()); + getProgressDialog().setValue(progress); + + //Logger.print(factory.toString()); + } + + finalHdComputationTime.start(); + finalizeHdConcurrently(faces.size(), numVertices); + finalHdComputationTime.stop(); + + totalTime.stop(); + + printTimeStats(); + + return null; + } + + @Override + protected void done() { + super.done(); + CL.clReleaseCommandQueue(commandQueue); + CL.clReleaseContext(context); + } + + protected void printTimeStats() { + Logger.print(hdComputationTime.toString()); + Logger.print(loadTime.toString()); + Logger.print(finalHdComputationTime.toString()); + Logger.print(kdTreeConstructionTime.toString()); + Logger.print(totalTime.toString()); + } + + private void initOpenCL() { + // The platform, device type and device number that will be used + final int platformIndex = 0; + final long deviceType = CL.CL_DEVICE_TYPE_ALL; + final int deviceIndex = 0; + + // Enable exceptions and subsequently omit error checks in this sample + CL.setExceptionsEnabled(true); + + // Obtain the number of platforms + int[] numPlatformsArray = new int[1]; + CL.clGetPlatformIDs(0, null, numPlatformsArray); + int numPlatforms = numPlatformsArray[0]; + + // Obtain a platform ID + cl_platform_id[] platforms = new cl_platform_id[numPlatforms]; + CL.clGetPlatformIDs(platforms.length, platforms, null); + cl_platform_id platform = platforms[platformIndex]; + + // Initialize the context properties + cl_context_properties contextProperties = new cl_context_properties(); + contextProperties.addProperty(CL.CL_CONTEXT_PLATFORM, platform); + + // Obtain the number of devices for the platform + int[] numDevicesArray= new int[1]; + CL.clGetDeviceIDs(platform, deviceType, 0, null, numDevicesArray); + int numDevices = numDevicesArray[0]; + + // Obtain a device ID + cl_device_id[] devices= new cl_device_id[numDevices]; + CL.clGetDeviceIDs(platform, deviceType, numDevices, devices, null); + this.device = devices[deviceIndex]; + + // Create a context for the selected device + this.context = CL.clCreateContext( + contextProperties, 1, new cl_device_id[]{device}, + null, null, null); + + // Create a command-queue for the selected device + cl_queue_properties properties = new cl_queue_properties(); + commandQueue = CL.clCreateCommandQueueWithProperties( + context, device, properties, null); + + // Create the program from the source code + program = CL.clCreateProgramWithSource(context, + 1, new String[]{ PROGRAM_SOURCE }, null, null); + + // Build the program + CL.clBuildProgram(program, 0, null, null, null, null); + } + + protected void finalizeHdConcurrently(int numFaces, int numVertices) { + // Set the work-item dimensions + long[] globalWorkSize = new long[]{numVertices}; + + ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + final List<Future<Void>> results = new ArrayList<>(); + + for (int i = 0; i < numFaces; i++) { + for (int j = i; j < numFaces; j++) { + + if (i == j) { + continue; + } + + final int finalI = i; + final int finalJ = j; + + results.add(executor.submit(new Callable<Void>() { + @Override + public Void call() throws Exception { + float[] dstArray = new float[numVertices]; + + cl_mem dstMem = CL.clCreateBuffer(context, + CL.CL_MEM_READ_WRITE, + Sizeof.cl_float * numVertices, null, null); + Pointer dstP = Pointer.to(dstArray); + + // Create the kernel + cl_kernel kernel = CL.clCreateKernel(program, "hdKernel", null); + + // Set the arguments for the kernel + int a = 0; + CL.clSetKernelArg(kernel, a++, Sizeof.cl_mem, Pointer.to(srcArrays[finalI])); + CL.clSetKernelArg(kernel, a++, Sizeof.cl_mem, Pointer.to(srcArrays[finalJ])); + CL.clSetKernelArg(kernel, a++, Sizeof.cl_mem, Pointer.to(dstMem)); + + // Execute the kernel + CL.clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, + globalWorkSize, null, 0, null, null); + + // Read the output data + CL.clEnqueueReadBuffer(commandQueue, dstMem, CL.CL_TRUE, 0, + numVertices * Sizeof.cl_float, dstP, 0, null, null); + + // Release kernel + CL.clReleaseKernel(kernel); + CL.clReleaseMemObject(dstMem); + + // Compute average HD of the face pair + double sum = 0.0; + int counter = 0; + for (int k = 0; k < numVertices; k++) { + double d = dstArray[k]; + if (Double.isFinite(d)) { + sum += d; + counter++; + } + } + setDistSimilarity(finalI, finalJ, sum / counter); + setDistSimilarity(finalJ, finalI, sum / counter); + + return null; + } + })); + } + } + + executor.shutdown(); + while (!executor.isTerminated()){} + try { + int i = 0; + for (Future<Void> res: results) { + res.get(); // waits until all computations are finished + int progress = (int) Math.round(100.0 * (i+1) / results.size()); + getProgressDialog().setValue(progress); + } + } catch (final InterruptedException | ExecutionException ex) { + java.util.logging.Logger.getLogger(ApproxHausdorffDistTask.class.getName()).log(Level.SEVERE, null, ex); + } + + // Release Program, and memory objects + for (int i = 0; i < numFaces; i++) { + CL.clReleaseMemObject(srcArrays[i]); + } + CL.clReleaseProgram(program); + } +} diff --git a/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java b/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java index 18f1840e..79f143e9 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java @@ -118,7 +118,7 @@ public class BatchAction extends ControlPanelAction implements HumanFaceListener HumanFace selectedFace = controlPanel.getSelectedFace(); if (controlPanel.showIcpPreview() && selectedFace != null) { getScene().clearScene(); // scene is recovered automatically - see the event handler above - faceSceneSlot = getScene().getFreeIndex(); + faceSceneSlot = getScene().getFreeSlot(); // Add inital face to the scene: getScene().setDrawableFace(faceSceneSlot, selectedFace); @@ -167,7 +167,7 @@ public class BatchAction extends ControlPanelAction implements HumanFaceListener HumanFace face = controlPanel.getSelectedFace(); if (face != null) { if (faceSceneSlot == -1) { - faceSceneSlot = getScene().getFreeIndex(); + faceSceneSlot = getScene().getFreeSlot(); } getScene().setDrawableFace(faceSceneSlot, face); getScene().setFaceAsPrimary(faceSceneSlot); diff --git a/GUI/src/main/java/cz/fidentis/analyst/batch/IcpTask.java b/GUI/src/main/java/cz/fidentis/analyst/batch/IcpTask.java index 2da9a800..8dac7dd7 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/batch/IcpTask.java +++ b/GUI/src/main/java/cz/fidentis/analyst/batch/IcpTask.java @@ -177,7 +177,7 @@ public class IcpTask extends SwingWorker<MeshModel, HumanFace> { } if (controlPanel.showIcpPreview()) { if (faceSceneSlot == -1) { - faceSceneSlot = canvas.getScene().getFreeIndex(); + faceSceneSlot = canvas.getScene().getFreeSlot(); } canvas.getScene().setDrawableFace(faceSceneSlot, f); canvas.getScene().getDrawableFace(faceSceneSlot).setTransparency(0.5f); diff --git a/GUI/src/main/java/cz/fidentis/analyst/canvas/Canvas.java b/GUI/src/main/java/cz/fidentis/analyst/canvas/Canvas.java index c0be1ee3..29feb057 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/canvas/Canvas.java +++ b/GUI/src/main/java/cz/fidentis/analyst/canvas/Canvas.java @@ -84,7 +84,7 @@ public class Canvas extends JPanel { public int addPrimaryFace(HumanFace face) { if (face != null) { faces.add(face); - int index = scene.getFreeIndex(); + int index = scene.getFreeSlot(); scene.setHumanFace(index, face); scene.setFaceAsPrimary(index); return index; @@ -101,7 +101,7 @@ public class Canvas extends JPanel { public int addSecondaryFace(HumanFace face) { if (face != null) { faces.add(face); - int index = scene.getFreeIndex(); + int index = scene.getFreeSlot(); scene.setHumanFace(index, face); scene.setFaceAsSecondary(index); return index; @@ -148,7 +148,7 @@ public class Canvas extends JPanel { * @return index of the primary face or -1 */ public int getPrimaryFaceIndex() { - return scene.getPrimaryFaceIndex(); + return scene.getPrimaryFaceSlot(); } /** @@ -156,7 +156,7 @@ public class Canvas extends JPanel { * @return index of the secondary face or -1 */ public int getSecondaryFaceIndex() { - return scene.getSecondaryFaceIndex(); + return scene.getSecondaryFaceSlot(); } /** diff --git a/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/RenderingModeToolbox.java b/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/RenderingModeToolbox.java index 36292aaa..5aa3e880 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/RenderingModeToolbox.java +++ b/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/RenderingModeToolbox.java @@ -36,7 +36,7 @@ public class RenderingModeToolbox extends JPopupMenu { JMenuItem menuItem1 = new JMenuItem(new AbstractAction() { // fill @Override public void actionPerformed(ActionEvent e) { - canvas.getScene().getFaceIndices().forEach(i -> { + canvas.getScene().getFaceSlots().forEach(i -> { canvas.getScene().getDrawableFace(i).setRenderMode(GL2.GL_FILL); }); canvas.renderScene(); @@ -46,7 +46,7 @@ public class RenderingModeToolbox extends JPopupMenu { JMenuItem menuItem2 = new JMenuItem(new AbstractAction() { // lines @Override public void actionPerformed(ActionEvent e) { - canvas.getScene().getFaceIndices().forEach(i -> { + canvas.getScene().getFaceSlots().forEach(i -> { canvas.getScene().getDrawableFace(i).setRenderMode(GL2.GL_LINE); }); canvas.renderScene(); @@ -56,7 +56,7 @@ public class RenderingModeToolbox extends JPopupMenu { JMenuItem menuItem3 = new JMenuItem(new AbstractAction() { // points @Override public void actionPerformed(ActionEvent e) { - canvas.getScene().getFaceIndices().forEach(i -> { + canvas.getScene().getFaceSlots().forEach(i -> { canvas.getScene().getDrawableFace(i).setRenderMode(GL2.GL_POINT); }); canvas.renderScene(); diff --git a/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxFaceToFace.java b/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxFaceToFace.java index c0423288..984f9ac2 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxFaceToFace.java +++ b/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxFaceToFace.java @@ -51,23 +51,23 @@ public class SceneToolboxFaceToFace extends JPanel { // Change inital state: primLandButton.setSelected(false); - DrawableFeaturePoints fp0 = canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceIndex()); + DrawableFeaturePoints fp0 = canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceSlot()); if (fp0 != null) { fp0.show(false); } secLandButton.setSelected(false); - DrawableFeaturePoints fp1 = canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getSecondaryFaceIndex()); + DrawableFeaturePoints fp1 = canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getSecondaryFaceSlot()); if (fp1 != null) { fp1.show(false); } secDistButton.setSelected(true); - canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceIndex()).setRenderHeatmap(true); + canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceSlot()).setRenderHeatmap(true); slider.setValue(30); - canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceIndex()).setTransparency(30/(float)TRANSPARENCY_RANGE); - canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceIndex()).setTransparency(1); + canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceSlot()).setTransparency(30/(float)TRANSPARENCY_RANGE); + canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceSlot()).setTransparency(1); } private void initComponents() { @@ -94,7 +94,7 @@ public class SceneToolboxFaceToFace extends JPanel { @Override public void actionPerformed(ActionEvent e) { boolean onOff = ((JToggleButton) e.getSource()).isSelected(); - canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceIndex()).show(onOff); + canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceSlot()).show(onOff); canvas.renderScene(); } }); @@ -119,7 +119,7 @@ public class SceneToolboxFaceToFace extends JPanel { @Override public void actionPerformed(ActionEvent e) { boolean onOff = ((JToggleButton) e.getSource()).isSelected(); - canvas.getScene().showDrawableFace(canvas.getScene().getPrimaryFaceIndex(), onOff); + canvas.getScene().showDrawableFace(canvas.getScene().getPrimaryFaceSlot(), onOff); canvas.renderScene(); } }); @@ -138,12 +138,12 @@ public class SceneToolboxFaceToFace extends JPanel { slider.addChangeListener((ChangeEvent e) -> { int val = ((JSlider) e.getSource()).getValue(); if (val <= TRANSPARENCY_RANGE) { - canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceIndex()) + canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceSlot()) .setTransparency(val/(float)TRANSPARENCY_RANGE); - canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceIndex()).setTransparency(1); + canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceSlot()).setTransparency(1); } else if (val > TRANSPARENCY_RANGE) { - canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceIndex()).setTransparency(1); - canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceIndex()) + canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceSlot()).setTransparency(1); + canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceSlot()) .setTransparency((2 * TRANSPARENCY_RANGE - val) / (float)TRANSPARENCY_RANGE); } canvas.renderScene(); @@ -169,7 +169,7 @@ public class SceneToolboxFaceToFace extends JPanel { @Override public void actionPerformed(ActionEvent e) { boolean onOff = ((JToggleButton) e.getSource()).isSelected(); - canvas.getScene().showDrawableFace(canvas.getScene().getSecondaryFaceIndex(), onOff); + canvas.getScene().showDrawableFace(canvas.getScene().getSecondaryFaceSlot(), onOff); canvas.renderScene(); } }); @@ -195,7 +195,7 @@ public class SceneToolboxFaceToFace extends JPanel { @Override public void actionPerformed(ActionEvent e) { boolean onOff = ((JToggleButton) e.getSource()).isSelected(); - canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getSecondaryFaceIndex()).show(onOff); + canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getSecondaryFaceSlot()).show(onOff); canvas.renderScene(); } }); @@ -220,9 +220,9 @@ public class SceneToolboxFaceToFace extends JPanel { @Override public void actionPerformed(ActionEvent e) { if (((JToggleButton) e.getSource()).isSelected()) { - canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceIndex()).setRenderHeatmap(true); + canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceSlot()).setRenderHeatmap(true); } else { - canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceIndex()).setRenderHeatmap(false); + canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceSlot()).setRenderHeatmap(false); } // Switch: //canvas.getScene().getDrawableFace(secIndex).setRenderHeatmap( diff --git a/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxSingleFace.java b/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxSingleFace.java index a0e045dc..b5078bcb 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxSingleFace.java +++ b/GUI/src/main/java/cz/fidentis/analyst/canvas/toolbar/SceneToolboxSingleFace.java @@ -68,7 +68,7 @@ public class SceneToolboxSingleFace extends JPanel { @Override public void actionPerformed(ActionEvent e) { boolean onOff = ((JToggleButton) e.getSource()).isSelected(); - canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceIndex()).show(onOff); + canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceSlot()).show(onOff); canvas.renderScene(); } }); @@ -93,7 +93,7 @@ public class SceneToolboxSingleFace extends JPanel { @Override public void actionPerformed(ActionEvent e) { boolean onOff = ((JToggleButton) e.getSource()).isSelected(); - canvas.getScene().showDrawableFace(canvas.getScene().getPrimaryFaceIndex(), onOff); + canvas.getScene().showDrawableFace(canvas.getScene().getPrimaryFaceSlot(), onOff); canvas.renderScene(); } }); @@ -111,7 +111,7 @@ public class SceneToolboxSingleFace extends JPanel { slider.addChangeListener((ChangeEvent e) -> { int val = ((JSlider) e.getSource()).getValue(); - canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceIndex()).setTransparency(val/100f); + canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceSlot()).setTransparency(val/100f); canvas.renderScene(); }); diff --git a/GUI/src/main/java/cz/fidentis/analyst/core/ControlPanelAction.java b/GUI/src/main/java/cz/fidentis/analyst/core/ControlPanelAction.java index 0ca16a83..75021c0f 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/core/ControlPanelAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/core/ControlPanelAction.java @@ -72,25 +72,25 @@ public abstract class ControlPanelAction extends AbstractAction { protected DrawableFace getPrimaryDrawableFace() { return (canvas.getScene() != null) - ? canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceIndex()) + ? canvas.getScene().getDrawableFace(canvas.getScene().getPrimaryFaceSlot()) : null; } protected DrawableFace getSecondaryDrawableFace() { return (canvas.getScene() != null) - ? canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceIndex()) + ? canvas.getScene().getDrawableFace(canvas.getScene().getSecondaryFaceSlot()) : null; } protected DrawableFeaturePoints getPrimaryFeaturePoints() { return (canvas.getScene() != null) - ? canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceIndex()) + ? canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getPrimaryFaceSlot()) : null; } protected DrawableFeaturePoints getSecondaryFeaturePoints() { return (canvas.getScene() != null) - ? canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getSecondaryFaceIndex()) + ? canvas.getScene().getDrawableFeaturePoints(canvas.getScene().getSecondaryFaceSlot()) : null; } diff --git a/GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java b/GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java index 71162781..455ab3f8 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java @@ -93,7 +93,7 @@ public class DistanceAction extends ControlPanelAction implements HumanFaceListe // Add spheres to the scene fpSpheres = new DrawableFpWeights(getSecondaryFeaturePoints().getFeaturePoints()); - getCanvas().getScene().setOtherDrawable(getCanvas().getScene().getFreeIndexForOtherDrawables(), fpSpheres); + getCanvas().getScene().setOtherDrawable(getCanvas().getScene().getFreeSlotForOtherDrawables(), fpSpheres); // Place control panel to the topControlPanel topControlPanel.addTab(controlPanel.getName(), controlPanel.getIcon(), controlPanel); diff --git a/GUI/src/main/java/cz/fidentis/analyst/scene/Scene.java b/GUI/src/main/java/cz/fidentis/analyst/scene/Scene.java index 0a319fc0..28613b1a 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/scene/Scene.java +++ b/GUI/src/main/java/cz/fidentis/analyst/scene/Scene.java @@ -22,8 +22,8 @@ public class Scene { private final List<DrawablePlane> drawableSymmetryPlanes = new ArrayList<>(); private final List<Drawable> otherDrawables = new ArrayList<>(); - private int primaryFaceIndex = -1; - private int secondaryFaceIndex = -1; + private int primaryFaceSlot = -1; + private int secondaryFaceSlot = -1; public static final int MAX_FACES_IN_SCENE = 20; @@ -35,87 +35,87 @@ public class Scene { this.drawableFeaturePoints.clear(); this.drawableSymmetryPlanes.clear(); this.otherDrawables.clear(); - primaryFaceIndex = -1; - secondaryFaceIndex = -1; + primaryFaceSlot = -1; + secondaryFaceSlot = -1; } /** - * Finds and returns a first free index for human face and its drawables. - * @return a first free index for human face and its drawables. + * Finds and returns a first free slot for human face and its drawables. + * @return a first free slot for human face and its drawables. */ - public int getFreeIndex() { - int index = -1; + public int getFreeSlot() { + int slot = -1; for (int i = 0; i < getArraySize(); i++) { if (this.drawableFaces.get(i) == null) { - index = i; + slot = i; break; } } - if (index == -1) { - index = getArraySize(); + if (slot == -1) { + slot = getArraySize(); } - return (index < Scene.MAX_FACES_IN_SCENE) ? index : -1; + return (slot < Scene.MAX_FACES_IN_SCENE) ? slot : -1; } /** - * Finds and returns a first free index for other drawable objects. - * @return a first free index for other drawable objects. + * Finds and returns a first free slot for other drawable objects. + * @return a first free slot for other drawable objects. */ - public int getFreeIndexForOtherDrawables() { - int index = -1; + public int getFreeSlotForOtherDrawables() { + int slot = -1; for (int i = 0; i < this.otherDrawables.size(); i++) { if (this.otherDrawables.get(i) == null) { - index = i; + slot = i; break; } } - if (index == -1) { - index = otherDrawables.size(); + if (slot == -1) { + slot = otherDrawables.size(); } - return (index < Scene.MAX_FACES_IN_SCENE) ? index : -1; + return (slot < Scene.MAX_FACES_IN_SCENE) ? slot : -1; } /** - * Returns index of the primary face or -1 - * @return index of the primary face or -1 + * Returns slot of the primary face or -1 + * @return slot of the primary face or -1 */ - public int getPrimaryFaceIndex() { - return this.primaryFaceIndex; + public int getPrimaryFaceSlot() { + return this.primaryFaceSlot; } /** - * Returns index of the secondary face or -1 - * @return index of the secondary face or -1 + * Returns slot of the secondary face or -1 + * @return slot of the secondary face or -1 */ - public int getSecondaryFaceIndex() { - return this.secondaryFaceIndex; + public int getSecondaryFaceSlot() { + return this.secondaryFaceSlot; } /** * Sets the given face as primary. - * @param index Index of the face that should be set as primary + * @param slot slot of the face that should be set as primary */ - public void setFaceAsPrimary(int index) { - if (index >= 0 && index < getArraySize()) { - this.primaryFaceIndex = index; + public void setFaceAsPrimary(int slot) { + if (slot >= 0 && slot < getArraySize()) { + this.primaryFaceSlot = slot; } } /** * Sets the given face as secondary. - * @param index Index of the face that should be set as secondary + * @param slot slot of the face that should be set as secondary */ - public void setFaceAsSecondary(int index) { - if (index >= 0 && index < getArraySize()) { - this.secondaryFaceIndex = index; + public void setFaceAsSecondary(int slot) { + if (slot >= 0 && slot < getArraySize()) { + this.secondaryFaceSlot = slot; } } /** - * Returns all "occupied" indices, i.e., indexes where is stored some human face. - * @return "occupied" indices, i.e., indexes where is stored some human face. + * Returns all "occupied" slots, i.e., indexes where some human face is stored. + * @return "occupied" slots, i.e., indexes where some human face is stored. */ - public List<Integer> getFaceIndices() { + public List<Integer> getFaceSlots() { List<Integer> ret = new ArrayList<>(); for (int i = 0; i < this.drawableFaces.size(); i++) { if (this.drawableFaces.get(i) != null) { @@ -128,48 +128,48 @@ public class Scene { /** * Returns drawable face. * - * @param index Index of the face + * @param slot Slot of the face * @return drawable face or {@code null} */ - public DrawableFace getDrawableFace(int index) { - return (index < 0 || index >= getArraySize()) ? null : drawableFaces.get(index); + public DrawableFace getDrawableFace(int slot) { + return (slot < 0 || slot >= getArraySize()) ? null : drawableFaces.get(slot); } /** * Sets the face and all its existing drawable components. * If the face is {@code null}, then the drawable face and all its components are removed. * - * @param index Index of the face + * @param slot Slot of the face * @param face New face or {@code null} * @return */ - public boolean setHumanFace(int index, HumanFace face) { - return setDrawableFace(index, face) && - setDrawableFeaturePoints(index, face) && - setDrawableSymmetryPlane(index, face); + public boolean setHumanFace(int slot, HumanFace face) { + return setDrawableFace(slot, face) && + setDrawableFeaturePoints(slot, face) && + setDrawableSymmetryPlane(slot, face); } /** * Sets the drawable face (mesh). If the face is {@code null}, then the drawable face is removed. * - * @param index Index of the face + * @param slot Slot of the face * @param face New face or {@code null} */ - public boolean setDrawableFace(int index, HumanFace face) { - if (index < 0 || index >= Scene.MAX_FACES_IN_SCENE) { + public boolean setDrawableFace(int slot, HumanFace face) { + if (slot < 0 || slot >= Scene.MAX_FACES_IN_SCENE) { return false; } else if (face == null) { // remove - if (index >= getArraySize()){ + if (slot >= getArraySize()){ return false; } else { - this.drawableFaces.set(index, null); + this.drawableFaces.set(slot, null); return true; } - } else if (!prepareArrays(index, face)) { + } else if (!prepareArrays(slot, face)) { return false; } - drawableFaces.set(index, new DrawableFace(face)); + drawableFaces.set(slot, new DrawableFace(face)); return true; } @@ -178,25 +178,25 @@ public class Scene { * Sets the drawable feature points of the face. * If the face is {@code null}, then the drawable feature points are removed. * - * @param index Index of the face + * @param slot Slot of the face * @param face New face or {@code null} */ - public boolean setDrawableFeaturePoints(int index, HumanFace face) { - if (index < 0 || index >= Scene.MAX_FACES_IN_SCENE) { + public boolean setDrawableFeaturePoints(int slot, HumanFace face) { + if (slot < 0 || slot >= Scene.MAX_FACES_IN_SCENE) { return false; } else if (face == null) { // remove - if (index >= getArraySize()){ + if (slot >= getArraySize()){ return false; } else { - this.drawableFeaturePoints.set(index, null); + this.drawableFeaturePoints.set(slot, null); return true; } - } else if (!prepareArrays(index, face)) { + } else if (!prepareArrays(slot, face)) { return false; } drawableFeaturePoints.set( - index, + slot, (face.getFeaturePoints() != null) ? new DrawableFeaturePoints(face.getFeaturePoints()) : null @@ -209,25 +209,25 @@ public class Scene { * Sets the drawable symmetry plane of the face. * If the face is {@code null}, then the drawable symmetry plane is removed. * - * @param index Index of the face + * @param slot Slot of the face * @param face New face or {@code null} */ - public boolean setDrawableSymmetryPlane(int index, HumanFace face) { - if (index < 0 || index >= Scene.MAX_FACES_IN_SCENE) { + public boolean setDrawableSymmetryPlane(int slot, HumanFace face) { + if (slot < 0 || slot >= Scene.MAX_FACES_IN_SCENE) { return false; } else if (face == null) { // remove - if (index >= getArraySize()){ + if (slot >= getArraySize()){ return false; } else { - this.drawableSymmetryPlanes.set(index, null); + this.drawableSymmetryPlanes.set(slot, null); return true; } - } else if (!prepareArrays(index, face)) { + } else if (!prepareArrays(slot, face)) { return false; } drawableSymmetryPlanes.set( - index, + slot, (face.getSymmetryPlane() != null && face.getSymmetryPlaneFacet() != null) ? new DrawablePlane(face.getSymmetryPlaneFacet(), face.getSymmetryPlane()) : null @@ -240,25 +240,25 @@ public class Scene { * Sets other drawable. * If the drawable is {@code null}, then the drawable is removed. * - * @param index Index of the drawable + * @param slot Slot of the drawable * @param face New face or {@code null} */ - public boolean setOtherDrawable(int index, Drawable dr) { - if (index < 0 || index >= Scene.MAX_FACES_IN_SCENE) { + public boolean setOtherDrawable(int slot, Drawable dr) { + if (slot < 0 || slot >= Scene.MAX_FACES_IN_SCENE) { return false; } else if (dr == null) { // remove - if (index >= otherDrawables.size()){ + if (slot >= otherDrawables.size()){ return false; } else { - otherDrawables.set(index, null); + otherDrawables.set(slot, null); return true; } } - for (int i = otherDrawables.size(); i <= index; i++) { + for (int i = otherDrawables.size(); i <= slot; i++) { otherDrawables.add(null); } - otherDrawables.set(index, dr); + otherDrawables.set(slot, dr); return true; } @@ -268,18 +268,18 @@ public class Scene { public final void setDefaultColors() { for (int i = 0; i < getArraySize(); i++) { if (drawableFaces.get(i) != null) { - if (i == this.primaryFaceIndex) { + if (i == this.primaryFaceSlot) { drawableFaces.get(i).setColor(DrawableFace.SKIN_COLOR_PRIMARY); - } else if (i == this.secondaryFaceIndex) { + } else if (i == this.secondaryFaceSlot) { drawableFaces.get(i).setColor(DrawableFace.SKIN_COLOR_SECONDARY); } else { drawableFaces.get(i).setColor(DrawableFace.SKIN_COLOR_DEFAULT); } } if (drawableFeaturePoints.get(i) != null) { - if (i == this.primaryFaceIndex) { + if (i == this.primaryFaceSlot) { drawableFeaturePoints.get(i).setColor(getColorOfFeaturePoints(DrawableFace.SKIN_COLOR_PRIMARY)); - } else if (i == this.secondaryFaceIndex) { + } else if (i == this.secondaryFaceSlot) { drawableFeaturePoints.get(i).setColor(getColorOfFeaturePoints(DrawableFace.SKIN_COLOR_SECONDARY)); } else { drawableFeaturePoints.get(i).setColor(getColorOfFeaturePoints(DrawableFace.SKIN_COLOR_DEFAULT)); @@ -298,66 +298,67 @@ public class Scene { /** * Returns drawable feature points. * - * @param index Index of the face + * @param slot Slot of the face * @return drawable face or {@code null} */ - public DrawableFeaturePoints getDrawableFeaturePoints(int index) { - return (index >= 0 && index < getArraySize()) ? drawableFeaturePoints.get(index) : null; + public DrawableFeaturePoints getDrawableFeaturePoints(int slot) { + return (slot >= 0 && slot < getArraySize()) ? drawableFeaturePoints.get(slot) : null; } /** * Returns drawable symmetry plane. * - * @param index Index of the face + * @param slot Slot of the face * @return drawable plane or {@code null} */ - public DrawablePlane getDrawableSymmetryPlane(int index) { - return (index >= 0 && index < getArraySize()) ? drawableSymmetryPlanes.get(index) : null; + public DrawablePlane getDrawableSymmetryPlane(int slot) { + return (slot >= 0 && slot < getArraySize()) ? drawableSymmetryPlanes.get(slot) : null; } /** * Showing or hiding the face (its mesh) * - * @param index Index of the face + * @param slot Slot of the face * @param show determines whether to hide or show the object */ - public void showDrawableFace(int index, boolean show) { - if (index >= 0 && index < getArraySize() && this.drawableFaces.get(index) != null) { - this.drawableFaces.get(index).show(show); + public void showDrawableFace(int slot, boolean show) { + if (slot >= 0 && slot < getArraySize() && this.drawableFaces.get(slot) != null) { + this.drawableFaces.get(slot).show(show); } } /** * Showing or hiding the feature points * - * @param index Index of the face + * @param slot Slot of the face * @param show determines whether to hide or show the object */ - public void showFeaturePoints(int index, boolean show) { - if (index >= 0 && index < getArraySize() && this.drawableFeaturePoints.get(index) != null) { - this.drawableFeaturePoints.get(index).show(show); + public void showFeaturePoints(int slot, boolean show) { + if (slot >= 0 && slot < getArraySize() && this.drawableFeaturePoints.get(slot) != null) { + this.drawableFeaturePoints.get(slot).show(show); } } /** * Showing or hiding the symmetry plane * - * @param index Index of the face + * @param slot Slot of the face * @param show determines whether to hide or show the object */ - public void showSymmetryPlane(int index, boolean show) { - if (index >= 0 && index < getArraySize() && this.drawableSymmetryPlanes.get(index) != null) { - this.drawableSymmetryPlanes.get(index).show(show); + public void showSymmetryPlane(int slot, boolean show) { + if (slot >= 0 && slot < getArraySize() && this.drawableSymmetryPlanes.get(slot) != null) { + this.drawableSymmetryPlanes.get(slot).show(show); } } /** * Returns other drawable object. * + * @param slot Slot of the drawable object * @return drawable object or {@code null} */ - public Drawable getOtherDrawable(int index) { - return (index >= 0 && index < this.otherDrawables.size()) ? this.otherDrawables.get(index) : null; + public Drawable getOtherDrawable(int slot) { + return (slot >= 0 && slot < this.otherDrawables.size()) ? this.otherDrawables.get(slot) : null; } /** @@ -383,13 +384,13 @@ public class Scene { ); } - protected boolean prepareArrays(int index, Object drawable) { - if (index >= Scene.MAX_FACES_IN_SCENE) { + protected boolean prepareArrays(int slot, Object drawable) { + if (slot >= Scene.MAX_FACES_IN_SCENE) { return false; } // extend the - for (int i = getArraySize(); i <= index; i++) { + for (int i = getArraySize(); i <= slot; i++) { this.drawableFaces.add(null); this.drawableFeaturePoints.add(null); this.drawableSymmetryPlanes.add(null); diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java index 4aa180ad..6eab131f 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java @@ -285,13 +285,13 @@ public class ProfilesAction extends ControlPanelAction implements HumanFaceListe protected void computeOrthogonalCuttingPlanes(boolean horizontal) { DrawableCuttingPlane drPlane = getDrawableOrthogonalPlane(horizontal); if (priCuttingPlaneIndex == -1) { - priCuttingPlaneIndex = getCanvas().getScene().getFreeIndexForOtherDrawables(); + priCuttingPlaneIndex = getCanvas().getScene().getFreeSlotForOtherDrawables(); } getCanvas().getScene().setOtherDrawable(priCuttingPlaneIndex, drPlane); if (getSecondaryDrawableFace() != null) { if (secCuttingPlaneIndex == -1) { - secCuttingPlaneIndex = getCanvas().getScene().getFreeIndexForOtherDrawables(); + secCuttingPlaneIndex = getCanvas().getScene().getFreeSlotForOtherDrawables(); } getCanvas().getScene().setOtherDrawable(secCuttingPlaneIndex, new DrawableCuttingPlane(drPlane)); } @@ -333,7 +333,7 @@ public class ProfilesAction extends ControlPanelAction implements HumanFaceListe DrawableCuttingPlane cuttingPlane = getCuttingPlaneFromSymmetry(getCanvas().getPrimaryFaceIndex()); cuttingPlane.setTransparency(0.5f); if (priCuttingPlaneIndex == -1) { - priCuttingPlaneIndex = getCanvas().getScene().getFreeIndexForOtherDrawables(); + priCuttingPlaneIndex = getCanvas().getScene().getFreeSlotForOtherDrawables(); } getCanvas().getScene().setOtherDrawable(priCuttingPlaneIndex, cuttingPlane); recomputePrimaryProfile(); @@ -342,7 +342,7 @@ public class ProfilesAction extends ControlPanelAction implements HumanFaceListe cuttingPlane = getCuttingPlaneFromSymmetry(getCanvas().getSecondaryFaceIndex()); cuttingPlane.setTransparency(0.5f); if (secCuttingPlaneIndex == -1) { - secCuttingPlaneIndex = getCanvas().getScene().getFreeIndexForOtherDrawables(); + secCuttingPlaneIndex = getCanvas().getScene().getFreeSlotForOtherDrawables(); } getCanvas().getScene().setOtherDrawable(secCuttingPlaneIndex, cuttingPlane); recomputeSecondaryProfile(); diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java index 45315518..a044a14b 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java @@ -58,11 +58,11 @@ public class SymmetryAction extends ControlPanelAction implements HumanFaceListe // If the symmetry panel is focused... if (((JTabbedPane) e.getSource()).getSelectedComponent() instanceof SymmetryPanel) { getCanvas().getScene().setDefaultColors(); - getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getPrimaryFaceIndex(), true); - getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getSecondaryFaceIndex(), true); + getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getPrimaryFaceSlot(), true); + getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getSecondaryFaceSlot(), true); } else { - getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getPrimaryFaceIndex(), false); - getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getSecondaryFaceIndex(), false); + getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getPrimaryFaceSlot(), false); + getCanvas().getScene().showSymmetryPlane(getCanvas().getScene().getSecondaryFaceSlot(), false); } }); @@ -80,13 +80,13 @@ public class SymmetryAction extends ControlPanelAction implements HumanFaceListe switch (action) { case SymmetryPanel.ACTION_COMMAND_RECOMPUTE_FROM_MESH: sPlane = 1; - recomputeFromMesh(getCanvas().getScene().getPrimaryFaceIndex()); - recomputeFromMesh(getCanvas().getScene().getSecondaryFaceIndex()); + recomputeFromMesh(getCanvas().getScene().getPrimaryFaceSlot()); + recomputeFromMesh(getCanvas().getScene().getSecondaryFaceSlot()); break; case SymmetryPanel.ACTION_COMMAND_COMPUTE_FROM_FPS: sPlane = 2; - recomputeFromFeaturePoints(getCanvas().getScene().getPrimaryFaceIndex()); - recomputeFromFeaturePoints(getCanvas().getScene().getSecondaryFaceIndex()); + recomputeFromFeaturePoints(getCanvas().getScene().getPrimaryFaceSlot()); + recomputeFromFeaturePoints(getCanvas().getScene().getSecondaryFaceSlot()); break; default: // do nothing @@ -102,13 +102,13 @@ public class SymmetryAction extends ControlPanelAction implements HumanFaceListe return; case 1: // from mesh recomputeFromMesh(event.getFace().equals(getPrimaryDrawableFace().getHumanFace()) - ? getCanvas().getScene().getPrimaryFaceIndex() - : getCanvas().getScene().getSecondaryFaceIndex()); + ? getCanvas().getScene().getPrimaryFaceSlot() + : getCanvas().getScene().getSecondaryFaceSlot()); break; case 2: // from FPs recomputeFromFeaturePoints(event.getFace().equals(getPrimaryDrawableFace().getHumanFace()) - ? getCanvas().getScene().getPrimaryFaceIndex() - : getCanvas().getScene().getSecondaryFaceIndex()); + ? getCanvas().getScene().getPrimaryFaceSlot() + : getCanvas().getScene().getSecondaryFaceSlot()); break; default: } -- GitLab