<commit_before>import { Nullable } from "../types";
import { VertexBuffer } from "../Meshes/buffer";
import { AbstractMesh } from "../Meshes/abstractMesh";
import { Mesh } from "../Meshes/mesh";
import { LinesMesh, InstancedLinesMesh } from "../Meshes/linesMesh";
import { Vector3, TmpVectors } from "../Maths/math.vector";
import { IDisposable, Scene } from "../scene";
import { Observer } from "../Misc/observable";
import { Effect } from "../Materials/effect";
import { Material } from "../Materials/material";
import { ShaderMaterial } from "../Materials/shaderMaterial";
import { Camera } from "../Cameras/camera";
import { Constants } from "../Engines/constants";
import { Node } from "../node";

import "../Shaders/line.fragment";
import "../Shaders/line.vertex";
import { DataBuffer } from '../Meshes/dataBuffer';

declare module "../Meshes/abstractMesh" {
    export interface AbstractMesh {
        /**
         * Gets the edgesRenderer associated with the mesh
         */
        edgesRenderer: Nullable<EdgesRenderer>;
    }
}
AbstractMesh.prototype.disableEdgesRendering = function(): AbstractMesh {
    if (this._edgesRenderer) {
        this._edgesRenderer.dispose();
        this._edgesRenderer = null;
    }
    return this;
};

AbstractMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): AbstractMesh {
    this.disableEdgesRendering();
    this._edgesRenderer = new EdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);
    return this;
};

Object.defineProperty(AbstractMesh.prototype, "edgesRenderer", {
    get: function(this: AbstractMesh) {
        return this._edgesRenderer;
    },
    enumerable: true,
    configurable: true
});

declare module "../Meshes/linesMesh" {
    export interface LinesMesh {
        /**
         * Enables the edge rendering mode on the mesh.
         * This mode makes the mesh edges visible
         * @param epsilon defines the maximal distance between two angles to detect a face
         * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces
         * @returns the currentAbstractMesh
         * @see https://www.babylonjs-playground.com/#19O9TU#0
         */
        enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): AbstractMesh;
    }
}
LinesMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): AbstractMesh {
    this.disableEdgesRendering();
    this._edgesRenderer = new LineEdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);
    return this;
};

declare module "../Meshes/linesMesh" {
    export interface InstancedLinesMesh {
        /**
         * Enables the edge rendering mode on the mesh.
         * This mode makes the mesh edges visible
         * @param epsilon defines the maximal distance between two angles to detect a face
         * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces
         * @returns the current InstancedLinesMesh
         * @see https://www.babylonjs-playground.com/#19O9TU#0
         */
        enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): InstancedLinesMesh;
    }
}

InstancedLinesMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): InstancedLinesMesh {
    LinesMesh.prototype.enableEdgesRendering.apply(this, arguments);
    return this;
};

/**
 * FaceAdjacencies Helper class to generate edges
 */
class FaceAdjacencies {
    public edges = new Array<number>();
    public p0: Vector3;
    public p1: Vector3;
    public p2: Vector3;
    public edgesConnectedCount = 0;
}

/**
 * Defines the minimum contract an Edges renderer should follow.
 */
export interface IEdgesRenderer extends IDisposable {
    /**
     * Gets or sets a boolean indicating if the edgesRenderer is active
     */
    isEnabled: boolean;

    /**
     * Renders the edges of the attached mesh,
     */
    render(): void;

    /**
     * Checks wether or not the edges renderer is ready to render.
     * @return true if ready, otherwise false.
     */
    isReady(): boolean;
}

/**
 * This class is used to generate edges of the mesh that could then easily be rendered in a scene.
 */
export class EdgesRenderer implements IEdgesRenderer {

    /**
     * Define the size of the edges with an orthographic camera
     */
    public edgesWidthScalerForOrthographic = 1000.0;

    /**
     * Define the size of the edges with a perspective camera
     */
    public edgesWidthScalerForPerspective = 50.0;

    protected _source: AbstractMesh;
    protected _linesPositions = new Array<number>();
    protected _linesNormals = new Array<number>();
    protected _linesIndices = new Array<number>();
    protected _epsilon: number;
    protected _indicesCount: number;

