<commit_before>import macro from 'vtk.js/Sources/macro';

import {
  BehaviorCategory,
  ShapeBehavior,
} from 'vtk.js/Sources/Widgets/Widgets3D/ShapeWidget/Constants';

import vtkLabelRepresentation from 'vtk.js/Sources/Interaction/Widgets/LabelRepresentation';

import { SlicingMode } from 'vtk.js/Sources/Rendering/Core/ImageMapper/Constants';
import { vec3 } from 'gl-matrix';

const { vtkErrorMacro } = macro;

const EPSILON = 1e-6;

function makeBoundsFromPoints(point1, point2) {
  return [
    Math.min(point1[0], point2[0]),
    Math.max(point1[0], point2[0]),
    Math.min(point1[1], point2[1]),
    Math.max(point1[1], point2[1]),
    Math.min(point1[2], point2[2]),
    Math.max(point1[2], point2[2]),
  ];
}

export default function widgetBehavior(publicAPI, model) {
  model.classHierarchy.push('vtkShapeWidgetProp');

  // --------------------------------------------------------------------------
  // Display 2D
  // --------------------------------------------------------------------------

  publicAPI.setDisplayCallback = (callback) =>
    model.representations[0].setDisplayCallback(callback);

  // --------------------------------------------------------------------------
  // Public methods
  // --------------------------------------------------------------------------

  publicAPI.setSlicingMode = (slicingMode) => {
    publicAPI.reset();
    const direction = [0, 0, 0];
    direction[slicingMode % 3] = 1;
    model.shapeHandle.setDirection(direction);
    model.manipulator.setNormal(direction);
  };

  publicAPI.setModifierBehavior = (behavior) => {
    Object.assign(model.modifierBehavior, behavior);
  };

  publicAPI.isBehaviorActive = (category, flag) =>
    Object.keys(model.keysDown).some(
      (key) =>
        model.keysDown[key] &&
        model.modifierBehavior[key] &&
        model.modifierBehavior[key][category] === flag
    );

  publicAPI.isOppositeBehaviorActive = (category, flag) =>
    Object.values(ShapeBehavior[category]).some(
      (flagToTry) =>
        flag !== flagToTry && publicAPI.isBehaviorActive(category, flagToTry)
    );

  publicAPI.getActiveBehaviorFromCategory = (category) =>
    Object.values(ShapeBehavior[category]).find(
      (flag) =>
        publicAPI.isBehaviorActive(category, flag) ||
        (!publicAPI.isOppositeBehaviorActive(category, flag) &&
          model.modifierBehavior.None[category] === flag)
    );

  publicAPI.isRatioFixed = () =>
    publicAPI.getActiveBehaviorFromCategory(BehaviorCategory.RATIO) ===
    ShapeBehavior[BehaviorCategory.RATIO].FIXED;

  publicAPI.isDraggingEnabled = () => {
    const behavior = publicAPI.getActiveBehaviorFromCategory(
      BehaviorCategory.PLACEMENT
    );
    return (
      behavior === ShapeBehavior[BehaviorCategory.PLACEMENT].DRAG ||
      behavior === ShapeBehavior[BehaviorCategory.PLACEMENT].CLICK_AND_DRAG
    );
  };

  publicAPI.isDraggingForced = () =>
    publicAPI.isBehaviorActive(
      BehaviorCategory.PLACEMENT,
      ShapeBehavior[BehaviorCategory.PLACEMENT].DRAG
    ) ||
    model.modifierBehavior.None[BehaviorCategory.PLACEMENT] ===
      ShapeBehavior[BehaviorCategory.PLACEMENT].DRAG;

  publicAPI.setVisibleOnFocus = (visibleOnFocus) => {
    model.visibleOnFocus = visibleOnFocus;
  };

  publicAPI.setXAxis = (xAxis) => {
    vec3.normalize(model.xAxis, xAxis);
  };

  publicAPI.setYAxis = (yAxis) => {
    vec3.normalize(model.yAxis, yAxis);
  };

  publicAPI.setZAxis = (zAxis) => {
    vec3.normalize(model.zAxis, zAxis);
  };

  publicAPI.setLabelTextCallback = (callback) => {
    model.labelTextCallback = callback;
  };

  publicAPI.setResetAfterPointPlacement = (reset) => {
    model.resetAfterPointPlacement = reset;
  };

  publicAPI.getPoint1 = () => model.point1;
  publicAPI.getPoint2 = () => model.point2;

  publicAPI.setPoints = (point1, point2) => {
    model.point1 = point1;
    model.point2 = point2;

    model.point1Handle.setOrigin(model.point1);
    model.point2Handle.setOrigin(model.point2);

    if (model.useHandles) {
      model.point1Handle.setVisible(true);
      model.point2Handle.setVisible(true);
    }
    model.shapeHandle.setVisible(true);

    publicAPI.updateShapeBounds();
  };

  // This method is to be called to place the first point
  // for the first time. It is not inlined so that
  // the user can specify himself where the first point
  // is right after publicAPI.grabFocus() without waiting
  // for interactions.
  publicAPI.placePoint1 = (point) => {
    if (model.hasFocus) {
      publicAPI.setPoints(point, point);

      model.point1Handle.deactivate();
      model.point2Handle.activate();
      model.activeState = model.point2Handle;

      if (model.useHandles) {
        model.point2Handle.setVisible(true);
      }

      publicAPI.updateShapeBounds();
      publicAPI.invokeStartInteractionEvent();

      if (model.visibleOnFocus) {
        model.shapeHandle.setVisible(true);
      }
    }
  };

  publicAPI.placePoint2 = (point2) => {
    if (model.hasFocus) {
      model.point2 = point2;

      model.point2Handle.setOrigin(model.point2);

      publicAPI.updateShapeBounds();
      publicAPI.invokeInteractionEvent();
      publicAPI.invokeEndInteractionEvent();

      if (model.resetAfterPointPlacement) {
        publicAPI.reset();
      } else {
        publicAPI.loseFocus();
      }
    }
  };

  publicAPI.getLabel = () => model.label;

  // --------------------------------------------------------------------------
  // Private methods
  // --------------------------------------------------------------------------

  publicAPI.makeSquareFromPoints = (point1, point2) => {
    const d = [0, 0, 0];
    vec3.subtract(d, point2, point1);

    let sx = vec3.dot(d, model.xAxis);
    let sy = vec3.dot(d, model.yAxis);
    let sz = vec3.dot(d, model.zAxis);

    const absSx = Math.abs(sx);
    const absSy = Math.abs(sy);
    const absSz = Math.abs(sz);

    const slicingMode = model.shapeHandle.getDirection().indexOf(1);

    if (slicingMode === SlicingMode.I) {
      if (absSy < EPSILON) {
        sy = sz;
      } else if (absSz < EPSILON) {
        sz = sy;
      } else if (absSy > absSz) {
        sz = (sz / absSz) * absSy;
      } else {<commit_msg>fix(ShapeWidget): Include label in setVisibility method.<commit_after>import macro from 'vtk.js/Sources/macro';

import {
  BehaviorCategory,
  ShapeBehavior,
} from 'vtk.js/Sources/Widgets/Widgets3D/ShapeWidget/Constants';

import vtkLabelRepresentation from 'vtk.js/Sources/Interaction/Widgets/LabelRepresentation';

import { SlicingMode } from 'vtk.js/Sources/Rendering/Core/ImageMapper/Constants';
import { vec3 } from 'gl-matrix';

const { vtkErrorMacro } = macro;

const EPSILON = 1e-6;

function makeBoundsFromPoints(point1, point2) {
  return [
    Math.min(point1[0], point2[0]),
    Math.max(point1[0], point2[0]),
    Math.min(point1[1], point2[1]),
    Math.max(point1[1], point2[1]),
    Math.min(point1[2], point2[2]),
    Math.max(point1[2], point2[2]),
  ];
}

export default function widgetBehavior(publicAPI, model) {
  model.classHierarchy.push('vtkShapeWidgetProp');

  const superClass = Object.assign({}, publicAPI);

  // --------------------------------------------------------------------------
  // Display 2D
  // --------------------------------------------------------------------------

  publicAPI.setDisplayCallback = (callback) =>
    model.representations[0].setDisplayCallback(callback);

  // --------------------------------------------------------------------------
  // Public methods
  // --------------------------------------------------------------------------

  publicAPI.setSlicingMode = (slicingMode) => {
    publicAPI.reset();
    const direction = [0, 0, 0];
    direction[slicingMode % 3] = 1;
    model.shapeHandle.setDirection(direction);
    model.manipulator.setNormal(direction);
  };

  publicAPI.setModifierBehavior = (behavior) => {
    Object.assign(model.modifierBehavior, behavior);
  };

  publicAPI.isBehaviorActive = (category, flag) =>
    Object.keys(model.keysDown).some(
      (key) =>
        model.keysDown[key] &&
        model.modifierBehavior[key] &&
        model.modifierBehavior[key][category] === flag
    );

  publicAPI.isOppositeBehaviorActive = (category, flag) =>
    Object.values(ShapeBehavior[category]).some(
      (flagToTry) =>
        flag !== flagToTry && publicAPI.isBehaviorActive(category, flagToTry)
    );

  publicAPI.getActiveBehaviorFromCategory = (category) =>
    Object.values(ShapeBehavior[category]).find(
      (flag) =>
        publicAPI.isBehaviorActive(category, flag) ||
        (!publicAPI.isOppositeBehaviorActive(category, flag) &&
          model.modifierBehavior.None[category] === flag)
    );

  publicAPI.isRatioFixed = () =>
    publicAPI.getActiveBehaviorFromCategory(BehaviorCategory.RATIO) ===
    ShapeBehavior[BehaviorCategory.RATIO].FIXED;

  publicAPI.isDraggingEnabled = () => {
    const behavior = publicAPI.getActiveBehaviorFromCategory(
      BehaviorCategory.PLACEMENT
    );
    return (
      behavior === ShapeBehavior[BehaviorCategory.PLACEMENT].DRAG ||
      behavior === ShapeBehavior[BehaviorCategory.PLACEMENT].CLICK_AND_DRAG
    );
  };

  publicAPI.isDraggingForced = () =>
    publicAPI.isBehaviorActive(
      BehaviorCategory.PLACEMENT,
      ShapeBehavior[BehaviorCategory.PLACEMENT].DRAG
    ) ||
    model.modifierBehavior.None[BehaviorCategory.PLACEMENT] ===
      ShapeBehavior[BehaviorCategory.PLACEMENT].DRAG;

  publicAPI.setVisibleOnFocus = (visibleOnFocus) => {
    model.visibleOnFocus = visibleOnFocus;
  };

  publicAPI.setXAxis = (xAxis) => {
    vec3.normalize(model.xAxis, xAxis);
  };

  publicAPI.setYAxis = (yAxis) => {
    vec3.normalize(model.yAxis, yAxis);
  };

  publicAPI.setZAxis = (zAxis) => {
    vec3.normalize(model.zAxis, zAxis);
  };

  publicAPI.setLabelTextCallback = (callback) => {
    model.labelTextCallback = callback;
  };

  publicAPI.setResetAfterPointPlacement = (reset) => {
    model.resetAfterPointPlacement = reset;
  };

  publicAPI.getPoint1 = () => model.point1;
  publicAPI.getPoint2 = () => model.point2;

  publicAPI.setPoints = (point1, point2) => {
    model.point1 = point1;
    model.point2 = point2;

    model.point1Handle.setOrigin(model.point1);
    model.point2Handle.setOrigin(model.point2);

    if (model.useHandles) {
      model.point1Handle.setVisible(true);
      model.point2Handle.setVisible(true);
    }
    model.shapeHandle.setVisible(true);

    publicAPI.updateShapeBounds();
  };

  // This method is to be called to place the first point
  // for the first time. It is not inlined so that
  // the user can specify himself where the first point
  // is right after publicAPI.grabFocus() without waiting
  // for interactions.
  publicAPI.placePoint1 = (point) => {
    if (model.hasFocus) {
      publicAPI.setPoints(point, point);

      model.point1Handle.deactivate();
      model.point2Handle.activate();
      model.activeState = model.point2Handle;

      if (model.useHandles) {
        model.point2Handle.setVisible(true);
      }

      publicAPI.updateShapeBounds();
      publicAPI.invokeStartInteractionEvent();

      if (model.visibleOnFocus) {
        model.shapeHandle.setVisible(true);
      }
    }
  };

  publicAPI.placePoint2 = (point2) => {
    if (model.hasFocus) {
      model.point2 = point2;

      model.point2Handle.setOrigin(model.point2);

      publicAPI.updateShapeBounds();
      publicAPI.invokeInteractionEvent();
      publicAPI.invokeEndInteractionEvent();

      if (model.resetAfterPointPlacement) {
        publicAPI.reset();
      } else {
        publicAPI.loseFocus();
      }
    }
  };

  publicAPI.setVisibility = (visibility) => {
    if (model.useHandles) {
      superClass.setVisibility(visibility);
    } else {
      model.shapeHandle.setVisible(visibility);
    }

    if (model.label) {
      if (visibility) {
        model.label.setContainer(model.interactor.getContainer());
      } else {
        model.label.setContainer(null);
      }
    }

    publicAPI.updateRepresentationForRender();
    model.interactor.render();
  };

  publicAPI.getLabel = () => model.label;

  // --------------------------------------------------------------------------
  // Private methods
  // --------------------------------------------------------------------------

  publicAPI.makeSquareFromPoints = (point1, point2) => {
    const d = [0, 0, 0];
    vec3.subtract(d, point2, point1);

    let sx = vec3.dot(d, model.xAxis);
    let sy = vec3.dot(d, model.yAxis);
    let sz = vec3.dot(d, model.zAxis);

    const absSx = Math.abs(sx);
    const absSy = Math.abs(sy);
    const absSz = Math.abs(sz);

    const slicingMode = model.shapeHandle.getDirection().indexOf(1);

    if (slicingMode === SlicingMode.I) {
      if (absSy < EPSILON) {
        sy = sz;
      } else if (absSz < EPSILON) {
        sz = sy;
      } else if (absSy > absSz) {
        sz = (sz / absSz) * absSy;
      } else {
{'fraction_non_alphanumeric': 0.19368015414258188, 'fraction_numerical': 0.012177263969171483, 'mean_word_length': 2.4565796483750666, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '7052424', 'n_tokens_mistral': 4028, 'n_tokens_neox': 3882, 'n_words': 617}