{ "cells": [ { "cell_type": "markdown", "id": "f8ee4fe2", "metadata": {}, "source": [ "# Polyline creation\n", "\n", "This example shows how to use PyAEDT to create and manipulate polylines.\n", "\n", "Keywords: **AEDT**, **modeler**, **polyline**." ] }, { "cell_type": "markdown", "id": "b833f612", "metadata": {}, "source": [ "## Import packages and define constants\n", "Import the required packages." ] }, { "cell_type": "code", "execution_count": null, "id": "2ec6b50d", "metadata": {}, "outputs": [], "source": [ "import os\n", "import tempfile\n", "import time" ] }, { "cell_type": "code", "execution_count": null, "id": "ce7fea45", "metadata": {}, "outputs": [], "source": [ "import ansys.aedt.core" ] }, { "cell_type": "markdown", "id": "827ccc25", "metadata": {}, "source": [ "Define constants" ] }, { "cell_type": "code", "execution_count": null, "id": "992f7d79", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "AEDT_VERSION = \"2024.2\"\n", "NG_MODE = False # Open AEDT UI when it is launched." ] }, { "cell_type": "markdown", "id": "0ea26de8", "metadata": {}, "source": [ "## Create temporary directory\n", "\n", "Create a temporary directory where downloaded data or\n", "dumped data can be stored.\n", "If you'd like to retrieve the project data for subsequent use,\n", "the temporary folder name is given by ``temp_folder.name``." ] }, { "cell_type": "code", "execution_count": null, "id": "21cdbd0b", "metadata": {}, "outputs": [], "source": [ "temp_folder = tempfile.TemporaryDirectory(suffix=\".ansys\")" ] }, { "cell_type": "markdown", "id": "0b4b29cf", "metadata": {}, "source": [ "## Create Maxwell 3D object\n", "\n", "Create a `Maxwell3d` object and set the unit type to ``\"mm\"``." ] }, { "cell_type": "code", "execution_count": null, "id": "10e6ec20", "metadata": {}, "outputs": [], "source": [ "project_name = os.path.join(temp_folder.name, \"polyline.aedt\")\n", "maxwell = ansys.aedt.core.Maxwell3d(\n", " project=project_name,\n", " solution_type=\"Transient\",\n", " design=\"test_polyline_3D\",\n", " version=AEDT_VERSION,\n", " new_desktop=True,\n", " non_graphical=NG_MODE,\n", ")\n", "maxwell.modeler.model_units = \"mm\"\n", "modeler = maxwell.modeler" ] }, { "cell_type": "markdown", "id": "2bf3f1ea", "metadata": {}, "source": [ "## Define variables\n", "\n", "Define two design variables as parameters for the polyline objects." ] }, { "cell_type": "code", "execution_count": null, "id": "03964084", "metadata": {}, "outputs": [], "source": [ "maxwell[\"p1\"] = \"100mm\"\n", "maxwell[\"p2\"] = \"71mm\"" ] }, { "cell_type": "markdown", "id": "8cd21db8", "metadata": {}, "source": [ "## Input data\n", "\n", "Input data. All data for the polyline functions can be entered as either floating point\n", "values or strings. Floating point values are assumed to be in model units\n", "(``maxwell.modeler.model_units``)." ] }, { "cell_type": "code", "execution_count": null, "id": "d69bd9d2", "metadata": {}, "outputs": [], "source": [ "test_points = [\n", " [\"0mm\", \"p1\", \"0mm\"],\n", " [\"-p1\", \"0mm\", \"0mm\"],\n", " [\"-p1/2\", \"-p1/2\", \"0mm\"],\n", " [\"0mm\", \"0mm\", \"0mm\"],\n", "]" ] }, { "cell_type": "markdown", "id": "124edaa4", "metadata": {}, "source": [ "## Create polyline primitives\n", "\n", "The following examples are for creating polyline primitives." ] }, { "cell_type": "markdown", "id": "662dfb54", "metadata": {}, "source": [ "### Create line primitive\n", "\n", "Create a line primitive. The basic polyline command takes a list of positions\n", "(``[X, Y, Z]`` coordinates) and creates a polyline object with one or more\n", "segments. The supported segment types are ``Line``, ``Arc`` (3 points),\n", "``AngularArc`` (center-point + angle), and ``Spline``." ] }, { "cell_type": "code", "execution_count": null, "id": "77559b05", "metadata": {}, "outputs": [], "source": [ "line1 = modeler.create_polyline(points=test_points[0:2], name=\"PL01_line\")\n", "print(\"Created Polyline with name: {}\".format(modeler.objects[line1.id].name))\n", "print(\"Segment types : {}\".format([s.type for s in line1.segment_types]))\n", "print(\"primitive id = {}\".format(line1.id))" ] }, { "cell_type": "markdown", "id": "939937b5", "metadata": {}, "source": [ "### Create arc primitive\n", "\n", "Create an arc primitive. The ``position_list`` parameter must contain at\n", "least three position values. The first three position values are used." ] }, { "cell_type": "code", "execution_count": null, "id": "7dc358be", "metadata": {}, "outputs": [], "source": [ "line2 = modeler.create_polyline(\n", " points=test_points[0:3], segment_type=\"Arc\", name=\"PL02_arc\"\n", ")\n", "print(\n", " \"Created object with id {} and name {}.\".format(\n", " line2.id, modeler.objects[line2.id].name\n", " )\n", ")" ] }, { "cell_type": "markdown", "id": "62d801e8", "metadata": {}, "source": [ "### Create spline primitive\n", "\n", "Create a spline primitive. Defining the segment using a ``PolylineSegment``\n", "object allows you to provide additional input parameters for the spine, such\n", "as the number of points (in this case 4). The ``points`` parameter\n", "must contain at least four position values." ] }, { "cell_type": "code", "execution_count": null, "id": "e3c808b6", "metadata": {}, "outputs": [], "source": [ "line3 = modeler.create_polyline(\n", " points=test_points,\n", " segment_type=modeler.polyline_segment(\"Spline\", num_points=4),\n", " name=\"PL03_spline_4pt\",\n", ")" ] }, { "cell_type": "markdown", "id": "bb5e3ca3", "metadata": {}, "source": [ "### Create center-point arc primitive\n", "\n", "Create a center-point arc primitive. A center-point arc segment is defined\n", "by a starting point, a center point, and an angle of rotation around the\n", "center point. The rotation occurs in a plane parallel to the XY, YZ, or ZX\n", "plane of the active coordinate system. The starting point and the center point\n", "must therefore have one coordinate value (X, Y, or Z) with the same value.\n", "\n", "In this first code example, ``start-point`` and ``center-point`` have a common\n", "Z position, ``\"0mm\"``. The curve therefore lies in the XY plane at $ z = 0 $." ] }, { "cell_type": "code", "execution_count": null, "id": "79dabf1e", "metadata": {}, "outputs": [], "source": [ "start_point = [100, 100, 0]\n", "center_point = [0, 0, 0]\n", "line4 = modeler.create_polyline(\n", " points=[start_point],\n", " segment_type=modeler.polyline_segment(\n", " \"AngularArc\", arc_center=center_point, arc_angle=\"30deg\"\n", " ),\n", " name=\"PL04_center_point_arc\",\n", ")" ] }, { "cell_type": "markdown", "id": "42495ffd", "metadata": {}, "source": [ "In this second code example, ``start_point`` and ``center_point`` have the same\n", "values for the Y and Z coordinates, so the plane or rotation could be either XY or ZX.\n", "For these special cases when the rotation plane is ambiguous, you can specify\n", "the plane explicitly." ] }, { "cell_type": "code", "execution_count": null, "id": "c51ea651", "metadata": {}, "outputs": [], "source": [ "start_point = [100, 0, 0]\n", "center_point = [0, 0, 0]\n", "line4_xy = modeler.create_polyline(\n", " points=[start_point],\n", " segment_type=modeler.polyline_segment(\n", " \"AngularArc\", arc_center=center_point, arc_angle=\"30deg\", arc_plane=\"XY\"\n", " ),\n", " name=\"PL04_center_point_arc_rot_XY\",\n", ")\n", "line4_zx = modeler.create_polyline(\n", " points=[start_point],\n", " segment_type=modeler.polyline_segment(\n", " \"AngularArc\", arc_center=center_point, arc_angle=\"30deg\", arc_plane=\"ZX\"\n", " ),\n", " name=\"PL04_center_point_arc_rot_ZX\",\n", ")" ] }, { "cell_type": "markdown", "id": "5110e887", "metadata": {}, "source": [ "## Create compound polylines\n", "\n", "You can pass a list of points to the ``create_polyline()`` method to create a multi-segment\n", "polyline.\n", "\n", "If the type of segment is not specified, all points\n", "are connected by straight line segments." ] }, { "cell_type": "code", "execution_count": null, "id": "de2532d4", "metadata": {}, "outputs": [], "source": [ "line6 = modeler.create_polyline(points=test_points, name=\"PL06_segmented_compound_line\")" ] }, { "cell_type": "markdown", "id": "66ff39c1", "metadata": {}, "source": [ "You can specify the segment type as an optional named argument to\n", "define the segment type used to connect the points." ] }, { "cell_type": "code", "execution_count": null, "id": "990fdf1a", "metadata": {}, "outputs": [], "source": [ "line5 = modeler.create_polyline(\n", " points=test_points, segment_type=[\"Line\", \"Arc\"], name=\"PL05_compound_line_arc\"\n", ")" ] }, { "cell_type": "markdown", "id": "2c00523a", "metadata": {}, "source": [ "Setting the named argument ``close_surface=True`` ensures\n", "that the polyline starting point and\n", "ending point are the same. You can also explicitly close the\n", "polyline by setting the last point equal\n", "to the first point in the list of points." ] }, { "cell_type": "code", "execution_count": null, "id": "2dc5afd4", "metadata": {}, "outputs": [], "source": [ "line7 = modeler.create_polyline(\n", " points=test_points, close_surface=True, name=\"PL07_segmented_compound_line_closed\"\n", ")" ] }, { "cell_type": "markdown", "id": "7774f73a", "metadata": {}, "source": [ "Setting the named argument ``cover_surface=True`` also\n", "covers the polyline and creates a sheet object." ] }, { "cell_type": "code", "execution_count": null, "id": "13fb004b", "metadata": {}, "outputs": [], "source": [ "line_cover = modeler.create_polyline(\n", " points=test_points, cover_surface=True, name=\"SPL01_segmented_compound_line\"\n", ")" ] }, { "cell_type": "markdown", "id": "a9d00886", "metadata": {}, "source": [ "## Insert compound lines\n", "\n", "The following examples are for inserting compound lines.\n", "\n", "### Insert line segment\n", "\n", "Insert a line segment starting at vertex 1 ``[\"100mm\", \"0mm\", \"0mm\"]``\n", "of an existing polyline and ending at some new point ``[\"90mm\", \"20mm\", \"0mm\"].``\n", "By numerical comparison of the starting point with the existing vertices of the\n", "original polyline object, it is determined automatically that the segment is\n", "inserted after the first segment of the original polyline." ] }, { "cell_type": "code", "execution_count": null, "id": "7ca2f6ca", "metadata": {}, "outputs": [], "source": [ "line8_segment = modeler.create_polyline(\n", " points=test_points,\n", " close_surface=True,\n", " name=\"PL08_segmented_compound_insert_segment\",\n", ")\n", "points_line8_segment = line8_segment.points[1]\n", "insert_point = [\"-100mm\", \"20mm\", \"0mm\"]\n", "line8_segment.insert_segment(points=[insert_point, points_line8_segment])" ] }, { "cell_type": "markdown", "id": "91adce14", "metadata": {}, "source": [ "### Insert compound line with insert curve\n", "\n", "Insert a compound line starting a line segment at vertex 1 ``[\"100mm\", \"0mm\", \"0mm\"]``\n", "of an existing polyline and ending at some new point ``[\"90mm\", \"20mm\", \"0mm\"]``.\n", "By numerical comparison of the starting point, it is determined automatically\n", "that the segment is inserted after the first segment of the original polyline." ] }, { "cell_type": "code", "execution_count": null, "id": "db615641", "metadata": {}, "outputs": [], "source": [ "line8_segment_arc = modeler.create_polyline(\n", " points=test_points, close_surface=False, name=\"PL08_segmented_compound_insert_arc\"\n", ")\n", "\n", "start_point = line8_segment_arc.vertex_positions[1]\n", "insert_point1 = [\"90mm\", \"20mm\", \"0mm\"]\n", "insert_point2 = [40, 40, 0]\n", "\n", "line8_segment_arc.insert_segment(\n", " points=[start_point, insert_point1, insert_point2], segment=\"Arc\"\n", ")" ] }, { "cell_type": "markdown", "id": "e738ca59", "metadata": {}, "source": [ "### Insert compound line at end of a center-point arc\n", "\n", "Insert a compound line at the end of a center-point arc (``type=\"AngularArc\"``).\n", "This is a special case.\n", "\n", "Step 1: Draw a center-point arc." ] }, { "cell_type": "code", "execution_count": null, "id": "6c282357", "metadata": {}, "outputs": [], "source": [ "start_point = [2200.0, 0.0, 1200.0]\n", "arc_center_1 = [1400, 0, 800]\n", "arc_angle_1 = \"43.47deg\"\n", "\n", "line_arc = modeler.create_polyline(\n", " name=\"First_Arc\",\n", " points=[start_point],\n", " segment_type=modeler.polyline_segment(\n", " type=\"AngularArc\", arc_angle=arc_angle_1, arc_center=arc_center_1\n", " ),\n", ")" ] }, { "cell_type": "markdown", "id": "080b12d8", "metadata": {}, "source": [ "Step 2: Insert a line segment at the end of the arc with a specified end point." ] }, { "cell_type": "code", "execution_count": null, "id": "947fc2b3", "metadata": {}, "outputs": [], "source": [ "start_of_line_segment = line_arc.end_point\n", "end_of_line_segment = [3600, 200, 30]\n", "line_arc.insert_segment(points=[start_of_line_segment, end_of_line_segment])" ] }, { "cell_type": "markdown", "id": "64f98f29", "metadata": {}, "source": [ "Step 3: Append a center-point arc segment to the line object." ] }, { "cell_type": "code", "execution_count": null, "id": "5ad1ee02", "metadata": {}, "outputs": [], "source": [ "arc_angle_2 = \"39.716deg\"\n", "arc_center_2 = [3400, 200, 3800]\n", "line_arc.insert_segment(\n", " points=[end_of_line_segment],\n", " segment=modeler.polyline_segment(\n", " type=\"AngularArc\", arc_center=arc_center_2, arc_angle=arc_angle_2\n", " ),\n", ")" ] }, { "cell_type": "markdown", "id": "2bc0bf31", "metadata": {}, "source": [ "You can use the compound polyline definition to complete all three steps in\n", "a single step." ] }, { "cell_type": "code", "execution_count": null, "id": "9cbf0f73", "metadata": {}, "outputs": [], "source": [ "modeler.create_polyline(\n", " points=[start_point, end_of_line_segment],\n", " segment_type=[\n", " modeler.polyline_segment(\n", " type=\"AngularArc\", arc_angle=\"43.47deg\", arc_center=arc_center_1\n", " ),\n", " modeler.polyline_segment(type=\"Line\"),\n", " modeler.polyline_segment(\n", " type=\"AngularArc\", arc_angle=arc_angle_2, arc_center=arc_center_2\n", " ),\n", " ],\n", " name=\"Compound_Polyline_One_Command\",\n", ")" ] }, { "cell_type": "markdown", "id": "89dc45b3", "metadata": {}, "source": [ "## Insert two 3-point arcs forming a circle\n", "\n", "Insert two 3-point arcs forming a circle.\n", "Note that the last point of the second arc segment is not defined in\n", "the position list." ] }, { "cell_type": "code", "execution_count": null, "id": "3532fe80", "metadata": {}, "outputs": [], "source": [ "line_three_points = modeler.create_polyline(\n", " points=[\n", " [34.1004, 14.1248, 0],\n", " [27.646, 16.7984, 0],\n", " [24.9725, 10.3439, 0],\n", " [31.4269, 7.6704, 0],\n", " ],\n", " segment_type=[\"Arc\", \"Arc\"],\n", " cover_surface=True,\n", " close_surface=True,\n", " name=\"line_covered\",\n", " material=\"vacuum\",\n", ")" ] }, { "cell_type": "markdown", "id": "ee2eb89e", "metadata": {}, "source": [ "Here is an example of a complex polyline where the number of points is\n", "insufficient to populate the requested segments. This results in an\n", "``IndexError`` that PyAEDT catches silently. The return value of the command\n", "is ``False``, which can be caught at the app level. While this example might\n", "not be so useful in a Jupyter Notebook, it is important for unit tests." ] }, { "cell_type": "code", "execution_count": null, "id": "aacbd097", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "line_points = [\n", " [\"67.1332mm\", \"2.9901mm\", \"0mm\"],\n", " [\"65.9357mm\", \"2.9116mm\", \"0mm\"],\n", " [\"65.9839mm\", \"1.4562mm\", \"0mm\"],\n", " [\"66mm\", \"0mm\", \"0mm\"],\n", " [\"99mm\", \"0mm\", \"0mm\"],\n", " [\"98.788mm\", \"6.4749mm\", \"0mm\"],\n", " [\"98.153mm\", \"12.9221mm\", \"0mm\"],\n", " [\"97.0977mm\", \"19.3139mm\", \"0mm\"],\n", "]" ] }, { "cell_type": "code", "execution_count": null, "id": "73163cde", "metadata": {}, "outputs": [], "source": [ "line_segments = [\"Line\", \"Arc\", \"Line\", \"Arc\", \"Line\"]\n", "line_complex1 = modeler.create_polyline(\n", " points=line_points, segment_type=line_segments, name=\"Polyline_example\"\n", ")" ] }, { "cell_type": "markdown", "id": "be8fb05a", "metadata": {}, "source": [ "Here is an example that provides more points than the segment list requires.\n", "This is valid usage. The remaining points are ignored." ] }, { "cell_type": "code", "execution_count": null, "id": "0793a7bc", "metadata": {}, "outputs": [], "source": [ "line_segments = [\"Line\", \"Arc\", \"Line\", \"Arc\"]\n", "line_complex2 = modeler.create_polyline(\n", " line_points, segment_type=line_segments, name=\"Polyline_example2\"\n", ")" ] }, { "cell_type": "markdown", "id": "77865666", "metadata": {}, "source": [ "## Save project\n", "\n", "Save the project." ] }, { "cell_type": "code", "execution_count": null, "id": "78d2e5ea", "metadata": {}, "outputs": [], "source": [ "maxwell.save_project()\n", "maxwell.release_desktop()\n", "time.sleep(3) # Allow AEDT to shut down before cleaning the temporary project folder." ] }, { "cell_type": "markdown", "id": "e25ca1a2", "metadata": {}, "source": [ "## Clean up\n", "\n", "All project files are saved in the folder ``temp_folder.name``.\n", "If you've run this example as a Jupyter notebook, you\n", "can retrieve those project files. The following cell removes\n", "all temporary files, including the project folder." ] }, { "cell_type": "code", "execution_count": null, "id": "4f69f2df", "metadata": {}, "outputs": [], "source": [ "temp_folder.cleanup()" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" } }, "nbformat": 4, "nbformat_minor": 5 }