    protected _lineShader: ShaderMaterial;
    protected _ib: DataBuffer;
    protected _buffers: { [key: string]: Nullable<VertexBuffer> } = {};
    protected _buffersForInstances: { [key: string]: Nullable<VertexBuffer> } = {};
    protected _checkVerticesInsteadOfIndices = false;

    private _meshRebuildObserver: Nullable<Observer<AbstractMesh>>;
    private _meshDisposeObserver: Nullable<Observer<Node>>;

    /** Gets or sets a boolean indicating if the edgesRenderer is active */
    public isEnabled = true;

    private static _LineShaders: Array<ShaderMaterial> = [];
    private static _LineShaderScenes: Array<Scene> = [];

    private static GetShader(scene: Scene): ShaderMaterial {
        let idx = EdgesRenderer._LineShaderScenes.indexOf(scene);

        if (idx < 0) {
            EdgesRenderer._LineShaderScenes.push(scene);

            const shader = new ShaderMaterial("lineShader", scene, "line",
                {
                    attributes: ["position", "normal"],
                    uniforms: ["world", "viewProjection", "color", "width", "aspectRatio"]
                });

            shader.disableDepthWrite = true;
            shader.backFaceCulling = false;

            EdgesRenderer._LineShaders.push(shader);

            idx = EdgesRenderer._LineShaders.length - 1;
        }

        return EdgesRenderer._LineShaders[idx];
    }

    /**
     * Creates an instance of the EdgesRenderer. It is primarily use to display edges of a mesh.
     * Beware when you use this class with complex objects as the adjacencies computation can be really long
     * @param  source Mesh used to create edges
     * @param  epsilon sum of angles in adjacency to check for edge
     * @param  checkVerticesInsteadOfIndices bases the edges detection on vertices vs indices
     * @param  generateEdgesLines - should generate Lines or only prepare resources.
     */
    constructor(source: AbstractMesh, epsilon = 0.95, checkVerticesInsteadOfIndices = false, generateEdgesLines = true) {
        this._source = source;
        this._checkVerticesInsteadOfIndices = checkVerticesInsteadOfIndices;

        this._epsilon = epsilon;

        this._prepareRessources();
        if (generateEdgesLines) {<commit_msg>Add a new property to scene instead of keeping track in EdgesRenderer<commit_after>import { Nullable } from "../types";
import { VertexBuffer } from "../Meshes/buffer";
import { AbstractMesh } from "../Meshes/abstractMesh";
import { Mesh } from "../Meshes/mesh";
import { LinesMesh, InstancedLinesMesh } from "../Meshes/linesMesh";
import { Vector3, TmpVectors } from "../Maths/math.vector";
import { IDisposable, Scene } from "../scene";
import { Observer } from "../Misc/observable";
import { Effect } from "../Materials/effect";
import { Material } from "../Materials/material";
import { ShaderMaterial } from "../Materials/shaderMaterial";
import { Camera } from "../Cameras/camera";
import { Constants } from "../Engines/constants";
import { Node } from "../node";

import "../Shaders/line.fragment";
import "../Shaders/line.vertex";
import { DataBuffer } from '../Meshes/dataBuffer';

declare module "../Scene" {
    export interface Scene {
        /** @hidden */
        _edgeRenderLineShader: Nullable<ShaderMaterial>;
    }
}

declare module "../Meshes/abstractMesh" {
    export interface AbstractMesh {
        /**
         * Gets the edgesRenderer associated with the mesh
         */
        edgesRenderer: Nullable<EdgesRenderer>;
    }
}
AbstractMesh.prototype.disableEdgesRendering = function(): AbstractMesh {
    if (this._edgesRenderer) {
        this._edgesRenderer.dispose();
        this._edgesRenderer = null;
    }
    return this;
};

AbstractMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): AbstractMesh {
    this.disableEdgesRendering();
    this._edgesRenderer = new EdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);
    return this;
};

Object.defineProperty(AbstractMesh.prototype, "edgesRenderer", {
    get: function(this: AbstractMesh) {
        return this._edgesRenderer;
    },
    enumerable: true,
    configurable: true
});

declare module "../Meshes/linesMesh" {
    export interface LinesMesh {
        /**
         * Enables the edge rendering mode on the mesh.
         * This mode makes the mesh edges visible
         * @param epsilon defines the maximal distance between two angles to detect a face
         * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces
         * @returns the currentAbstractMesh
         * @see https://www.babylonjs-playground.com/#19O9TU#0
         */
        enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): AbstractMesh;
    }
}
LinesMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): AbstractMesh {
    this.disableEdgesRendering();
    this._edgesRenderer = new LineEdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);
    return this;
};

