Sample

Schnappinger/aoi/artofillusion.texture.FaceVertexParameterValue

Human rating uses the original dataset scale.

Human3.31
Lines235

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
23.7Δ 13.9
Scalabrino0.7810–1; higher is more readable
58.6Δ 20.9
Dorn0.0880–1; higher is more readable
32.0Δ 5.6
Mi0.5820–1; higher is more readable
55.8Δ 18.2
LLOC123Logical lines; fewer is more readable
20.6Δ 17.0
DeepSeek V4 Pro140–20; mean of three runs
29.9Δ 7.8
GPT-6.1 Sol160–20; mean of three runs
38.9Δ 1.3
BTTF0.2660–1; higher is more readable
18.2Δ 19.5
Human3.311–4; original rating
37.6

Views

Source code

/* Copyright (C) 2003-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.texture; import artofillusion.*; import artofillusion.object.*; import java.io.*; /** This class defines a scalar parameter whose value is defined at each vertex of each face of a mesh. */ public class FaceVertexParameterValue implements ParameterValue { private double values[]; private int faceStartIndex[]; /** This constructor is private. It is used internally by duplicate(). */ private FaceVertexParameterValue() { } /** * Create a new FaceVertexParameterValue object. val is an array containing the parameter * value at every vertex of every face. Specifically, val[i][j] is the value at the j'th * vertex of the i'th face. */ public FaceVertexParameterValue(double val[][]) { setValue(val); } /** Create a new FaceVertexParameterValue for a mesh, and initialize it to appropriate default values. */ public FaceVertexParameterValue(FacetedMesh mesh, TextureParameter param) { faceStartIndex = new int[mesh.getFaceCount()+1]; int totalValues = 0; for (int i = 0; i < mesh.getFaceCount(); i++) { totalValues += mesh.getFaceVertexCount(i); faceStartIndex[i+1] = totalValues; } MeshVertex vertex[] = mesh.getVertices(); values = new double[totalValues]; int index = 0; if (param.type == TextureParameter.NORMAL_PARAMETER) for (int face = 0; face < mesh.getFaceCount(); face++) for (int vert = 0; vert < mesh.getFaceVertexCount(face); vert++) values[index++] = param.defaultVal; if (param.type == TextureParameter.X_COORDINATE) for (int face = 0; face < mesh.getFaceCount(); face++) for (int vert = 0; vert < mesh.getFaceVertexCount(face); vert++) values[index++] = vertex[mesh.getFaceVertexIndex(face, vert)].r.x; if (param.type == TextureParameter.Y_COORDINATE) for (int face = 0; face < mesh.getFaceCount(); face++) for (int vert = 0; vert < mesh.getFaceVertexCount(face); vert++) values[index++] = vertex[mesh.getFaceVertexIndex(face, vert)].r.y; if (param.type == TextureParameter.Z_COORDINATE) for (int face = 0; face < mesh.getFaceCount(); face++) for (int vert = 0; vert < mesh.getFaceVertexCount(face); vert++) values[index++] = vertex[mesh.getFaceVertexIndex(face, vert)].r.z; } /** * Set the list of parameter values. val is an array containing the parameter * value at every vertex of every face. Specifically, val[i][j] is the value at the j'th * vertex of the i'th face. */ public void setValue(double val[][]) { faceStartIndex = new int[val.length+1]; int totalValues = 0; for (int i = 0; i < val.length; i++) { totalValues += val[i].length; faceStartIndex[i+1] = totalValues; } values = new double[totalValues]; int index = 0; for (int i = 0; i < val.length; i++) for (int j = 0; j < val[i].length; j++) values[index++] = val[i][j]; } /** * Get the value of the parameter at a particular vertex in a particular face. * * @param faceIndex the index of the face within the mesh * @param vertIndex the index of the vertex within the face * @return the value at the specified face/vertex */ public double getValue(int faceIndex, int vertIndex) { return values[faceStartIndex[faceIndex]+vertIndex]; } /** * Set the value of the parameter at a particular vertex in a particular face. * * @param faceIndex the index of the face within the mesh * @param vertIndex the index of the vertex within the face * @param newValue the value to set for the specified face/vertex */ public void setValue(int faceIndex, int vertIndex, double newValue) { values[faceStartIndex[faceIndex]+vertIndex] = newValue; } /** * Get the value of the parameter at a particular point within the interior of a face. * This method assumes the face is triangular (which is always the case for a parameter * of a RenderingMesh). */ public double getValue(int faceIndex, int v1, int v2, int v3, double u, double v, double w) { return u*getValue(faceIndex, 0)+v*getValue(faceIndex, 1)+w*getValue(faceIndex, 2); } /** * Get the number of faces for which the parameter has values. */ public int getFaceCount() { return faceStartIndex.length-1; } /** * Get the number of vertices in a particular face. * * @param faceIndex the index of the face within the mesh */ public int getFaceVertexCount(int faceIndex) { return faceStartIndex[faceIndex+1]-faceStartIndex[faceIndex]; } /** Get the average value of the parameter over the entire surface. */ public double getAverageValue() { double avg = 0.0; for (int i = 0; i < values.length; i++) avg += values[i]; return (avg/values.length); } /** Create a duplicate of this object. */ public ParameterValue duplicate() { FaceVertexParameterValue copy = new FaceVertexParameterValue(); copy.values = (double[]) values.clone(); copy.faceStartIndex = (int[]) faceStartIndex.clone(); return copy; } /** Determine whether this object represents the same set of values as another one. */ public boolean equals(Object o) { if (!(o instanceof FaceVertexParameterValue)) return false; FaceVertexParameterValue v = (FaceVertexParameterValue) o; if (v.values.length != values.length || v.faceStartIndex.length != faceStartIndex.length) return false; for (int i = 0; i < values.length; i++) if (v.values[i] != values[i]) return false; for (int i = 0; i < faceStartIndex.length; i++) if (v.faceStartIndex[i] != faceStartIndex[i]) return false; return true; } /** Write out a serialized representation of this object to a stream. */ public void writeToStream(DataOutputStream out) throws IOException { out.writeInt(-1); out.writeInt(values.length); for (int i = 0; i < values.length; i++) out.writeDouble(values[i]); out.writeInt(faceStartIndex.length); for (int i = 1; i < faceStartIndex.length; i++) out.writeInt(faceStartIndex[i]); } /** Reconstruct a serialized object. */ public FaceVertexParameterValue(DataInputStream in) throws IOException { int version = in.readInt(); if (version >= 0) { // Old format from before a version number was being stored. int faces = version; values = new double[faces*3]; faceStartIndex = new int[values.length+1]; for (int i = 0; i < 3; i++) for (int j = 0; j < faces; j++) values[j*3+i] = in.readDouble(); for (int i = 1; i <= faces; i++) faceStartIndex[i] = i*3; } else if (version != -1) throw new InvalidObjectException(""); else { values = new double[in.readInt()]; for (int i = 0; i < values.length; i++) values[i] = in.readDouble(); faceStartIndex = new int[in.readInt()]; for (int i = 1; i < faceStartIndex.length; i++) faceStartIndex[i] = in.readInt(); } } }

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.8334.881−275.051
Source linesThe number of non-empty source lines.235+94
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.741−7.111

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

Score0.781

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.236−7.32
Indentation frequencyHow rapidly indentation changes from line to line.195+6.008
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.196−4.077
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.234.861+2.873
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.106.936+0.921
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.106.983−0.866
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.092+0.051

Intercept 0.07 + feature contributions = -2.34 (log-odds).
Score = sigmoid(-2.34) = 0.088.

Score0.582
Score123
Run 1

The code is generally readable with clear class purpose and method-level Javadoc. Structure is logical, and fields are named clearly. However, there are several readability issues: the constructor for FaceVertexParameterValue(FacetedMesh mesh, TextureParameter param) uses four nearly identical nested loops with repeated if-checks and index increments, making it verbose and error-prone. Nesting is moderate (two levels in loops), but action granularity is sometimes poor—multiple operations on one line (e.g., values[index++] = ...) reduce clarity. Some methods like equals() and writeToStream() are straightforward, but the duplicated loop patterns could be extracted for better intent. Reading flow is mostly natural, though repeated face/vertex loops feel monotonous. The class length is acceptable, but the constructor and setValue method are unnecessarily long. Overall, it's understandable but could be improved with helper methods and reduced repetition.

Run 2

The code is generally well-structured with clear class responsibilities, consistent naming, and good Javadoc documentation. It avoids deep nesting, keeps methods short, and maintains logical organization. However, readability suffers from repeated nested loops in the constructor — four nearly identical blocks for different parameter types — which could be extracted into a helper method. Array indexing via `faceStartIndex` and `values` is not immediately obvious and requires the reader to understand the internal storage layout. The `equals` method has a tedious pair of loops that could be simplified with `Arrays.equals`. Overall the intent is clear and the code is maintainable, but some duplication and storage-level details reduce clarity.

Run 3

The code is generally well-structured with clear class and method organization, and documentation is helpful. However, readability is hampered by repeated nested loops in the constructor, which could be consolidated. The repeated if-blocks for different parameter types create lengthy, repetitive code, and the constructor has multiple actions per line (e.g., `values[index++] = ...`). Deep nesting in the serialization constructor (if/else) and in the loops reduces flow. Variable names like `v`, `u`, `w` in getValue are vague without context. Overall, the intent is clear but the code is unnecessarily verbose and could be refactored for better flow and nesting.

Run 1

Code Structure: Clearly organized into constructors, accessors, copying, equality, and serialization, with focused methods. Nesting: Mostly shallow, although initialization and legacy deserialization use nested loops; omitted braces make their boundaries less explicit. Clarity of intent: Descriptive method names and useful documentation explain the face/vertex model, but the flattened storage invariant and serialization marker deserve explanation. Unused interpolation arguments and an empty exception message introduce ambiguity. Code length: Most methods are concise, but four nearly identical initialization branches add avoidable repetition. Action granularity: Generally one operation per line, with occasional combined indexing and incrementing. Reading flow: Consistent formatting and straightforward control flow make the class easy to follow; dense arithmetic spacing, abbreviated local names, and legacy-format handling slightly interrupt readability.

Run 2

Code Structure: The class is logically organized into constructors, accessors, copying, comparison, and serialization, with focused methods. Nesting: Most methods are shallow, though initialization and legacy deserialization use nested loops; omitted braces make their boundaries less explicit. Clarity of intent: Descriptive method names and useful documentation explain the face/vertex model. However, unused interpolation arguments, unexplained serialization marker -1, and an empty exception message introduce ambiguity. Code length: Generally concise, but four nearly identical initialization branches add avoidable repetition. Action granularity: Most statements perform one action, although index increments embedded in assignments slightly increase cognitive load. Reading flow: Consistent formatting and straightforward loops support natural reading, while dense arithmetic, abbreviated local names, and repeated branching occasionally interrupt it.

Run 3

Code Structure: Cohesive class with clearly separated initialization, access, copying, comparison, and serialization methods. Nesting: Mostly shallow, although unbraced conditionals containing nested loops require careful reading. Clarity of intent: Descriptive method names and useful documentation explain the face/vertex mapping; unused interpolation arguments, an unexplained serialization sentinel, and an empty exception message introduce ambiguity. Code length: Most methods are concise, but four nearly identical initialization branches add unnecessary repetition. Action granularity: Generally one action per line, with occasional embedded index increments combining assignment and state changes. Reading flow: Consistent formatting and straightforward method bodies support natural reading; dense arithmetic expressions, abbreviated local names, and legacy-format indexing make some sections harder to follow.