Sample

Schnappinger/aoi/artofillusion.script.ScriptedObjectController

Human rating uses the original dataset scale.

Human3.95
Lines120

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
39.1Δ 24.6
Scalabrino0.7880–1; higher is more readable
59.6Δ 4.1
Dorn0.320–1; higher is more readable
50.2Δ 13.5
Mi0.2910–1; higher is more readable
19.5Δ 44.2
LLOC50Logical lines; fewer is more readable
39.4Δ 24.3
DeepSeek V4 Pro170–20; mean of three runs
66.8Δ 3.1
GPT-6.1 Sol160–20; mean of three runs
38.9Δ 24.8
BTTF0.4140–1; higher is more readable
36.3Δ 27.4
Human3.951–4; original rating
63.7

Views

Source code

/* Copyright (C) 2002-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.script; import artofillusion.*; import artofillusion.animation.*; import artofillusion.math.*; import artofillusion.object.*; /** This class mediates interactions between an ObjectScript and the rest of the program. */ public class ScriptedObjectController { private ObjectInfo info; private ScriptedObject object; private ScriptedObjectEnumeration enumeration; private Scene scene; private boolean preview; /** Create a new ScriptedObjectController and execute its script. */ ScriptedObjectController(ObjectInfo obj, ScriptedObjectEnumeration objectEnum, boolean interactive, Scene sc) { info = obj; Object3D innerObject = obj.getObject(); while (innerObject instanceof ObjectWrapper) innerObject = ((ObjectWrapper) innerObject).getWrappedObject(); object = (ScriptedObject) innerObject; enumeration = objectEnum; preview = interactive; scene = sc; object.setUsesTime(false); object.setUsesCoords(false); new Thread() { public void run() { try { ObjectScript script = object.getObjectScript(); script.execute(ScriptedObjectController.this); enumeration.executionComplete(); } catch (Exception ex) { enumeration.executionComplete(); ScriptRunner.displayError(object.getLanguage(), ex); } } }.start(); } /** Get the coordinate system which defines the scripted object's position in the scene. */ public final CoordinateSystem getCoordinates() { object.setUsesCoords(true); return info.getCoords(); } /** Get the current time. */ public final double getTime() { object.setUsesTime(true); return scene.getTime(); } /** Get the scene this object is part of. */ public final Scene getScene() { object.setUsesTime(true); return scene; } /** Determine whether the script is currently being executed to create an interactive preview. */ public final boolean isPreview() { return preview; } /** Get the value of a parameter. */ public final double getParameter(String name) throws IllegalArgumentException { for (int i = object.getNumParameters()-1; i >= 0; i--) if (object.getParameterName(i).equals(name)) return object.getParameterValue(i); throw new IllegalArgumentException("Unknown parameter '"+name+"'"); } /** Add an object to the scripted object. */ public final void addObject(ObjectInfo info) { info.tracks = new Track [0]; if (info.getObject().canSetTexture() && info.getObject().getTextureMapping() == null) info.setTexture(object.getTexture(), object.getTextureMapping()); if (info.getObject().canSetMaterial() && info.getObject().getMaterialMapping() == null) info.setMaterial(object.getMaterial(), object.getMaterialMapping()); enumeration.addObject(info); } /** Add an object to the scripted object. */ public final void addObject(Object3D obj, CoordinateSystem coords) { addObject(new ObjectInfo(obj, coords, "")); } }

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.3261.834−107.641
Source linesThe number of non-empty source lines.120+48
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.757−7.136

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

Score0.788

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.120−3.212
Indentation frequencyHow rapidly indentation changes from line to line.111+3.102
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.111−2.126
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.118.83+1.251
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.110.983−1.036
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.110.983+0.986
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.075+0.213

Intercept 0.07 + feature contributions = -0.752 (log-odds).
Score = sigmoid(-0.752) = 0.32.

Score0.291
Score50
Run 1