declare module "../Meshes/linesMesh" {
    export interface InstancedLinesMesh {
        /**
         * Enables the edge rendering mode on the mesh.
         * This mode makes the mesh edges visible
         * @param epsilon defines the maximal distance between two angles to detect a face
         * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces
         * @returns the current InstancedLinesMesh
         * @see https://www.babylonjs-playground.com/#19O9TU#0
         */
        enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): InstancedLinesMesh;
    }
}

InstancedLinesMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): InstancedLinesMesh {
    LinesMesh.prototype.enableEdgesRendering.apply(this, arguments);
    return this;
};

/**
 * FaceAdjacencies Helper class to generate edges
 */
class FaceAdjacencies {
    public edges = new Array<number>();
    public p0: Vector3;
    public p1: Vector3;
    public p2: Vector3;
    public edgesConnectedCount = 0;
}

/**
 * Defines the minimum contract an Edges renderer should follow.
 */
export interface IEdgesRenderer extends IDisposable {
    /**
     * Gets or sets a boolean indicating if the edgesRenderer is active
     */
    isEnabled: boolean;

    /**
     * Renders the edges of the attached mesh,
     */
    render(): void;

    /**
     * Checks wether or not the edges renderer is ready to render.
     * @return true if ready, otherwise false.
     */
    isReady(): boolean;
}

/**
 * This class is used to generate edges of the mesh that could then easily be rendered in a scene.
 */
export class EdgesRenderer implements IEdgesRenderer {

    /**
     * Define the size of the edges with an orthographic camera
     */
    public edgesWidthScalerForOrthographic = 1000.0;

    /**
     * Define the size of the edges with a perspective camera
     */
    public edgesWidthScalerForPerspective = 50.0;

    protected _source: AbstractMesh;
    protected _linesPositions = new Array<number>();
    protected _linesNormals = new Array<number>();
    protected _linesIndices = new Array<number>();
    protected _epsilon: number;
    protected _indicesCount: number;

    protected _lineShader: ShaderMaterial;
    protected _ib: DataBuffer;
    protected _buffers: { [key: string]: Nullable<VertexBuffer> } = {};
    protected _buffersForInstances: { [key: string]: Nullable<VertexBuffer> } = {};
    protected _checkVerticesInsteadOfIndices = false;

    private _meshRebuildObserver: Nullable<Observer<AbstractMesh>>;
    private _meshDisposeObserver: Nullable<Observer<Node>>;

    /** Gets or sets a boolean indicating if the edgesRenderer is active */
    public isEnabled = true;

    private static GetShader(scene: Scene): ShaderMaterial {
        if (!scene._edgeRenderLineShader) {
            const shader = new ShaderMaterial("lineShader", scene, "line",
                {
                    attributes: ["position", "normal"],
                    uniforms: ["world", "viewProjection", "color", "width", "aspectRatio"]
                });

            shader.disableDepthWrite = true;
            shader.backFaceCulling = false;

            scene._edgeRenderLineShader = shader;
        }

        return scene._edgeRenderLineShader;
    }

    /**
     * Creates an instance of the EdgesRenderer. It is primarily use to display edges of a mesh.
     * Beware when you use this class with complex objects as the adjacencies computation can be really long
     * @param  source Mesh used to create edges
     * @param  epsilon sum of angles in adjacency to check for edge
     * @param  checkVerticesInsteadOfIndices bases the edges detection on vertices vs indices
     * @param  generateEdgesLines - should generate Lines or only prepare resources.
     */
    constructor(source: AbstractMesh, epsilon = 0.95, checkVerticesInsteadOfIndices = false, generateEdgesLines = true) {
        this._source = source;
        this._checkVerticesInsteadOfIndices = checkVerticesInsteadOfIndices;

        this._epsilon = epsilon;

        this._prepareRessources();
        if (generateEdgesLines) {
{'fraction_non_alphanumeric': 0.09585565266422329, 'fraction_numerical': 0.005215675218494502, 'mean_word_length': 3.173235294117647, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 28, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5192257', 'n_tokens_mistral': 3830, 'n_tokens_neox': 3725, 'n_words': 1159}