Sample

Schnappinger/aoi/artofillusion.CurveViewer

Human rating uses the original dataset scale.

Human2.2
Lines250

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
17.1Δ 6.5
Scalabrino0.2540–1; higher is more readable
1.4Δ 9.2
Dorn0.0050–1; higher is more readable
15.5Δ 5.0
Mi0.0490–1; higher is more readable
6.3Δ 4.3
LLOC139Logical lines; fewer is more readable
18.8Δ 8.3
DeepSeek V4 Pro130–20; mean of three runs
21.1Δ 10.6
GPT-6.1 Sol130–20; mean of three runs
9.4Δ 1.2
BTTF0.0450–1; higher is more readable
1.7Δ 8.9
Human2.21–4; original rating
10.6

Views

Source code

/* Copyright (C) 1999-2006 by Peter Eastman This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ package artofillusion; import artofillusion.math.*; import artofillusion.object.*; import artofillusion.ui.*; import buoy.event.*; import buoy.widget.*; import java.awt.*; /** The CurveViewer class is a component which displays a Curve object and allows the user to edit it. */ public class CurveViewer extends MeshViewer { boolean draggingSelectionBox, dragging; int deselect; public CurveViewer(MeshEditController window, RowContainer p) { super(window, p); } protected void drawObject() { if (!showMesh) return; MeshVertex v[] = ((Mesh) getController().getObject().getObject()).getVertices(); boolean selected[] = controller.getSelection(); WireframeMesh wireframe = getController().getObject().getObject().getWireframeMesh(); for (int i = 0; i < wireframe.from.length; i++) renderLine(wireframe.vert[wireframe.from[i]], wireframe.vert[wireframe.to[i]], theCamera, lineColor); for (int i = 0; i < v.length; i++) if (!selected[i] && theCamera.getObjectToView().timesZ(v[i].r) > theCamera.getClipDistance()) { Vec2 p = theCamera.getObjectToScreen().timesXY(v[i].r); double z = theCamera.getObjectToView().timesZ(v[i].r); renderBox(((int) p.x) - HANDLE_SIZE/2, ((int) p.y) - HANDLE_SIZE/2, HANDLE_SIZE, HANDLE_SIZE, z, lineColor); } Color col = (currentTool.hilightSelection() ? highlightColor : lineColor); for (int i = 0; i < v.length; i++) if (selected[i] && theCamera.getObjectToView().timesZ(v[i].r) > theCamera.getClipDistance()) { Vec2 p = theCamera.getObjectToScreen().timesXY(v[i].r); double z = theCamera.getObjectToView().timesZ(v[i].r); renderBox(((int) p.x) - HANDLE_SIZE/2, ((int) p.y) - HANDLE_SIZE/2, HANDLE_SIZE, HANDLE_SIZE, z, col); } } /** When the user presses the mouse, forward events to the current tool as appropriate. If this is a vertex based tool, allow them to select or deselect vertices. */ protected void mousePressed(WidgetMouseEvent e) { int i, j, x, y; double z, nearest; MeshVertex v[] = ((Curve) getController().getObject().getObject()).getVertices(); Vec2 pos; Point p; requestFocus(); sentClick = false; deselect = -1; dragging = false; clickPoint = e.getPoint(); // Determine which tool is active. if (metaTool != null && e.isMetaDown()) activeTool = metaTool; else if (altTool != null && e.isAltDown()) activeTool = altTool; else activeTool = currentTool; // If the current tool wants all clicks, just forward the event and return. if ((activeTool.whichClicks() & EditingTool.ALL_CLICKS) != 0) { activeTool.mousePressed(e, this); dragging = true; sentClick = true; } boolean allowSelectionChange = activeTool.allowSelectionChanges(); boolean wantHandleClicks = ((activeTool.whichClicks() & EditingTool.HANDLE_CLICKS) != 0); if (!allowSelectionChange && !wantHandleClicks) return; // See whether the click was on a currently selected vertex. p = e.getPoint(); boolean selected[] = controller.getSelection(); for (i = 0; i < v.length; i++) if (selected[i]) { pos = theCamera.getObjectToScreen().timesXY(v[i].r); x = (int) pos.x; y = (int) pos.y; if (x >= p.x-HANDLE_SIZE/2 && x <= p.x+HANDLE_SIZE/2 && y >= p.y-HANDLE_SIZE/2 && y <= p.y+HANDLE_SIZE/2) break; } if (i < v.length) { // The click was on a selected vertex. If it was a shift-click, the user may want // to deselect it, so set a flag. Forward the event to the current tool. if (e.isShiftDown() && allowSelectionChange) deselect = i; if (wantHandleClicks) { activeTool.mousePressedOnHandle(e, this, 0, i); sentClick = true; } return; } // The click was not on a selected vertex. See whether it was on an unselected one. // If so, select it and send an event to the current tool. j = -1; nearest = Double.MAX_VALUE; for (i = 0; i < v.length; i++) { pos = theCamera.getObjectToScreen().timesXY(v[i].r); x = (int) pos.x; y = (int) pos.y; if (x >= p.x-HANDLE_SIZE/2 && x <= p.x+HANDLE_SIZE/2 && y >= p.y-HANDLE_SIZE/2 && y <= p.y+HANDLE_SIZE/2) { z = theCamera.getObjectToView().timesZ(v[i].r); if (z > 0.0 && z < nearest) { nearest = z; j = i; } } } if (j > -1) { if (allowSelectionChange) { boolean oldSelection[] = (boolean []) selected.clone(); if (!e.isShiftDown()) for (i = 0; i < selected.length; i++) selected[i] = false; selected[j] = true; ((CurveEditorWindow) controller).findSelectionDistance(); currentTool.getWindow().setUndoRecord(new UndoRecord(currentTool.getWindow(), false, UndoRecord.SET_MESH_SELECTION, new Object [] {controller, new Integer(controller.getSelectionMode()), oldSelection})); controller.setSelection(selected); activeTool.getWindow().updateMenus(); } if (e.isShiftDown()) repaint(); else if (wantHandleClicks) { activeTool.mousePressedOnHandle(e, this, 0, j); sentClick = true; } return; } // The click was not on a handle. Start dragging a selection box. if (allowSelectionChange) { draggingSelectionBox = true; beginDraggingSelection(p, false); } } protected void mouseDragged(WidgetMouseEvent e) { if (!dragging) { Point p = e.getPoint(); if (Math.abs(p.x-clickPoint.x) < 2 && Math.abs(p.y-clickPoint.y) < 2) return; } dragging = true; deselect = -1; super.mouseDragged(e); } protected void mouseReleased(WidgetMouseEvent e) { int i, x, y; MeshVertex v[] = ((Curve) getController().getObject().getObject()).getVertices(); Vec2 pos; moveToGrid(e); endDraggingSelection(); boolean selected[] = controller.getSelection(); boolean oldSelection[] = (boolean []) selected.clone(); if (draggingSelectionBox && !e.isShiftDown() && !e.isControlDown()) for (i = 0; i < selected.length; i++) selected[i] = false; // If the user was dragging a selection box, then select or deselect anything // it intersects. if (selectBounds != null) { boolean newsel = !e.isControlDown(); for (i = 0; i < v.length; i++) { pos = theCamera.getObjectToScreen().timesXY(v[i].r); x = (int) pos.x; y = (int) pos.y; if (selectionRegionContains(new Point(x, y))) selected[i] = newsel; } } draggingBox = draggingSelectionBox = false; // Send the event to the current tool, if appropriate. if (sentClick) { if (!dragging) { Point p = e.getPoint(); e.translatePoint(clickPoint.x-p.x, clickPoint.y-p.y); } activeTool.mouseReleased(e, this); } // If the user shift-clicked a selected point and released the mouse without dragging, // then deselect the point. if (deselect > -1) selected[deselect] = false; ((CurveEditorWindow) controller).findSelectionDistance(); for (int k = 0; k < selected.length; k++) if (selected[k] != oldSelection[k]) { currentTool.getWindow().setUndoRecord(new UndoRecord(currentTool.getWindow(), false, UndoRecord.SET_MESH_SELECTION, new Object [] {controller, new Integer(controller.getSelectionMode()), oldSelection})); break; } controller.setSelection(selected); activeTool.getWindow().updateMenus(); } }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.11956.381−394.561
Source linesThe number of non-empty source lines.250+100
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.774−7.161

Intercept 8.87 + feature contributions = -292.852 (log-odds).
Score = sigmoid(-292.852) = 0.

Score0.254

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.251−7.851
Indentation frequencyHow rapidly indentation changes from line to line.227+7.115
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.212.988−5.356
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.227−4.788
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.249.818+3.082
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.212.984+2.632
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.12−0.219

Intercept 0.07 + feature contributions = -5.316 (log-odds).
Score = sigmoid(-5.316) = 0.005.

Score0.049
Score139
Run 1

The code has a clear overall structure with logical method separation (drawObject, mousePressed, mouseDragged, mouseReleased) and helpful comments explaining intent. However, readability suffers from several issues: deep nesting in mousePressed (up to 4 levels) and mouseReleased, long methods that handle multiple responsibilities, and repetitive calculations (camera transforms computed multiple times). Several lines contain multiple actions (e.g., checking bounds and breaking in the same statement). The mousePressed method specifically mixes tool detection, selection logic, and event forwarding, making the flow difficult to follow. Action granularity is inconsistent—some lines perform a single operation while others chain multiple comparisons. While variable names are generally descriptive (draggingSelectionBox, allowSelectionChange), the overall flow through selection states requires careful tracking. The comments help navigation but don't fully compensate for the complex branching logic.

Run 2

The code has clear comments and somewhat logical method separation, but suffers from long, dense methods with deep nesting and multiple responsibilities. For example, mousePressed() and mouseReleased() are very long, combining selection logic, event routing, and UI updates. Nested loops and conditionals (up to 3-4 levels) make flow hard to follow. Many lines perform multiple operations, such as math + type casting + method calls, reducing action granularity. Variable names like 'p', 'v', 'i', 'j' are common, harming clarity. Repeated code blocks (camera projection, hit testing) should be extracted. The reading flow is interrupted by large commented blocks and mixed concerns. Overall, the code works but is not highly readable; it would benefit from refactoring into smaller helper methods with clearer names and less nesting.

Run 3

The code is reasonably structured with clear class hierarchy and method separation, but it falls short of high readability. The main methods (mousePressed, mouseReleased) are quite long and contain multiple distinct operations, making them hard to follow. Nesting is moderate but includes several deep conditional blocks. The intent is mostly clear due to comments explaining major sections, but some complex expressions like `theCamera.getObjectToView().timesZ(v[i].r)` are repeated heavily, obscuring clarity. Action granularity is inconsistent—some lines contain multiple operations (e.g., `renderBox` calls with complex arguments), while others are unnecessarily verbose. The reading flow is acceptable but interrupted by frequent variable reuse and long method bodies. Magic numbers like `HANDLE_SIZE` and hardcoded constants reduce clarity. The code would benefit from extracting helper methods, reducing duplication, and simplifying conditionals.

Run 1

Code Structure: Methods are logically organized around rendering and mouse events, but mousePressed combines tool routing, hit testing, selection updates, and undo management. Nesting: Several nested loops and conditionals, especially in mousePressed, increase cognitive load; early returns help. Clarity of intent: Method names and explanatory comments communicate the overall purpose, but short variables, implicit state dependencies, and a comment promising a return that does not occur reduce clarity. Code length: Repeated vertex projection, hit testing, rendering, and undo construction could be extracted into helpers. Action granularity: Most statements perform one action per line, though chained assignments and long constructor expressions are harder to scan. Reading flow: Event handling follows a natural progression, but inconsistent brace indentation, omitted braces, and lengthy expressions interrupt readability.

Run 2

Code Structure: Rendering and mouse events are separated into logical methods, but mousePressed combines tool dispatch, hit testing, selection updates, and undo management. Nesting: Several nested loops and conditionals make selection handling harder to follow; early returns help. Clarity of intent: Method names and explanatory comments communicate the overall purpose, but terse variables, shared state flags, and a comment promising a return that does not occur reduce clarity. Code length: Repeated rendering, hit-testing, and undo-record construction could be extracted into helpers. Action granularity: Most lines perform one action, though chained assignments and long constructor expressions are dense. Reading flow: Event handling follows a sensible chronological sequence, but inconsistent brace placement, omitted braces, long lines, and declarations separated from use interrupt the flow.

Run 3

Code Structure: Rendering and mouse-event handling are logically separated, but mousePressed combines tool dispatch, hit testing, selection updates, and undo management. Nesting: Several loops and conditionals reach moderate depth; early returns help limit complexity. Clarity of intent: Method names and explanatory comments make the overall purpose clear, but terse variables, shared flags, and inherited state require careful tracking. One comment promises a return that the following block does not perform. Code length: Repeated vertex projection, hit-testing conditions, rendering logic, and undo construction add avoidable length. Action granularity: Most statements perform one action per line, though chained assignments and lengthy constructor calls are harder to parse. Reading flow: The press-drag-release lifecycle is natural, but inconsistent brace placement, omitted braces, long lines, and declarations separated from their use interrupt scanning.