The code is well-structured with clear class organization and logical method grouping. Nesting is minimal, with only one inner class and a single loop that could potentially be inverted for early exit but remains readable. Intent is clearly documented through Javadoc comments for each method, and naming conventions are strong. Code length is appropriate—no unnecessary verbosity. Each action generally occupies its own line, with the exception of the loop in getParameter, which remains clear. Reading flow is natural, starting with the constructor, followed by getters, and then action methods. The only slight concern is the anonymous Thread subclass in the constructor adds minor complexity. Overall, this code is highly readable with excellent documentation and clean structure.

Run 2

The code is well-structured with clear class organization and logical method grouping. It uses minimal nesting, with only one level in the thread's run() method and in the getParameter loop. Each method has a concise Javadoc comment, making intent obvious. The code is appropriately concise without being overly compressed. Action granularity is good—most methods perform a single, well-defined action, and the single-line if statements are simple and readable. The reading flow is natural, with methods ordered logically (constructor, getters, parameter access, object addition). Minor deductions: the inner while loop in the constructor could be extracted for clarity, and the repeated exception handling in the thread could be slightly simplified, but these are minor. Overall, highly readable code that follows good Java conventions and clean-code principles.

Run 3

The code is well-structured with clear class purpose and logical method organization. Javadoc comments explain each method's intent. Nesting is minimal—only a few if statements and a while loop, neither deeply nested. Methods are concise and perform single, focused actions (e.g., getTime only sets a flag and returns scene time). Reading flow is natural: constructor, then accessors, then parameter lookup, then addObject overloads. However, some minor issues reduce clarity: the constructor mixes object unwrapping with thread execution logic, and there's slight redundancy in the two addObject methods' comments being identical. The anonymous Thread class adds mild abstraction, but its intent is clear from context. Variable and method names are descriptive. Overall, the code is readable, maintainable, and follows good object-oriented practices, losing points only for slight structural mixing and duplicated comments.

Run 1

Code Structure: The class is logically organized into initialization and small public methods, although the constructor combines setup with asynchronous script execution. Nesting: Most methods are flat; the anonymous thread and try/catch introduce moderate nesting, while unbraced loops and conditionals slightly hinder scanning. Clarity of intent: Descriptive method names and documentation explain the controller's purpose, but abbreviated variable names and implicit side effects, such as getScene() marking time usage, reduce clarity. Code length: The implementation is concise, though executionComplete() is duplicated across success and failure paths. Action granularity: Statements generally perform one action per line, making operations easy to follow. Reading flow: Methods follow a natural progression, but inconsistent indentation in exception handling, compact operator spacing, and inline thread creation interrupt otherwise straightforward reading.

Run 2

Code Structure: The class is logically organized into initialization, accessors, parameter lookup, and object addition, although the constructor mixes setup with asynchronous execution. Nesting: Most methods are flat; the anonymous thread and try/catch introduce moderate nesting. Clarity of intent: Descriptive method names and concise documentation explain the controller's purpose, but abbreviated constructor arguments and unexpected getter side effects reduce clarity. Code length: The implementation is compact, though duplicated executionComplete() calls and repeated object access add minor redundancy. Action granularity: Statements generally perform one action per line, making operations easy to follow. Reading flow: Methods follow a natural progression, but inconsistent indentation, omitted braces around control statements, and embedded thread creation interrupt an otherwise straightforward flow.

Run 3

Code Structure: The class is logically organized around script execution and small public access methods, though the constructor mixes initialization, object unwrapping, and asynchronous execution. Nesting: Most methods are flat; the anonymous thread and try/catch introduce moderate nesting. Clarity of intent: Method names and documentation communicate purpose well, but abbreviated identifiers and implicit side effects, such as getScene() marking time usage, require interpretation. Code length: Generally concise, although executionComplete() is duplicated and texture/material checks repeat accessor calls. Action granularity: Statements generally perform one action per line, with only conventional loop syntax combining operations. Reading flow: Methods follow a natural progression from setup to queries and object addition, but inconsistent brace indentation, omitted braces on control statements, and inline thread creation slightly interrupt readability.