TEKLA_SOLID_SCANNER_WITH_PDF_VIEWS_CORRECTED
TEKLA_SOLID_SCANNER_WITH_PDF_VIEWS_CORRECTED
// ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════
// TEKLA_SOLID_SCANNER_WITH_PDF_VIEWS_CORRECTED.cs
// ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════
// Comprehensive Solid Object Scanner with Multi-Page PDF Generation
// FULLY QUALIFIED CLASS NAMES USED THROUGHOUT
// ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════
#pragma warning disable 1633
#pragma reference "Tekla.Macros.Akit"
#pragma reference "Tekla.Macros.Wpf.Runtime"
#pragma reference "Tekla.Macros.Runtime"
#pragma reference "Tekla.Structures.Datatype"
#pragma warning restore 1633
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Runtime.InteropServices;
// TEKLA NAMESPACES - Direct using for commonly used types
using Tekla.Structures.Geometry3d;
using Tekla.Structures.Model;
using Tekla.Structures.Model.UI;
using Tekla.Structures.Solid;
using Tekla.Structures;
namespace Tekla.Technology.Akit.UserScript
{
#region DATA CLASSES
/// <summary>
/// Stores solid edge data with FULLY QUALIFIED types
/// </summary>
public class PUBLIC_CLASS_SolidEdgeData
{
public Tekla.Structures.Geometry3d.Point public_StartPoint_local { get; set; }
public Tekla.Structures.Geometry3d.Point public_EndPoint_local { get; set; }
public Tekla.Structures.Geometry3d.Point public_StartPoint_global { get; set; }
public Tekla.Structures.Geometry3d.Point public_EndPoint_global { get; set; }
public string public_string_EdgeType { get; set; }
public int public_int_EdgeIndex { get; set; }
public PUBLIC_CLASS_SolidEdgeData()
{
this.public_StartPoint_local = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_EndPoint_local = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_StartPoint_global = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_EndPoint_global = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_string_EdgeType = "";
this.public_int_EdgeIndex = 0;
}
}
/// <summary>
/// Stores solid face data with loops
/// </summary>
public class PUBLIC_CLASS_SolidFaceData
{
public int public_int_FaceIndex { get; set; }
public Tekla.Structures.Geometry3d.Vector public_Vector_Normal { get; set; }
public System.Collections.Generic.List<System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point>> public_list_of_list_Loops_local { get; set; }
public System.Collections.Generic.List<System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point>> public_list_of_list_Loops_global { get; set; }
public PUBLIC_CLASS_SolidFaceData()
{
this.public_int_FaceIndex = 0;
this.public_Vector_Normal = new Tekla.Structures.Geometry3d.Vector(0, 0, 1);
this.public_list_of_list_Loops_local = new System.Collections.Generic.List<System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point>>();
this.public_list_of_list_Loops_global = new System.Collections.Generic.List<System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point>>();
}
}
/// <summary>
/// Stores 2D line data for views
/// </summary>
public class PUBLIC_CLASS_LineData2D
{
public double public_double_X1 { get; set; }
public double public_double_Y1 { get; set; }
public double public_double_X2 { get; set; }
public double public_double_Y2 { get; set; }
public bool public_bool_IsHidden { get; set; }
public int public_int_ColorIndex { get; set; }
public PUBLIC_CLASS_LineData2D()
{
this.public_double_X1 = 0;
this.public_double_Y1 = 0;
this.public_double_X2 = 0;
this.public_double_Y2 = 0;
this.public_bool_IsHidden = false;
this.public_int_ColorIndex = 7;
}
}
/// <summary>
/// Stores complete part solid data
/// </summary>
public class PUBLIC_CLASS_PartSolidData
{
public int public_int_PartId { get; set; }
public string public_string_PartGuid { get; set; }
public string public_string_PartName { get; set; }
public string public_string_PartMark { get; set; }
public string public_string_Profile { get; set; }
public string public_string_Material { get; set; }
public string public_string_PartType { get; set; }
public Tekla.Structures.Geometry3d.Point public_Point_MinPoint_local { get; set; }
public Tekla.Structures.Geometry3d.Point public_Point_MaxPoint_local { get; set; }
public Tekla.Structures.Geometry3d.Point public_Point_MinPoint_global { get; set; }
public Tekla.Structures.Geometry3d.Point public_Point_MaxPoint_global { get; set; }
public Tekla.Structures.Geometry3d.CoordinateSystem public_CoordinateSystem { get; set; }
public System.Collections.Generic.List<PUBLIC_CLASS_SolidEdgeData> public_list_Edges { get; set; }
public System.Collections.Generic.List<PUBLIC_CLASS_SolidFaceData> public_list_Faces { get; set; }
public System.Collections.Generic.List<PUBLIC_CLASS_LineData2D> public_list_FrontViewLines { get; set; }
public System.Collections.Generic.List<PUBLIC_CLASS_LineData2D> public_list_TopViewLines { get; set; }
public System.Collections.Generic.List<PUBLIC_CLASS_LineData2D> public_list_SideViewLines { get; set; }
public PUBLIC_CLASS_PartSolidData()
{
this.public_int_PartId = 0;
this.public_string_PartGuid = "";
this.public_string_PartName = "";
this.public_string_PartMark = "";
this.public_string_Profile = "";
this.public_string_Material = "";
this.public_string_PartType = "";
this.public_Point_MinPoint_local = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_Point_MaxPoint_local = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_Point_MinPoint_global = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_Point_MaxPoint_global = new Tekla.Structures.Geometry3d.Point(0, 0, 0);
this.public_CoordinateSystem = null;
this.public_list_Edges = new System.Collections.Generic.List<PUBLIC_CLASS_SolidEdgeData>();
this.public_list_Faces = new System.Collections.Generic.List<PUBLIC_CLASS_SolidFaceData>();
this.public_list_FrontViewLines = new System.Collections.Generic.List<PUBLIC_CLASS_LineData2D>();
this.public_list_TopViewLines = new System.Collections.Generic.List<PUBLIC_CLASS_LineData2D>();
this.public_list_SideViewLines = new System.Collections.Generic.List<PUBLIC_CLASS_LineData2D>();
}
}
/// <summary>
/// Bounding box for view fitting
/// </summary>
public class PUBLIC_CLASS_BoundingBox2D
{
public double public_double_MinX { get; set; }
public double public_double_MinY { get; set; }
public double public_double_MaxX { get; set; }
public double public_double_MaxY { get; set; }
public double public_double_Width { get { return this.public_double_MaxX - this.public_double_MinX; } }
public double public_double_Height { get { return this.public_double_MaxY - this.public_double_MinY; } }
public PUBLIC_CLASS_BoundingBox2D()
{
this.public_double_MinX = System.Double.MaxValue;
this.public_double_MinY = System.Double.MaxValue;
this.public_double_MaxX = System.Double.MinValue;
this.public_double_MaxY = System.Double.MinValue;
}
public void PUBLIC_VOID_Expand(double param_x, double param_y)
{
if (param_x < this.public_double_MinX) this.public_double_MinX = param_x;
if (param_x > this.public_double_MaxX) this.public_double_MaxX = param_x;
if (param_y < this.public_double_MinY) this.public_double_MinY = param_y;
if (param_y > this.public_double_MaxY) this.public_double_MaxY = param_y;
}
}
#endregion DATA CLASSES
#region PDF WRITER CLASS
/// <summary>
/// Pure PDF Writer Class - FULLY QUALIFIED - No external dependencies
/// </summary>
public class PUBLIC_CLASS_PdfWriter
{
// A3 Landscape dimensions in points (72 points = 1 inch)
public static readonly double PUBLIC_STATIC_DOUBLE_A3_LANDSCAPE_WIDTH = 1190.55; // 420mm
public static readonly double PUBLIC_STATIC_DOUBLE_A3_LANDSCAPE_HEIGHT = 841.89; // 297mm
public static readonly double PUBLIC_STATIC_DOUBLE_MM_TO_POINTS = 2.83465;
public static readonly double PUBLIC_STATIC_DOUBLE_POINTS_TO_MM = 0.352778;
// Private fields
private System.Text.StringBuilder _private_StringBuilder_contentStream;
private System.Collections.Generic.List<PRIVATE_CLASS_PdfPage> _private_list_pages;
private PRIVATE_CLASS_PdfPage _private_currentPage;
private double _private_double_pageWidth;
private double _private_double_pageHeight;
private double _private_double_lineWidth;
private double _private_double_strokeR;
private double _private_double_strokeG;
private double _private_double_strokeB;
/// <summary>
/// Internal PDF Page class
/// </summary>
private class PRIVATE_CLASS_PdfPage
{
public double public_double_Width { get; set; }
public double public_double_Height { get; set; }
public string public_string_Content { get; set; }
}
/// <summary>
/// Constructor - A3 Landscape default
/// </summary>
public PUBLIC_CLASS_PdfWriter()
{
this._private_double_pageWidth = PUBLIC_STATIC_DOUBLE_A3_LANDSCAPE_WIDTH;
this._private_double_pageHeight = PUBLIC_STATIC_DOUBLE_A3_LANDSCAPE_HEIGHT;
this._private_list_pages = new System.Collections.Generic.List<PRIVATE_CLASS_PdfPage>();
this._private_double_lineWidth = 0.5;
this._private_double_strokeR = 0;
this._private_double_strokeG = 0;
this._private_double_strokeB = 0;
this.PUBLIC_VOID_NewPage();
}
/// <summary>
/// Get page count
/// </summary>
public int PUBLIC_INT_PageCount
{
get { return this._private_list_pages.Count; }
}
/// <summary>
/// Get page width
/// </summary>
public double PUBLIC_DOUBLE_PageWidth
{
get { return this._private_double_pageWidth; }
}
/// <summary>
/// Get page height
/// </summary>
public double PUBLIC_DOUBLE_PageHeight
{
get { return this._private_double_pageHeight; }
}
/// <summary>
/// Format double for PDF
/// </summary>
private string PRIVATE_STRING_FormatDouble(double param_value)
{
return param_value.ToString("0.####", System.Globalization.CultureInfo.InvariantCulture);
}
/// <summary>
/// Append line to content stream
/// </summary>
private void PRIVATE_VOID_AppendLine(string param_line)
{
this._private_StringBuilder_contentStream.AppendLine(param_line);
}
/// <summary>
/// Start new page
/// </summary>
public void PUBLIC_VOID_NewPage()
{
if (this._private_currentPage != null)
{
this._private_currentPage.public_string_Content = this._private_StringBuilder_contentStream.ToString();
}
this._private_currentPage = new PRIVATE_CLASS_PdfPage();
this._private_currentPage.public_double_Width = this._private_double_pageWidth;
this._private_currentPage.public_double_Height = this._private_double_pageHeight;
this._private_list_pages.Add(this._private_currentPage);
this._private_StringBuilder_contentStream = new System.Text.StringBuilder();
this.PRIVATE_VOID_AppendLine("q"); // Save graphics state
}
/// <summary>
/// Set stroke color RGB (0-1 range)
/// </summary>
public void PUBLIC_VOID_SetColor(double param_r, double param_g, double param_b)
{
this._private_double_strokeR = param_r;
this._private_double_strokeG = param_g;
this._private_double_strokeB = param_b;
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_g) + " " +
this.PRIVATE_STRING_FormatDouble(param_b) + " RG");
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_g) + " " +
this.PRIVATE_STRING_FormatDouble(param_b) + " rg");
}
/// <summary>
/// Set line width
/// </summary>
public void PUBLIC_VOID_SetLineWidth(double param_width)
{
this._private_double_lineWidth = param_width;
this.PRIVATE_VOID_AppendLine(this.PRIVATE_STRING_FormatDouble(param_width) + " w");
}
/// <summary>
/// Set solid line
/// </summary>
public void PUBLIC_VOID_SetLineSolid()
{
this.PRIVATE_VOID_AppendLine("[] 0 d");
}
/// <summary>
/// Set dashed line
/// </summary>
public void PUBLIC_VOID_SetLineDashed(double param_dash, double param_gap)
{
this.PRIVATE_VOID_AppendLine("[" + this.PRIVATE_STRING_FormatDouble(param_dash) + " " +
this.PRIVATE_STRING_FormatDouble(param_gap) + "] 0 d");
}
/// <summary>
/// Draw line
/// </summary>
public void PUBLIC_VOID_DrawLine(double param_x1, double param_y1, double param_x2, double param_y2)
{
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_x1) + " " +
this.PRIVATE_STRING_FormatDouble(param_y1) + " m " +
this.PRIVATE_STRING_FormatDouble(param_x2) + " " +
this.PRIVATE_STRING_FormatDouble(param_y2) + " l S");
}
/// <summary>
/// Draw rectangle
/// </summary>
public void PUBLIC_VOID_DrawRect(double param_x, double param_y, double param_w, double param_h, bool param_fill)
{
string ___local_operator = param_fill ? "f" : "S";
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_x) + " " +
this.PRIVATE_STRING_FormatDouble(param_y) + " " +
this.PRIVATE_STRING_FormatDouble(param_w) + " " +
this.PRIVATE_STRING_FormatDouble(param_h) + " re " + ___local_operator);
}
/// <summary>
/// Draw circle using bezier curves
/// </summary>
public void PUBLIC_VOID_DrawCircle(double param_cx, double param_cy, double param_r)
{
double ___local_k = 0.5522847498 * param_r;
this.PRIVATE_VOID_AppendLine(this.PRIVATE_STRING_FormatDouble(param_cx + param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy) + " m");
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_cx + param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy + ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx + ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy + param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy + param_r) + " c");
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_cx - ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy + param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx - param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy + ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx - param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy) + " c");
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_cx - ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy - param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx - param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy - ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy - param_r) + " c");
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_cx + ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy - param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx + param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy - ___local_k) + " " +
this.PRIVATE_STRING_FormatDouble(param_cx + param_r) + " " +
this.PRIVATE_STRING_FormatDouble(param_cy) + " c S");
}
/// <summary>
/// Draw text
/// </summary>
public void PUBLIC_VOID_DrawText(double param_x, double param_y, string param_text, double param_fontSize, double param_rotation)
{
if (System.String.IsNullOrEmpty(param_text)) return;
string ___local_escapedText = param_text.Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)");
this.PRIVATE_VOID_AppendLine("BT");
if (System.Math.Abs(param_rotation) > 0.001)
{
double ___local_rad = param_rotation * System.Math.PI / 180.0;
double ___local_cos = System.Math.Cos(___local_rad);
double ___local_sin = System.Math.Sin(___local_rad);
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(___local_cos) + " " +
this.PRIVATE_STRING_FormatDouble(___local_sin) + " " +
this.PRIVATE_STRING_FormatDouble(-___local_sin) + " " +
this.PRIVATE_STRING_FormatDouble(___local_cos) + " " +
this.PRIVATE_STRING_FormatDouble(param_x) + " " +
this.PRIVATE_STRING_FormatDouble(param_y) + " Tm");
}
else
{
this.PRIVATE_VOID_AppendLine(
this.PRIVATE_STRING_FormatDouble(param_x) + " " +
this.PRIVATE_STRING_FormatDouble(param_y) + " Td");
}
this.PRIVATE_VOID_AppendLine("/F1 " + this.PRIVATE_STRING_FormatDouble(param_fontSize) + " Tf");
this.PRIVATE_VOID_AppendLine("(" + ___local_escapedText + ") Tj");
this.PRIVATE_VOID_AppendLine("ET");
}
/// <summary>
/// Draw centered text
/// </summary>
public void PUBLIC_VOID_DrawCenteredText(double param_cx, double param_cy, string param_text, double param_fontSize)
{
if (System.String.IsNullOrEmpty(param_text)) return;
double ___local_approxWidth = param_text.Length * param_fontSize * 0.5;
this.PUBLIC_VOID_DrawText(param_cx - ___local_approxWidth / 2, param_cy - param_fontSize / 3, param_text, param_fontSize, 0);
}
/// <summary>
/// Draw arrow
/// </summary>
public void PUBLIC_VOID_DrawArrow(double param_x1, double param_y1, double param_x2, double param_y2, double param_size)
{
this.PUBLIC_VOID_DrawLine(param_x1, param_y1, param_x2, param_y2);
double ___local_angle = System.Math.Atan2(param_y2 - param_y1, param_x2 - param_x1);
double ___local_a1 = ___local_angle + System.Math.PI * 0.85;
double ___local_a2 = ___local_angle - System.Math.PI * 0.85;
this.PUBLIC_VOID_DrawLine(param_x2, param_y2,
param_x2 + param_size * System.Math.Cos(___local_a1),
param_y2 + param_size * System.Math.Sin(___local_a1));
this.PUBLIC_VOID_DrawLine(param_x2, param_y2,
param_x2 + param_size * System.Math.Cos(___local_a2),
param_y2 + param_size * System.Math.Sin(___local_a2));
}
/// <summary>
/// Draw horizontal dimension
/// </summary>
public void PUBLIC_VOID_DrawHorizontalDimension(double param_x1, double param_x2, double param_y, double param_dimY, string param_text, double param_fontSize)
{
// Extension lines
this.PUBLIC_VOID_DrawLine(param_x1, param_y, param_x1, param_dimY);
this.PUBLIC_VOID_DrawLine(param_x2, param_y, param_x2, param_dimY);
// Dimension line with arrows
this.PUBLIC_VOID_DrawArrow(param_x1, param_dimY, param_x2, param_dimY, 2);
this.PUBLIC_VOID_DrawArrow(param_x2, param_dimY, param_x1, param_dimY, 2);
// Text
this.PUBLIC_VOID_DrawCenteredText((param_x1 + param_x2) / 2, param_dimY + param_fontSize * 0.5, param_text, param_fontSize);
}
/// <summary>
/// Draw vertical dimension
/// </summary>
public void PUBLIC_VOID_DrawVerticalDimension(double param_x, double param_y1, double param_y2, double param_dimX, string param_text, double param_fontSize)
{
// Extension lines
this.PUBLIC_VOID_DrawLine(param_x, param_y1, param_dimX, param_y1);
this.PUBLIC_VOID_DrawLine(param_x, param_y2, param_dimX, param_y2);
// Dimension line with arrows
this.PUBLIC_VOID_DrawArrow(param_dimX, param_y1, param_dimX, param_y2, 2);
this.PUBLIC_VOID_DrawArrow(param_dimX, param_y2, param_dimX, param_y1, 2);
// Text (rotated)
this.PUBLIC_VOID_DrawText(param_dimX + param_fontSize * 0.5, (param_y1 + param_y2) / 2, param_text, param_fontSize, 90);
}
/// <summary>
/// Draw title block
/// </summary>
public void PUBLIC_VOID_DrawTitleBlock(string param_title, string param_subtitle, int param_pageNum, int param_totalPages)
{
double ___local_margin = 20;
double ___local_tbHeight = 30;
double ___local_tbY = ___local_margin;
this.PUBLIC_VOID_SetColor(0, 0, 0);
this.PUBLIC_VOID_SetLineWidth(1);
// Border
this.PUBLIC_VOID_DrawRect(___local_margin, ___local_margin,
this._private_double_pageWidth - 2 * ___local_margin,
this._private_double_pageHeight - 2 * ___local_margin, false);
// Title block line
this.PUBLIC_VOID_DrawLine(___local_margin, ___local_tbY + ___local_tbHeight,
this._private_double_pageWidth - ___local_margin, ___local_tbY + ___local_tbHeight);
// Title text
this.PUBLIC_VOID_DrawText(___local_margin + 10, ___local_tbY + 10, param_title, 12, 0);
this.PUBLIC_VOID_DrawText(this._private_double_pageWidth / 2, ___local_tbY + 10, param_subtitle, 10, 0);
this.PUBLIC_VOID_DrawText(this._private_double_pageWidth - ___local_margin - 100, ___local_tbY + 10,
"Page " + param_pageNum.ToString() + " of " + param_totalPages.ToString(), 8, 0);
this.PUBLIC_VOID_DrawText(this._private_double_pageWidth - ___local_margin - 100, ___local_tbY + 20,
System.DateTime.Now.ToString("yyyy-MM-dd HH:mm"), 6, 0);
}
/// <summary>
/// Save PDF to file
/// </summary>
public void PUBLIC_VOID_Save(string param_filePath)
{
// Finalize current page
if (this._private_currentPage != null)
{
this.PRIVATE_VOID_AppendLine("Q"); // Restore state
this._private_currentPage.public_string_Content = this._private_StringBuilder_contentStream.ToString();
}
System.Text.StringBuilder ___local_pdf = new System.Text.StringBuilder();
System.Collections.Generic.List<int> ___local_objectOffsets = new System.Collections.Generic.List<int>();
// Header
___local_pdf.AppendLine("%PDF-1.4");
___local_pdf.AppendLine("%\xe2\xe3\xcf\xd3");
// Object 1: Catalog
___local_objectOffsets.Add(___local_pdf.Length);
___local_pdf.AppendLine("1 0 obj");
___local_pdf.AppendLine("<< /Type /Catalog /Pages 2 0 R >>");
___local_pdf.AppendLine("endobj");
// Object 2: Pages
___local_objectOffsets.Add(___local_pdf.Length);
___local_pdf.AppendLine("2 0 obj");
System.Text.StringBuilder ___local_kids = new System.Text.StringBuilder();
for (int ___local_i = 0; ___local_i < this._private_list_pages.Count; ___local_i++)
{
___local_kids.Append((3 + ___local_i * 3).ToString() + " 0 R ");
}
___local_pdf.AppendLine("<< /Type /Pages /Kids [" + ___local_kids.ToString() + "] /Count " +
this._private_list_pages.Count.ToString() + " >>");
___local_pdf.AppendLine("endobj");
// Pages and content
int ___local_objNum = 3;
for (int ___local_pageIdx = 0; ___local_pageIdx < this._private_list_pages.Count; ___local_pageIdx++)
{
PRIVATE_CLASS_PdfPage ___local_page = this._private_list_pages[___local_pageIdx];
int ___local_pageObjNum = ___local_objNum++;
int ___local_contentObjNum = ___local_objNum++;
int ___local_resourceObjNum = ___local_objNum++;
// Page object
___local_objectOffsets.Add(___local_pdf.Length);
___local_pdf.AppendLine(___local_pageObjNum.ToString() + " 0 obj");
___local_pdf.AppendLine("<< /Type /Page /Parent 2 0 R /MediaBox [0 0 " +
this.PRIVATE_STRING_FormatDouble(___local_page.public_double_Width) + " " +
this.PRIVATE_STRING_FormatDouble(___local_page.public_double_Height) + "] /Contents " +
___local_contentObjNum.ToString() + " 0 R /Resources " +
___local_resourceObjNum.ToString() + " 0 R >>");
___local_pdf.AppendLine("endobj");
// Content stream
string ___local_content = ___local_page.public_string_Content ?? "";
___local_objectOffsets.Add(___local_pdf.Length);
___local_pdf.AppendLine(___local_contentObjNum.ToString() + " 0 obj");
___local_pdf.AppendLine("<< /Length " + ___local_content.Length.ToString() + " >>");
___local_pdf.AppendLine("stream");
___local_pdf.Append(___local_content);
___local_pdf.AppendLine("endstream");
___local_pdf.AppendLine("endobj");
// Resources
___local_objectOffsets.Add(___local_pdf.Length);
___local_pdf.AppendLine(___local_resourceObjNum.ToString() + " 0 obj");
___local_pdf.AppendLine("<< /Font << /F1 << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> >> >>");
___local_pdf.AppendLine("endobj");
}
// XRef table
int ___local_xrefOffset = ___local_pdf.Length;
___local_pdf.AppendLine("xref");
___local_pdf.AppendLine("0 " + (___local_objectOffsets.Count + 1).ToString());
___local_pdf.AppendLine("0000000000 65535 f ");
for (int ___local_i = 0; ___local_i < ___local_objectOffsets.Count; ___local_i++)
{
___local_pdf.AppendLine(___local_objectOffsets[___local_i].ToString("D10") + " 00000 n ");
}
// Trailer
___local_pdf.AppendLine("trailer");
___local_pdf.AppendLine("<< /Size " + (___local_objectOffsets.Count + 1).ToString() + " /Root 1 0 R >>");
___local_pdf.AppendLine("startxref");
___local_pdf.AppendLine(___local_xrefOffset.ToString());
___local_pdf.AppendLine("%%EOF");
System.IO.File.WriteAllText(param_filePath, ___local_pdf.ToString());
}
}
#endregion PDF WRITER CLASS
#region MAIN SCRIPT CLASS
/// <summary>
/// Main Script Class with FULLY QUALIFIED names
/// </summary>
public class Script
{
#region PUBLIC STATIC VARIABLES
public static string PUBLIC_STATIC_STRING_MODEL_PATH = "";
public static string PUBLIC_STATIC_STRING_OUTPUT_PATH = "";
// Transformation planes - FULLY QUALIFIED
public static Tekla.Structures.Model.TransformationPlane PUBLIC_STATIC_TRANSFORMATIONPLANE_GLOBAL = null;
public static Tekla.Structures.Model.TransformationPlane PUBLIC_STATIC_TRANSFORMATIONPLANE_ORIGINAL = null;
public static Tekla.Structures.Geometry3d.Matrix PUBLIC_STATIC_MATRIX_ToGlobal = null;
// Data storage
public static System.Collections.Generic.List<PUBLIC_CLASS_PartSolidData> PUBLIC_STATIC_LIST_AllPartData =
new System.Collections.Generic.List<PUBLIC_CLASS_PartSolidData>();
public static System.Text.StringBuilder PUBLIC_STATIC_STRINGBUILDER_CoordinateReport =
new System.Text.StringBuilder();
// Model reference - FULLY QUALIFIED
public static Tekla.Structures.Model.Model PUBLIC_STATIC_MODEL_CurrentModel = null;
// Progress bar - FULLY QUALIFIED
public static Tekla.Structures.Model.Operations.Operation.ProgressBar PUBLIC_STATIC_PROGRESSBAR =
new Tekla.Structures.Model.Operations.Operation.ProgressBar();
// Counters
public static int PUBLIC_STATIC_INT_TotalBeams = 0;
public static int PUBLIC_STATIC_INT_TotalPolyBeams = 0;
public static int PUBLIC_STATIC_INT_TotalContourPlates = 0;
public static int PUBLIC_STATIC_INT_TotalBooleanParts = 0;
public static int PUBLIC_STATIC_INT_TotalBoltArrays = 0;
public static int PUBLIC_STATIC_INT_TotalOtherParts = 0;
#endregion PUBLIC STATIC VARIABLES
#region MAIN ENTRY POINT
/// <summary>
/// Main entry point - Run method for Tekla Macro
/// </summary>
public static void Run(Tekla.Technology.Akit.IScript akit)
{
try
{
// Initialize model connection - FULLY QUALIFIED
PUBLIC_STATIC_MODEL_CurrentModel = new Tekla.Structures.Model.Model();
if (!PUBLIC_STATIC_MODEL_CurrentModel.GetConnectionStatus())
{
System.Windows.Forms.MessageBox.Show(
"ERROR: Cannot connect to Tekla Structures!\nPlease ensure Tekla is running with a model open.",
"Connection Error",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
return;
}
// Get model info - FULLY QUALIFIED
Tekla.Structures.Model.ModelInfo ___local_modelInfo = PUBLIC_STATIC_MODEL_CurrentModel.GetInfo();
PUBLIC_STATIC_STRING_MODEL_PATH = ___local_modelInfo.ModelPath;
PUBLIC_STATIC_STRING_OUTPUT_PATH = PUBLIC_STATIC_STRING_MODEL_PATH + "\\SOLID_SCANNER_OUTPUT\\";
if (!System.IO.Directory.Exists(PUBLIC_STATIC_STRING_OUTPUT_PATH))
{
System.IO.Directory.CreateDirectory(PUBLIC_STATIC_STRING_OUTPUT_PATH);
}
// ════════════════════════════════════════════════════════════════════════════════
// CRITICAL: PRESERVE AND SET GLOBAL TRANSFORMATION PLANE
// ════════════════════════════════════════════════════════════════════════════════
Tekla.Structures.Model.WorkPlaneHandler ___local_wpHandler =
PUBLIC_STATIC_MODEL_CurrentModel.GetWorkPlaneHandler();
// Preserve original transformation plane
PUBLIC_STATIC_TRANSFORMATIONPLANE_ORIGINAL = ___local_wpHandler.GetCurrentTransformationPlane();
// Create and set GLOBAL transformation plane (empty constructor = global)
PUBLIC_STATIC_TRANSFORMATIONPLANE_GLOBAL = new Tekla.Structures.Model.TransformationPlane();
___local_wpHandler.SetCurrentTransformationPlane(PUBLIC_STATIC_TRANSFORMATIONPLANE_GLOBAL);
// Get transformation matrix to global
PUBLIC_STATIC_MATRIX_ToGlobal = PUBLIC_STATIC_TRANSFORMATIONPLANE_GLOBAL.TransformationMatrixToGlobal;
// Initialize data
PUBLIC_STATIC_LIST_AllPartData.Clear();
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.Clear();
PRIVATE_STATIC_VOID_ResetCounters();
// Initialize report header
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("═══════════════════════════════════════════════════════════════════════════════════════════════════════════");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("TEKLA SOLID SCANNER - COORDINATE REPORT (GLOBAL COORDINATES)");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("═══════════════════════════════════════════════════════════════════════════════════════════════════════════");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("Generated: " + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("Model: " + PUBLIC_STATIC_STRING_MODEL_PATH);
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("═══════════════════════════════════════════════════════════════════════════════════════════════════════════");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("");
// Show start message
System.Windows.Forms.DialogResult ___local_result = System.Windows.Forms.MessageBox.Show(
"TEKLA SOLID SCANNER WITH PDF VIEWS\n" +
"══════════════════════════════════════════\n\n" +
"Model: " + PUBLIC_STATIC_STRING_MODEL_PATH + "\n" +
"Output: " + PUBLIC_STATIC_STRING_OUTPUT_PATH + "\n\n" +
"This will scan:\n" +
"• Beams, PolyBeams, ContourPlates\n" +
"• BooleanParts and other solid objects\n\n" +
"Continue?",
"Solid Scanner",
System.Windows.Forms.MessageBoxButtons.YesNo,
System.Windows.Forms.MessageBoxIcon.Question);
if (___local_result != System.Windows.Forms.DialogResult.Yes)
{
PRIVATE_STATIC_VOID_RestoreOriginalPlane();
return;
}
// ════════════════════════════════════════════════════════════════════════════════
// PHASE 1: SCAN ALL SOLID OBJECTS
// ════════════════════════════════════════════════════════════════════════════════
PRIVATE_STATIC_VOID_ScanAllSolidObjects();
// ════════════════════════════════════════════════════════════════════════════════
// PHASE 2: GENERATE PDF WITH VIEWS
// ════════════════════════════════════════════════════════════════════════════════
PRIVATE_STATIC_VOID_GeneratePdfWithViews();
// ════════════════════════════════════════════════════════════════════════════════
// PHASE 3: SAVE REPORTS
// ════════════════════════════════════════════════════════════════════════════════
PRIVATE_STATIC_VOID_SaveReports();
// Restore original plane
PRIVATE_STATIC_VOID_RestoreOriginalPlane();
// Show completion
System.Windows.Forms.MessageBox.Show(
"SCAN COMPLETE!\n\n" +
"Parts Scanned:\n" +
" Beams: " + PUBLIC_STATIC_INT_TotalBeams.ToString() + "\n" +
" PolyBeams: " + PUBLIC_STATIC_INT_TotalPolyBeams.ToString() + "\n" +
" ContourPlates: " + PUBLIC_STATIC_INT_TotalContourPlates.ToString() + "\n" +
" BooleanParts: " + PUBLIC_STATIC_INT_TotalBooleanParts.ToString() + "\n" +
" Other: " + PUBLIC_STATIC_INT_TotalOtherParts.ToString() + "\n\n" +
"Total Parts: " + PUBLIC_STATIC_LIST_AllPartData.Count.ToString() + "\n\n" +
"Output saved to:\n" + PUBLIC_STATIC_STRING_OUTPUT_PATH,
"Complete",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Information);
}
catch (System.Exception ___local_ex)
{
PUBLIC_STATIC_PROGRESSBAR.Close();
PRIVATE_STATIC_VOID_RestoreOriginalPlane();
System.Windows.Forms.MessageBox.Show(
"CRITICAL ERROR:\n\n" + ___local_ex.Message + "\n\n" + ___local_ex.StackTrace,
"Error",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
}
#endregion MAIN ENTRY POINT
#region SCANNING METHODS
/// <summary>
/// Scan all solid objects in model
/// </summary>
private static void PRIVATE_STATIC_VOID_ScanAllSolidObjects()
{
// Get all model objects - FULLY QUALIFIED
Tekla.Structures.Model.ModelObjectEnumerator ___local_allObjects =
PUBLIC_STATIC_MODEL_CurrentModel.GetModelObjectSelector().GetAllObjects();
// Count total for progress
int ___local_totalCount = 0;
while (___local_allObjects.MoveNext()) ___local_totalCount++;
___local_allObjects.Reset();
// Show progress bar
bool ___local_pbVisible = PUBLIC_STATIC_PROGRESSBAR.Display(100, "Tekla Solid Scanner",
"Scanning solid objects...", "Cancel", " ");
int ___local_processed = 0;
while (___local_allObjects.MoveNext())
{
if (PUBLIC_STATIC_PROGRESSBAR.Canceled())
{
PUBLIC_STATIC_PROGRESSBAR.Close();
System.Windows.Forms.MessageBox.Show("Scan cancelled by user.");
return;
}
___local_processed++;
int ___local_percent = (int)((___local_processed / (double)___local_totalCount) * 100);
Tekla.Structures.Model.ModelObject ___local_obj = ___local_allObjects.Current;
if (___local_obj == null) continue;
string ___local_typeName = ___local_obj.GetType().Name;
PUBLIC_STATIC_PROGRESSBAR.SetProgress("Processing: " + ___local_typeName +
" (" + ___local_processed.ToString() + "/" + ___local_totalCount.ToString() + ")", ___local_percent);
try
{
// Process based on type - FULLY QUALIFIED type checks
if (___local_obj.GetType().ToString() == "Tekla.Structures.Model.Beam")
{
Tekla.Structures.Model.Beam ___local_beam = ___local_obj as Tekla.Structures.Model.Beam;
PRIVATE_STATIC_VOID_ProcessPart(___local_beam, "BEAM");
PUBLIC_STATIC_INT_TotalBeams++;
}
else if (___local_obj.GetType().ToString() == "Tekla.Structures.Model.PolyBeam")
{
Tekla.Structures.Model.PolyBeam ___local_polyBeam = ___local_obj as Tekla.Structures.Model.PolyBeam;
PRIVATE_STATIC_VOID_ProcessPart(___local_polyBeam, "POLYBEAM");
PUBLIC_STATIC_INT_TotalPolyBeams++;
}
else if (___local_obj.GetType().ToString() == "Tekla.Structures.Model.ContourPlate")
{
Tekla.Structures.Model.ContourPlate ___local_contourPlate = ___local_obj as Tekla.Structures.Model.ContourPlate;
PRIVATE_STATIC_VOID_ProcessPart(___local_contourPlate, "CONTOURPLATE");
PUBLIC_STATIC_INT_TotalContourPlates++;
}
else if (___local_obj.GetType().ToString() == "Tekla.Structures.Model.BooleanPart")
{
Tekla.Structures.Model.BooleanPart ___local_boolPart = ___local_obj as Tekla.Structures.Model.BooleanPart;
PRIVATE_STATIC_VOID_ProcessBooleanPart(___local_boolPart);
PUBLIC_STATIC_INT_TotalBooleanParts++;
}
}
catch (System.Exception ___local_ex)
{
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("ERROR processing " + ___local_typeName + ": " + ___local_ex.Message);
}
}
PUBLIC_STATIC_PROGRESSBAR.Close();
}
/// <summary>
/// Process a Part object - FULLY QUALIFIED
/// </summary>
private static void PRIVATE_STATIC_VOID_ProcessPart(Tekla.Structures.Model.Part param_part, string param_partType)
{
if (param_part == null) return;
PUBLIC_CLASS_PartSolidData ___local_partData = new PUBLIC_CLASS_PartSolidData();
___local_partData.public_int_PartId = param_part.Identifier.ID;
___local_partData.public_string_PartGuid = param_part.Identifier.GUID.ToString();
___local_partData.public_string_PartName = param_part.Name;
___local_partData.public_string_PartMark = PRIVATE_STATIC_STRING_GetPartMark(param_part);
___local_partData.public_string_Profile = param_part.Profile.ProfileString;
___local_partData.public_string_Material = param_part.Material.MaterialString;
___local_partData.public_string_PartType = param_partType;
___local_partData.public_CoordinateSystem = param_part.GetCoordinateSystem();
// Get solid - using ISolid for all types including PolyBeam
try
{
Tekla.Structures.Solid.ISolid ___local_solid = param_part.GetSolid();
if (___local_solid != null)
{
PRIVATE_STATIC_VOID_ExtractSolidData(___local_solid, ___local_partData);
}
}
catch (System.Exception ___local_ex)
{
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine(" ERROR getting solid for " + param_partType +
" " + param_part.Identifier.ID.ToString() + ": " + ___local_ex.Message);
}
// Generate view projections
PRIVATE_STATIC_VOID_GenerateViewProjections(___local_partData);
// Add to report
PRIVATE_STATIC_VOID_AddPartToReport(___local_partData);
PUBLIC_STATIC_LIST_AllPartData.Add(___local_partData);
}
/// <summary>
/// Process BooleanPart - FULLY QUALIFIED
/// </summary>
private static void PRIVATE_STATIC_VOID_ProcessBooleanPart(Tekla.Structures.Model.BooleanPart param_boolPart)
{
if (param_boolPart == null) return;
PUBLIC_CLASS_PartSolidData ___local_partData = new PUBLIC_CLASS_PartSolidData();
___local_partData.public_int_PartId = param_boolPart.Identifier.ID;
___local_partData.public_string_PartGuid = param_boolPart.Identifier.GUID.ToString();
___local_partData.public_string_PartName = "BooleanPart";
___local_partData.public_string_PartMark = "";
___local_partData.public_string_Profile = "";
___local_partData.public_string_Material = "";
___local_partData.public_string_PartType = "BOOLEAN";
// Boolean parts have operative part with solid
Tekla.Structures.Model.Part ___local_operativePart = param_boolPart.OperativePart;
if (___local_operativePart != null)
{
try
{
Tekla.Structures.Solid.ISolid ___local_solid = ___local_operativePart.GetSolid();
if (___local_solid != null)
{
PRIVATE_STATIC_VOID_ExtractSolidData(___local_solid, ___local_partData);
}
}
catch { }
}
PRIVATE_STATIC_VOID_GenerateViewProjections(___local_partData);
PRIVATE_STATIC_VOID_AddPartToReport(___local_partData);
PUBLIC_STATIC_LIST_AllPartData.Add(___local_partData);
}
#endregion SCANNING METHODS
#region SOLID DATA EXTRACTION
/// <summary>
/// Extract solid data - FULLY QUALIFIED with ISolid
/// </summary>
private static void PRIVATE_STATIC_VOID_ExtractSolidData(Tekla.Structures.Solid.ISolid param_solid, PUBLIC_CLASS_PartSolidData param_partData)
{
if (param_solid == null) return;
// Get bounding box
param_partData.public_Point_MinPoint_local = param_solid.MinimumPoint;
param_partData.public_Point_MaxPoint_local = param_solid.MaximumPoint;
param_partData.public_Point_MinPoint_global = PRIVATE_STATIC_POINT_TransformToGlobal(param_solid.MinimumPoint);
param_partData.public_Point_MaxPoint_global = PRIVATE_STATIC_POINT_TransformToGlobal(param_solid.MaximumPoint);
// Extract edges - FULLY QUALIFIED
Tekla.Structures.Solid.EdgeEnumerator ___local_edgeEnum = param_solid.GetEdgeEnumerator();
int ___local_edgeIndex = 0;
while (___local_edgeEnum.MoveNext())
{
Tekla.Structures.Solid.Edge ___local_edge = ___local_edgeEnum.Current as Tekla.Structures.Solid.Edge;
if (___local_edge != null)
{
PUBLIC_CLASS_SolidEdgeData ___local_edgeData = new PUBLIC_CLASS_SolidEdgeData();
___local_edgeData.public_StartPoint_local = ___local_edge.StartPoint;
___local_edgeData.public_EndPoint_local = ___local_edge.EndPoint;
___local_edgeData.public_StartPoint_global = PRIVATE_STATIC_POINT_TransformToGlobal(___local_edge.StartPoint);
___local_edgeData.public_EndPoint_global = PRIVATE_STATIC_POINT_TransformToGlobal(___local_edge.EndPoint);
___local_edgeData.public_string_EdgeType = ___local_edge.Type.ToString();
___local_edgeData.public_int_EdgeIndex = ___local_edgeIndex;
param_partData.public_list_Edges.Add(___local_edgeData);
___local_edgeIndex++;
}
}
// Extract faces - FULLY QUALIFIED
Tekla.Structures.Solid.FaceEnumerator ___local_faceEnum = param_solid.GetFaceEnumerator();
int ___local_faceIndex = 0;
while (___local_faceEnum.MoveNext())
{
Tekla.Structures.Solid.Face ___local_face = ___local_faceEnum.Current as Tekla.Structures.Solid.Face;
if (___local_face != null)
{
PUBLIC_CLASS_SolidFaceData ___local_faceData = new PUBLIC_CLASS_SolidFaceData();
___local_faceData.public_int_FaceIndex = ___local_faceIndex;
___local_faceData.public_Vector_Normal = ___local_face.Normal;
// Get loops - FULLY QUALIFIED
Tekla.Structures.Solid.LoopEnumerator ___local_loopEnum = ___local_face.GetLoopEnumerator();
while (___local_loopEnum.MoveNext())
{
Tekla.Structures.Solid.Loop ___local_loop = ___local_loopEnum.Current as Tekla.Structures.Solid.Loop;
if (___local_loop != null)
{
System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point> ___local_loopPoints =
new System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point>();
System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point> ___local_loopPointsGlobal =
new System.Collections.Generic.List<Tekla.Structures.Geometry3d.Point>();
Tekla.Structures.Solid.VertexEnumerator ___local_vertexEnum = ___local_loop.GetVertexEnumerator();
while (___local_vertexEnum.MoveNext())
{
Tekla.Structures.Geometry3d.Point ___local_pt =
___local_vertexEnum.Current as Tekla.Structures.Geometry3d.Point;
if (___local_pt != null)
{
___local_loopPoints.Add(___local_pt);
___local_loopPointsGlobal.Add(PRIVATE_STATIC_POINT_TransformToGlobal(___local_pt));
}
}
___local_faceData.public_list_of_list_Loops_local.Add(___local_loopPoints);
___local_faceData.public_list_of_list_Loops_global.Add(___local_loopPointsGlobal);
}
}
param_partData.public_list_Faces.Add(___local_faceData);
___local_faceIndex++;
}
}
}
#endregion SOLID DATA EXTRACTION
#region VIEW PROJECTION
/// <summary>
/// Generate view projections from edges
/// </summary>
private static void PRIVATE_STATIC_VOID_GenerateViewProjections(PUBLIC_CLASS_PartSolidData param_partData)
{
if (param_partData == null || param_partData.public_list_Edges.Count == 0) return;
foreach (PUBLIC_CLASS_SolidEdgeData ___local_edge in param_partData.public_list_Edges)
{
// Front View (XZ projection - looking along -Y)
PUBLIC_CLASS_LineData2D ___local_frontLine = new PUBLIC_CLASS_LineData2D();
___local_frontLine.public_double_X1 = ___local_edge.public_StartPoint_global.X;
___local_frontLine.public_double_Y1 = ___local_edge.public_StartPoint_global.Z;
___local_frontLine.public_double_X2 = ___local_edge.public_EndPoint_global.X;
___local_frontLine.public_double_Y2 = ___local_edge.public_EndPoint_global.Z;
___local_frontLine.public_bool_IsHidden = ___local_edge.public_string_EdgeType.Contains("HIDDEN");
param_partData.public_list_FrontViewLines.Add(___local_frontLine);
// Top View (XY projection - looking along -Z)
PUBLIC_CLASS_LineData2D ___local_topLine = new PUBLIC_CLASS_LineData2D();
___local_topLine.public_double_X1 = ___local_edge.public_StartPoint_global.X;
___local_topLine.public_double_Y1 = ___local_edge.public_StartPoint_global.Y;
___local_topLine.public_double_X2 = ___local_edge.public_EndPoint_global.X;
___local_topLine.public_double_Y2 = ___local_edge.public_EndPoint_global.Y;
___local_topLine.public_bool_IsHidden = ___local_edge.public_string_EdgeType.Contains("HIDDEN");
param_partData.public_list_TopViewLines.Add(___local_topLine);
// Side View (YZ projection - looking along -X)
PUBLIC_CLASS_LineData2D ___local_sideLine = new PUBLIC_CLASS_LineData2D();
___local_sideLine.public_double_X1 = ___local_edge.public_StartPoint_global.Y;
___local_sideLine.public_double_Y1 = ___local_edge.public_StartPoint_global.Z;
___local_sideLine.public_double_X2 = ___local_edge.public_EndPoint_global.Y;
___local_sideLine.public_double_Y2 = ___local_edge.public_EndPoint_global.Z;
___local_sideLine.public_bool_IsHidden = ___local_edge.public_string_EdgeType.Contains("HIDDEN");
param_partData.public_list_SideViewLines.Add(___local_sideLine);
}
}
#endregion VIEW PROJECTION
#region PDF GENERATION
/// <summary>
/// Generate PDF with views
/// </summary>
private static void PRIVATE_STATIC_VOID_GeneratePdfWithViews()
{
if (PUBLIC_STATIC_LIST_AllPartData.Count == 0)
{
System.Windows.Forms.MessageBox.Show("No solid parts found to export.");
return;
}
// Show progress
bool ___local_pbVisible = PUBLIC_STATIC_PROGRESSBAR.Display(100, "Generating PDF",
"Creating views...", "Cancel", " ");
PUBLIC_CLASS_PdfWriter ___local_pdf = new PUBLIC_CLASS_PdfWriter();
int ___local_totalPages = PUBLIC_STATIC_LIST_AllPartData.Count;
for (int ___local_i = 0; ___local_i < PUBLIC_STATIC_LIST_AllPartData.Count; ___local_i++)
{
if (PUBLIC_STATIC_PROGRESSBAR.Canceled())
{
PUBLIC_STATIC_PROGRESSBAR.Close();
return;
}
PUBLIC_CLASS_PartSolidData ___local_partData = PUBLIC_STATIC_LIST_AllPartData[___local_i];
int ___local_percent = (int)(((___local_i + 1) / (double)PUBLIC_STATIC_LIST_AllPartData.Count) * 100);
PUBLIC_STATIC_PROGRESSBAR.SetProgress("Drawing part " + (___local_i + 1).ToString() + "/" +
PUBLIC_STATIC_LIST_AllPartData.Count.ToString() + ": " + ___local_partData.public_string_PartName, ___local_percent);
if (___local_i > 0) ___local_pdf.PUBLIC_VOID_NewPage();
PRIVATE_STATIC_VOID_DrawPartPage(___local_pdf, ___local_partData, ___local_i + 1, ___local_totalPages);
}
PUBLIC_STATIC_PROGRESSBAR.Close();
// Save PDF
string ___local_pdfPath = PUBLIC_STATIC_STRING_OUTPUT_PATH + "SOLID_VIEWS_" +
System.DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".pdf";
___local_pdf.PUBLIC_VOID_Save(___local_pdfPath);
}
/// <summary>
/// Draw a single part page
/// </summary>
private static void PRIVATE_STATIC_VOID_DrawPartPage(PUBLIC_CLASS_PdfWriter param_pdf,
PUBLIC_CLASS_PartSolidData param_partData, int param_pageNum, int param_totalPages)
{
double ___local_margin = 30;
double ___local_titleHeight = 50;
double ___local_pageWidth = param_pdf.PUBLIC_DOUBLE_PageWidth;
double ___local_pageHeight = param_pdf.PUBLIC_DOUBLE_PageHeight;
// Draw title block
param_pdf.PUBLIC_VOID_DrawTitleBlock(
"Part: " + param_partData.public_string_PartName + " [" + param_partData.public_string_PartType + "]",
"Mark: " + param_partData.public_string_PartMark + " | Profile: " + param_partData.public_string_Profile,
param_pageNum, param_totalPages);
// Calculate view areas (3 views side by side)
double ___local_viewAreaY = ___local_margin + ___local_titleHeight;
double ___local_viewAreaHeight = ___local_pageHeight - ___local_viewAreaY - ___local_margin;
double ___local_viewAreaWidth = (___local_pageWidth - 4 * ___local_margin) / 3;
// Front View
double ___local_frontViewX = ___local_margin;
PRIVATE_STATIC_VOID_DrawView(param_pdf, param_partData.public_list_FrontViewLines,
___local_frontViewX, ___local_viewAreaY, ___local_viewAreaWidth, ___local_viewAreaHeight,
"FRONT VIEW (XZ)", param_partData);
// Top View
double ___local_topViewX = ___local_margin + ___local_viewAreaWidth + ___local_margin;
PRIVATE_STATIC_VOID_DrawView(param_pdf, param_partData.public_list_TopViewLines,
___local_topViewX, ___local_viewAreaY, ___local_viewAreaWidth, ___local_viewAreaHeight,
"TOP VIEW (XY - PLAN)", param_partData);
// Side View
double ___local_sideViewX = ___local_margin + 2 * (___local_viewAreaWidth + ___local_margin);
PRIVATE_STATIC_VOID_DrawView(param_pdf, param_partData.public_list_SideViewLines,
___local_sideViewX, ___local_viewAreaY, ___local_viewAreaWidth, ___local_viewAreaHeight,
"SIDE VIEW (YZ)", param_partData);
// Part info box at bottom
PRIVATE_STATIC_VOID_DrawPartInfoBox(param_pdf, param_partData, ___local_margin, ___local_margin + 5,
___local_pageWidth - 2 * ___local_margin, 40);
}
/// <summary>
/// Draw a single view
/// </summary>
private static void PRIVATE_STATIC_VOID_DrawView(PUBLIC_CLASS_PdfWriter param_pdf,
System.Collections.Generic.List<PUBLIC_CLASS_LineData2D> param_lines,
double param_x, double param_y, double param_width, double param_height,
string param_title, PUBLIC_CLASS_PartSolidData param_partData)
{
// Draw view border
param_pdf.PUBLIC_VOID_SetColor(0.5, 0.5, 0.5);
param_pdf.PUBLIC_VOID_SetLineWidth(0.5);
param_pdf.PUBLIC_VOID_DrawRect(param_x, param_y, param_width, param_height, false);
// Draw title
param_pdf.PUBLIC_VOID_SetColor(0, 0, 0);
param_pdf.PUBLIC_VOID_DrawCenteredText(param_x + param_width / 2, param_y + param_height - 10, param_title, 10);
if (param_lines == null || param_lines.Count == 0) return;
// Calculate bounding box
PUBLIC_CLASS_BoundingBox2D ___local_bbox = new PUBLIC_CLASS_BoundingBox2D();
foreach (PUBLIC_CLASS_LineData2D ___local_line in param_lines)
{
___local_bbox.PUBLIC_VOID_Expand(___local_line.public_double_X1, ___local_line.public_double_Y1);
___local_bbox.PUBLIC_VOID_Expand(___local_line.public_double_X2, ___local_line.public_double_Y2);
}
if (___local_bbox.public_double_Width < 0.001 || ___local_bbox.public_double_Height < 0.001) return;
// Calculate scale to fit
double ___local_viewMargin = 30;
double ___local_availWidth = param_width - 2 * ___local_viewMargin;
double ___local_availHeight = param_height - 2 * ___local_viewMargin - 20;
double ___local_scaleX = ___local_availWidth / ___local_bbox.public_double_Width;
double ___local_scaleY = ___local_availHeight / ___local_bbox.public_double_Height;
double ___local_scale = System.Math.Min(___local_scaleX, ___local_scaleY) * 0.9;
// Calculate offset to center
double ___local_scaledWidth = ___local_bbox.public_double_Width * ___local_scale;
double ___local_scaledHeight = ___local_bbox.public_double_Height * ___local_scale;
double ___local_offsetX = param_x + ___local_viewMargin + (___local_availWidth - ___local_scaledWidth) / 2;
double ___local_offsetY = param_y + ___local_viewMargin + (___local_availHeight - ___local_scaledHeight) / 2;
// Draw lines
param_pdf.PUBLIC_VOID_SetLineWidth(0.3);
foreach (PUBLIC_CLASS_LineData2D ___local_line in param_lines)
{
if (___local_line.public_bool_IsHidden)
{
param_pdf.PUBLIC_VOID_SetColor(0.6, 0.6, 0.6);
param_pdf.PUBLIC_VOID_SetLineDashed(2, 2);
}
else
{
param_pdf.PUBLIC_VOID_SetColor(0, 0, 0);
param_pdf.PUBLIC_VOID_SetLineSolid();
}
double ___local_x1 = ___local_offsetX + (___local_line.public_double_X1 - ___local_bbox.public_double_MinX) * ___local_scale;
double ___local_y1 = ___local_offsetY + (___local_line.public_double_Y1 - ___local_bbox.public_double_MinY) * ___local_scale;
double ___local_x2 = ___local_offsetX + (___local_line.public_double_X2 - ___local_bbox.public_double_MinX) * ___local_scale;
double ___local_y2 = ___local_offsetY + (___local_line.public_double_Y2 - ___local_bbox.public_double_MinY) * ___local_scale;
param_pdf.PUBLIC_VOID_DrawLine(___local_x1, ___local_y1, ___local_x2, ___local_y2);
}
param_pdf.PUBLIC_VOID_SetLineSolid();
// Draw dimensions
param_pdf.PUBLIC_VOID_SetColor(0, 0, 0.8);
param_pdf.PUBLIC_VOID_SetLineWidth(0.2);
// Horizontal dimension
double ___local_dimX1 = ___local_offsetX;
double ___local_dimX2 = ___local_offsetX + ___local_bbox.public_double_Width * ___local_scale;
double ___local_dimY = param_y + 15;
param_pdf.PUBLIC_VOID_DrawHorizontalDimension(___local_dimX1, ___local_dimX2, ___local_dimY + 10, ___local_dimY,
___local_bbox.public_double_Width.ToString("F0") + " mm", 6);
// Vertical dimension
double ___local_dimX = ___local_offsetX - 10;
double ___local_dimY1 = ___local_offsetY;
double ___local_dimY2 = ___local_offsetY + ___local_bbox.public_double_Height * ___local_scale;
param_pdf.PUBLIC_VOID_DrawVerticalDimension(___local_dimX + 20, ___local_dimY1, ___local_dimY2, ___local_dimX,
___local_bbox.public_double_Height.ToString("F0") + " mm", 6);
// Draw part mark
if (!System.String.IsNullOrEmpty(param_partData.public_string_PartMark))
{
param_pdf.PUBLIC_VOID_SetColor(1, 0, 0);
param_pdf.PUBLIC_VOID_DrawCenteredText(param_x + param_width / 2, param_y + param_height / 2,
param_partData.public_string_PartMark, 14);
}
}
/// <summary>
/// Draw part info box
/// </summary>
private static void PRIVATE_STATIC_VOID_DrawPartInfoBox(PUBLIC_CLASS_PdfWriter param_pdf,
PUBLIC_CLASS_PartSolidData param_partData, double param_x, double param_y, double param_width, double param_height)
{
param_pdf.PUBLIC_VOID_SetColor(0.9, 0.9, 0.9);
param_pdf.PUBLIC_VOID_DrawRect(param_x, param_y, param_width, param_height, true);
param_pdf.PUBLIC_VOID_SetColor(0, 0, 0);
param_pdf.PUBLIC_VOID_SetLineWidth(0.5);
param_pdf.PUBLIC_VOID_DrawRect(param_x, param_y, param_width, param_height, false);
double ___local_textY = param_y + param_height - 10;
double ___local_col1 = param_x + 5;
double ___local_col2 = param_x + param_width * 0.25;
double ___local_col3 = param_x + param_width * 0.5;
double ___local_col4 = param_x + param_width * 0.75;
param_pdf.PUBLIC_VOID_DrawText(___local_col1, ___local_textY, "ID: " + param_partData.public_int_PartId.ToString(), 8, 0);
param_pdf.PUBLIC_VOID_DrawText(___local_col2, ___local_textY, "Mark: " + param_partData.public_string_PartMark, 8, 0);
param_pdf.PUBLIC_VOID_DrawText(___local_col3, ___local_textY, "Profile: " + param_partData.public_string_Profile, 8, 0);
param_pdf.PUBLIC_VOID_DrawText(___local_col4, ___local_textY, "Material: " + param_partData.public_string_Material, 8, 0);
___local_textY = ___local_textY - 12;
param_pdf.PUBLIC_VOID_DrawText(___local_col1, ___local_textY, "Type: " + param_partData.public_string_PartType, 8, 0);
param_pdf.PUBLIC_VOID_DrawText(___local_col2, ___local_textY, "Edges: " + param_partData.public_list_Edges.Count.ToString(), 8, 0);
param_pdf.PUBLIC_VOID_DrawText(___local_col3, ___local_textY, "Faces: " + param_partData.public_list_Faces.Count.ToString(), 8, 0);
}
#endregion PDF GENERATION
#region REPORT GENERATION
/// <summary>
/// Add part to coordinate report
/// </summary>
private static void PRIVATE_STATIC_VOID_AddPartToReport(PUBLIC_CLASS_PartSolidData param_partData)
{
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("║ PART: " + param_partData.public_string_PartName +
" | TYPE: " + param_partData.public_string_PartType +
" | ID: " + param_partData.public_int_PartId.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("║ Mark: " + param_partData.public_string_PartMark +
" | Profile: " + param_partData.public_string_Profile +
" | Material: " + param_partData.public_string_Material);
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╣");
if (param_partData.public_Point_MinPoint_global != null && param_partData.public_Point_MaxPoint_global != null)
{
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("║ BOUNDING BOX (Global):");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("║ Min: X=" +
param_partData.public_Point_MinPoint_global.X.ToString("F3") + ", Y=" +
param_partData.public_Point_MinPoint_global.Y.ToString("F3") + ", Z=" +
param_partData.public_Point_MinPoint_global.Z.ToString("F3"));
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("║ Max: X=" +
param_partData.public_Point_MaxPoint_global.X.ToString("F3") + ", Y=" +
param_partData.public_Point_MaxPoint_global.Y.ToString("F3") + ", Z=" +
param_partData.public_Point_MaxPoint_global.Z.ToString("F3"));
}
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("║ EDGES: " +
param_partData.public_list_Edges.Count.ToString() + " FACES: " +
param_partData.public_list_Faces.Count.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╝");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("");
}
/// <summary>
/// Save reports to files
/// </summary>
private static void PRIVATE_STATIC_VOID_SaveReports()
{
// Add summary
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("═══════════════════════════════════════════════════════════════════════════════════════════════════════════");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("SUMMARY");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("═══════════════════════════════════════════════════════════════════════════════════════════════════════════");
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("Total Beams: " + PUBLIC_STATIC_INT_TotalBeams.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("Total PolyBeams: " + PUBLIC_STATIC_INT_TotalPolyBeams.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("Total ContourPlates: " + PUBLIC_STATIC_INT_TotalContourPlates.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("Total BooleanParts: " + PUBLIC_STATIC_INT_TotalBooleanParts.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("Total Other: " + PUBLIC_STATIC_INT_TotalOtherParts.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("TOTAL PARTS: " + PUBLIC_STATIC_LIST_AllPartData.Count.ToString());
PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.AppendLine("═══════════════════════════════════════════════════════════════════════════════════════════════════════════");
// Save coordinate report
string ___local_coordPath = PUBLIC_STATIC_STRING_OUTPUT_PATH + "COORDINATE_REPORT_" +
System.DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".txt";
System.IO.File.WriteAllText(___local_coordPath, PUBLIC_STATIC_STRINGBUILDER_CoordinateReport.ToString());
// Save CSV report
PRIVATE_STATIC_VOID_SaveCsvReport();
}
/// <summary>
/// Save CSV report
/// </summary>
private static void PRIVATE_STATIC_VOID_SaveCsvReport()
{
System.Text.StringBuilder ___local_csv = new System.Text.StringBuilder();
// Header
___local_csv.AppendLine("PART_ID,PART_GUID,PART_NAME,PART_MARK,PROFILE,MATERIAL,PART_TYPE,MIN_X,MIN_Y,MIN_Z,MAX_X,MAX_Y,MAX_Z,EDGE_COUNT,FACE_COUNT");
foreach (PUBLIC_CLASS_PartSolidData ___local_part in PUBLIC_STATIC_LIST_AllPartData)
{
string ___local_minX = ___local_part.public_Point_MinPoint_global != null ?
___local_part.public_Point_MinPoint_global.X.ToString("F3") : "";
string ___local_minY = ___local_part.public_Point_MinPoint_global != null ?
___local_part.public_Point_MinPoint_global.Y.ToString("F3") : "";
string ___local_minZ = ___local_part.public_Point_MinPoint_global != null ?
___local_part.public_Point_MinPoint_global.Z.ToString("F3") : "";
string ___local_maxX = ___local_part.public_Point_MaxPoint_global != null ?
___local_part.public_Point_MaxPoint_global.X.ToString("F3") : "";
string ___local_maxY = ___local_part.public_Point_MaxPoint_global != null ?
___local_part.public_Point_MaxPoint_global.Y.ToString("F3") : "";
string ___local_maxZ = ___local_part.public_Point_MaxPoint_global != null ?
___local_part.public_Point_MaxPoint_global.Z.ToString("F3") : "";
___local_csv.AppendLine(
___local_part.public_int_PartId.ToString() + "," +
___local_part.public_string_PartGuid + "," +
"\"" + ___local_part.public_string_PartName + "\"," +
"\"" + ___local_part.public_string_PartMark + "\"," +
"\"" + ___local_part.public_string_Profile + "\"," +
"\"" + ___local_part.public_string_Material + "\"," +
___local_part.public_string_PartType + "," +
___local_minX + "," + ___local_minY + "," + ___local_minZ + "," +
___local_maxX + "," + ___local_maxY + "," + ___local_maxZ + "," +
___local_part.public_list_Edges.Count.ToString() + "," +
___local_part.public_list_Faces.Count.ToString());
}
string ___local_csvPath = PUBLIC_STATIC_STRING_OUTPUT_PATH + "PARTS_DATA_" +
System.DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".csv";
System.IO.File.WriteAllText(___local_csvPath, ___local_csv.ToString());
}
#endregion REPORT GENERATION
#region HELPER METHODS
/// <summary>
/// Transform point to global coordinates
/// </summary>
private static Tekla.Structures.Geometry3d.Point PRIVATE_STATIC_POINT_TransformToGlobal(
Tekla.Structures.Geometry3d.Point param_localPoint)
{
if (param_localPoint == null) return null;
if (PUBLIC_STATIC_MATRIX_ToGlobal != null)
{
return PUBLIC_STATIC_MATRIX_ToGlobal.Transform(param_localPoint);
}
return new Tekla.Structures.Geometry3d.Point(param_localPoint.X, param_localPoint.Y, param_localPoint.Z);
}
/// <summary>
/// Get part mark
/// </summary>
private static string PRIVATE_STATIC_STRING_GetPartMark(Tekla.Structures.Model.Part param_part)
{
try
{
return param_part.GetPartMark();
}
catch
{
return "";
}
}
/// <summary>
/// Reset counters
/// </summary>
private static void PRIVATE_STATIC_VOID_ResetCounters()
{
PUBLIC_STATIC_INT_TotalBeams = 0;
PUBLIC_STATIC_INT_TotalPolyBeams = 0;
PUBLIC_STATIC_INT_TotalContourPlates = 0;
PUBLIC_STATIC_INT_TotalBooleanParts = 0;
PUBLIC_STATIC_INT_TotalBoltArrays = 0;
PUBLIC_STATIC_INT_TotalOtherParts = 0;
}
/// <summary>
/// Restore original transformation plane
/// </summary>
private static void PRIVATE_STATIC_VOID_RestoreOriginalPlane()
{
try
{
if (PUBLIC_STATIC_TRANSFORMATIONPLANE_ORIGINAL != null && PUBLIC_STATIC_MODEL_CurrentModel != null)
{
PUBLIC_STATIC_MODEL_CurrentModel.GetWorkPlaneHandler()
.SetCurrentTransformationPlane(PUBLIC_STATIC_TRANSFORMATIONPLANE_ORIGINAL);
}
}
catch { }
}
#endregion HELPER METHODS
}
#endregion MAIN SCRIPT CLASS
}
Comments
Post a Comment