/**
  Copyright (C) 2012-2024 by Autodesk, Inc.
  All rights reserved.

  VERICUT post processor configuration.

  $Revision: 44144 3b472f81a6944f3dfac3f9a3e56d873efce75350 $
  $Date: 2024-09-10 13:57:14 $

  FORKID {7B821814-D2EB-4DEE-84F2-FF4D3F28BEB1}
*/

description = "VERICUT";
vendor = "CGTech";
vendorUrl = "http://www.cgtech.com";
legal = "Copyright (C) 2012-2024 by Autodesk, Inc.";
certificationLevel = 2;
minimumRevision = 45702;
capabilities = CAPABILITY_INTERMEDIATE | CAPABILITY_CASCADING;

longDescription = "Post integration with VERICUT. This is a cascading post to use for automatic simulation of generated NC programs in VERICUT.";

dependencies = "vericut.hta";

// user-defined properties
properties = {
  toolListOnly: {
    title      : "Create tool database only",
    description: "Enable to create the tool database only, disable to run VERICUT.",
    group      : 0,
    type       : "boolean",
    value      : false,
    scope      : "post"
  }
};

function onSection() {
  if (currentSection.getType() != TYPE_MILLING) {
    error(localize("Unsupported operation type."));
    return;
  }
  skipRemainingSection();
}

function onClose() {
  showDialog();

  if (getProperty("toolListOnly")) {
    createToolDatabaseFile();
  } else {
    createVerificationJob();
    createProjectFile();
    createToolDatabaseFile();
    createOPSfile();
  }
}

this.exportStock = true;
this.exportPart = true;
this.exportFixture = true;

var destPath = FileSystem.getFolderPath(getCascadingPath());
var projectPath;
var vericutPath;

/* eslint-disable */
function showDialog() {
  if (!FileSystem.isFolder(FileSystem.getTemporaryFolder())) {
    FileSystem.makeFolder(FileSystem.getTemporaryFolder());
  }
  var path = FileSystem.getTemporaryFile("post");
  var exePath = getVericutPath();
  execute(findFile("vericut.hta"), "\"" + path + "\" " + "\"" + exePath + "\"", false, "");
  var result = {};
  try {
    var file = new TextFile(path, false, "utf-8");
    while (true) {
      var line = file.readln();
      var index = line.indexOf("=");
      if (index >= 0) {
        var name = line.substr(0, index);
        var value = line.substr(index + 1);
        result[name] = value;
      }
    }
    file.close();
  } catch (e) {
  }
  FileSystem.remove(path);

  var gotValues = false;
  for (var name in result) {
    gotValues = true;
    break;
  }
  if (!gotValues) {
    error(localize("Aborted by user."));
    return false;
  }

  var comment;
  for (var name in result) {
    var value = result[name];
    switch (name) {
    case "vericutPath":
      vericutPath = value;
      break;
    case "vcprojectPath":
      projectPath = value;
      break;
    case "baseToolNumber":
      baseToolNumber = parseInt(value);
      baseToolNumber = isNaN(baseToolNumber) ? 0 : baseToolNumber;
      break;
    }
  }
  return true;
}
/* eslint-enable */

var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4)});
var spatialFormat = createFormat({decimals:4});

function createOPSfile() {
  var path = FileSystem.replaceExtension(getCascadingPath(), "ops");
  var file = new TextFile(path, true, "utf-8");

  file.writeln("PROJECT FILE=" + "\"" + projectPath + "\"");
  file.writeln("SETUP NAME=" + "\"" + programName + "\"" + " INDEX=1 SETUP=1 FILE=" + "\"" + projectPath + "\"");
  file.writeln("SETUP NAME=" + "\"" + programName + "\"" + " INDEX=1 SETUP=1 FILE=" + "\"" + FileSystem.replaceExtension(getCascadingPath(), "VcTemp") + "\"");
  file.close();
}

function createToolDatabaseFile() {
  var path = FileSystem.replaceExtension(getCascadingPath(), "tls");
  var file = new TextFile(path, true, "ansi");

  if (revision < 41761) {
    error(localize("Your version of CAM does not support the use of the Vericut interface. Please update to the latest version."));
    return;
  }

  file.writeln("");
  file.writeln("");
  file.writeln("");

  var tools = getToolTable();
  if (tools.getNumberOfTools() > 0) {
    for (var i = 0; i < tools.getNumberOfTools(); ++i) {
      var tool = tools.getTool(i);
      var toolType = tool.getType();
      var holder = tool.holder;

      switch (toolType) {
      case TOOL_DRILL:
      case TOOL_DRILL_CENTER:
      case TOOL_DRILL_SPOT:
      case TOOL_DRILL_BLOCK:
      case TOOL_REAMER:
      case TOOL_BORING_BAR:
      case TOOL_COUNTER_BORE:
      case TOOL_COUNTER_SINK:
        cutterType = "HoleMaking";
        break;
      case TOOL_TAP_RIGHT_HAND:
      case TOOL_TAP_LEFT_HAND:
        cutterType = "Tap";
        break;
      case TOOL_PROBE:
        cutterType = "Probing";
        break;
      default:
        cutterType = "Milling";
        break;
      }

      var toolNumber = tool.type == TOOL_PROBE ? tool.number : baseToolNumber + tool.number;
      file.writeln("");
      file.writeln("" + getToolTypeName(tool.type) + "");
      file.writeln("" + tool.numberOfFlutes + "");
      file.writeln("SpindleAxis");
      file.writeln("" + cutterType + "");
      file.writeln("");

      if (cutterType == "Tap") {
        file.writeln("");
        file.writeln("" + spatialFormat.format(tool.diameter) + "");
        file.writeln("" + spatialFormat.format(1 / tool.threadPitch) + "");
        file.writeln("" + spatialFormat.format(tool.fluteLength) + "");
        file.writeln("" + spatialFormat.format(tool.bodyLength + ((unit == IN ? 0.5 : 12))) + "");
        file.writeln("" + spatialFormat.format(tool.diameter * 0.9) + "");
        file.writeln("" + spatialFormat.format(tool.shaftDiameter) + "");
        file.writeln("" + spatialFormat.format(tool.shoulderLength) + "");
        file.writeln("" + spatialFormat.format(tool.shaftDiameter) + "");
        file.writeln("" + spatialFormat.format(tool.diameter * 0.9) + "");
        file.writeln("" + spatialFormat.format(0.0) + "");
        file.writeln("");
        file.writeln("" + (toolType == TOOL_TAP_LEFT_HAND ? "Left" : "Right") + "");
        file.writeln("" + (tool.clockwise ? "CW" : "CCW") + "");
        file.writeln("Unified (" + ((unit == IN) ? "Inch" : "Millimeter") + ")");
        file.writeln("");
        file.writeln("");
        file.writeln(" 0 0 " + spatialFormat.format(0) + " ");
        file.writeln("off");
        file.writeln("");
      } else if (cutterType == "Probing") {
        file.writeln("");
        file.writeln("" + spatialFormat.format(tool.diameter) + "");
        file.writeln("" + spatialFormat.format(tool.bodyLength) + "");
        file.writeln("" + spatialFormat.format(tool.shaftDiameter) + "");
        file.writeln("" + spatialFormat.format(tool.bodyLength * 1.1) + "");
        file.writeln("" + spatialFormat.format(tool.spindleRPM) + "");
        file.writeln(" 0 0 " + spatialFormat.format(0) + " ");
        file.writeln("off");
        file.writeln("");
      } else {

        /*
        file.writeln(" Type=" + "\"" + "Apt 7" + "\"");
        file.writeln("" + xyzFormat.format(tool.diameter) + "");
        file.writeln("" + xyzFormat.format(tool.cornerRadius) + "");
        file.writeln("0");
        file.writeln("0");
        file.writeln("0");
        file.writeln("0");
        file.writeln("" + tool.bodyLength + "");
        file.writeln("" + tool.bodyLength + "");
        file.writeln("" + tool.shaftDiameter + "");
        file.writeln("" + tool.fluteLength + "");
        file.writeln("");
        */

        file.writeln("");
        file.writeln("00");
        var cutter = tool.getCutterProfile();
        for (var k = 0; k < cutter.getNumberOfEntities() / 2; ++k) {
          var arc = ((cutter.getEntity(k).clockwise == true) || cutter.getEntity(k).center.length > 1e-4);
          var endX = xyzFormat.format(cutter.getEntity(k).end.x);
          var endY = xyzFormat.format(cutter.getEntity(k).end.y);
          var centerX = xyzFormat.format(cutter.getEntity(k).center.x);
          var centerY = xyzFormat.format(cutter.getEntity(k).center.y);
          var arcDir = cutter.getEntity(k).clockwise ? "CW" : "CCW";
          var radius = xyzFormat.format(Vector.diff(cutter.getEntity(k).start, cutter.getEntity(k).center).length);

          if (arc) {
            file.writeln("" + centerX + "" + centerY + "" + radius + "" + arcDir + "");
          }
          file.writeln("" + endX + "" + endY + "");
        }
        file.writeln("" + spatialFormat.format(tool.fluteLength) + "");
        file.writeln("");
      }
      file.writeln("");

      if (holder && holder.hasSections()) {
        file.writeln("");
        file.writeln("");
        file.writeln(" 0 0 ");
        var hCurrent = 0;
        if (holder && holder.hasSections()) {
          var n = holder.getNumberOfSections();
          for (var j = 0; j <= n; ++j) {
            if (j == 0) {
              //file.writeln("        " + tool.shaftDiameter + " 0 " + (tool.shaftDiameter/2) + " 0");
            } else {
              hCurrent += holder.getLength(j - 1);
              file.writeln("" + xyzFormat.format(holder.getDiameter(j - 1) / 2) + "" + " " + xyzFormat.format(hCurrent) + " ");
            }
          }
          file.writeln("0 " + xyzFormat.format(hCurrent) + " ");
        }
        file.writeln(" 0 0 " + xyzFormat.format(tool.bodyLength) + " ");
        file.writeln("");
        file.writeln("");
      }
      file.writeln("");
      file.writeln("0");
      file.writeln("0");
      file.writeln("" + (tool.bodyLength + tool.holderLength) + "");
      file.writeln("");
      file.writeln("");
    }
  }
  file.writeln("");
  file.writeln("");
  file.close();
}

function createProjectFile() {
  var path = FileSystem.replaceExtension(getCascadingPath(), "VcTemp");
  var file = new TextFile(path, true, "ansi");

  if (!programName) {
    error(localize("Program name is not specified."));
    return;
  }

  file.writeln("");
  file.writeln("");
  file.writeln("");
  file.writeln("    ");
  file.writeln("    ");
  // path to NC PGM
  file.writeln("    " + getCascadingPath() + "");
  file.writeln("    ");
  file.writeln("    ");
  file.writeln("");
  file.writeln("" + FileSystem.replaceExtension(getCascadingPath(), "tls") + "");
  file.writeln("");
  file.writeln("    ");
  var tools = getToolTable();
  if (tools.getNumberOfTools() > 0) {
    for (var i = 0; i < tools.getNumberOfTools(); ++i) {
      var tool = tools.getTool(i);
      var toolNumber = tool.type == TOOL_PROBE ? tool.number : baseToolNumber + tool.number;
      file.writeln("      ");
      file.writeln("        " + tool.number + "");
      file.writeln("      ");
    }
  }
  file.writeln("    ");
  /* Not recommended by CGTech
  file.writeln("");
  file.writeln("");
  file.writeln("");
  */
  file.writeln("");

  var workpiece = getWorkpiece();
  var delta = Vector.diff(workpiece.upper, workpiece.lower);

  if (hasGlobalParameter("autodeskcam:fixture-path")) {
    var x = xyzFormat.format(getSection(0).getFCSOrigin().x);
    var y = xyzFormat.format(getSection(0).getFCSOrigin().y);
    var z = xyzFormat.format(getSection(0).getFCSOrigin().z);
  } else {
    var x = xyzFormat.format(delta.x / 2 - workpiece.upper.x);
    var y = xyzFormat.format(delta.y / 2 - workpiece.upper.y);
    var z = xyzFormat.format(workpiece.lower.z);
  }
  /*
  var vxx = xyzFormat.format(getSection(0).getFCSPlane().getRight().x);
  var vxy = xyzFormat.format(getSection(0).getFCSPlane().getRight().y);
  var vxz = xyzFormat.format(getSection(0).getFCSPlane().getRight().z);
  var vyx = xyzFormat.format(getSection(0).getFCSPlane().getUp().x);
  var vyy = xyzFormat.format(getSection(0).getFCSPlane().getUp().y);
  var vyz = xyzFormat.format(getSection(0).getFCSPlane().getUp().z);
*/
  if (destFixturePath) {
    file.writeln("");
    file.writeln("  Fixture");
    file.writeln("    ");
    file.writeln("    ");
    file.writeln("    ");
    file.writeln("      " + destFixturePath + "");
    file.writeln("          ");
    file.writeln("            ");
    file.writeln("            ");
    file.writeln("            ");
    file.writeln("            ");
    file.writeln("          ");
    file.writeln("      ");
    file.writeln("    ");
  }
  file.writeln("");
  file.writeln("  Fixture");
  if (destFixturePath) {
    file.writeln("    ");
  } else {
    file.writeln("    ");
  }
  file.writeln("    ");
  file.writeln("    ");
  file.writeln("      " + destStockPath + "");
  file.writeln("          ");
  file.writeln("            ");
  file.writeln("            ");
  file.writeln("            ");
  file.writeln("            ");
  file.writeln("          ");
  file.writeln("      ");
  file.writeln("    ");
  file.writeln("");
  file.writeln("  Stock");
  file.writeln("    ");
  file.writeln("    ");
  file.writeln("    ");
  file.writeln("      " + destPartPath + "");
  file.writeln("          ");
  file.writeln("            ");
  file.writeln("            ");
  file.writeln("            ");
  file.writeln("            ");
  file.writeln("          ");
  file.writeln("      ");
  file.writeln("    ");
  file.writeln("");

  file.writeln("");
  /* Not used
  file.writeln("  ");
  file.writeln("    ");
  file.writeln("      1");
  file.writeln("      Spindle");
  file.writeln("      Program_Zero");
  file.writeln("    ");
  file.writeln("  
"); */ var ncFrame = new Array(); var numberOfSections = getNumberOfSections(); for (var i = 0; i < numberOfSections; ++i) { var found = false; var section = getSection(i); for (var j = 0; j < ncFrame.length; ++j) { if (ncFrame[j].workOffsetNumber == section.workOffset) { found = true; break; } } if (!found) { ncFrame.push({workOffsetNumber:section.workOffset, fcsPlane:section.getFCSPlane()}); } } file.writeln(""); for (var i = 0; i < ncFrame.length; ++i) { var workOffset = ncFrame[i].workOffsetNumber; if ((getNumberOfSections() > 0) && (getSection(0).workOffset == 0)) { for (var j = 0; j < getNumberOfSections(); ++j) { if (getSection(j).workOffset > 0) { error(localize("Using multiple work offsets is not possible if the initial work offset is 0.")); return; } } } if (workOffset == 0) { workOffset = 1; } var wcs; if (workOffset > 0) { if (workOffset > 6) { var code = workOffset - 6; wcs = code; } else { wcs = 53 + workOffset; } } file.writeln(" "); file.writeln(" 1"); file.writeln(" Spindle"); file.writeln(" Program_Zero"); // file.writeln(" "); // file.writeln(" "); "); file.writeln(" "); } file.writeln("
"); file.writeln("
"); file.writeln(""); file.writeln(" "); file.writeln("Stock"); file.writeln(""); file.writeln(""); file.writeln(""); // file.writeln(""); // file.writeln("Stock"); // file.writeln(""); // file.writeln(""); // file.writeln(""); file.writeln("
"); file.writeln("
"); file.close(); } function quote(text) { var result = ""; for (var i = 0; i < text.length; ++i) { var ch = text.charAt(i); switch (ch) { case "\\": case "\"": result += "\\"; } result += ch; } return "\"" + result + "\""; } var destStockPath = ""; var destPartPath = ""; var destFixturePath = ""; function createVerificationJob() { var stockPath; if (hasGlobalParameter("autodeskcam:stock-path")) { stockPath = getGlobalParameter("autodeskcam:stock-path"); } var partPath; if (hasGlobalParameter("autodeskcam:part-path")) { partPath = getGlobalParameter("autodeskcam:part-path"); } var fixturePath; if (hasGlobalParameter("autodeskcam:fixture-path")) { fixturePath = getGlobalParameter("autodeskcam:fixture-path"); } if (!FileSystem.isFolder(destPath)) { error(subst(localize("NC verification job folder '%1' does not exist."), destPath)); return; } if (!programName) { error(localize("Program name is not specified.")); return; } if (FileSystem.isFile(stockPath)) { destStockPath = FileSystem.getCombinedPath(destPath, programName + "_STOCK.stl"); FileSystem.copyFile(stockPath, destStockPath); } if (FileSystem.isFile(partPath)) { destPartPath = FileSystem.getCombinedPath(destPath, programName + "_PART.stl"); FileSystem.copyFile(partPath, destPartPath); } if (FileSystem.isFile(fixturePath)) { destFixturePath = FileSystem.getCombinedPath(destPath, programName + "_FIXTURE.stl"); FileSystem.copyFile(fixturePath, destFixturePath); } } function getVericutPath() { var exePath = ""; var vericutVersion = ["9.2", "9.1.2", "9.1", "9.0", "8.1.1", "8.0"]; for (var version in vericutVersion) { try { if (hasRegistryValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\CGTech VERICUT " + vericutVersion[version] + "\\", "InstallLocation")) { vericutPath = getRegistryString("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\CGTech VERICUT " + vericutVersion[version] + "\\", "InstallLocation"); //exePath = FileSystem.getCombinedPath(vericutPath, "\\windows64\\commands\\vericut.bat"); if (FileSystem.isFolder(vericutPath)) { return vericutPath; } } } catch (e) { // ignore } } return exePath; } function onTerminate() { var exePath = FileSystem.getCombinedPath(vericutPath, "\\windows64\\commands\\vericut.bat"); if (!FileSystem.isFile(exePath)) { error(localize("VERICUT was not found on your machine. Be sure to specify a valid VERICUT installation folder.")); return; } var vericutOpsPath = "\"" + "ops=" + FileSystem.replaceExtension(getCascadingPath(), "ops") + "\""; execute(exePath, vericutOpsPath, false, ""); } function setProperty(property, value) { properties[property].current = value; }