Target: GX-TXT 0.9.8.10-dev-031
Surface: Python Script Workspace / registered Python Script workflow
Runner: analysis.python_script
Example: fit a point curve, generate a closed profile, extrude it, triangulate it, and publish the result as a geometry.mesh Dataset
Level: beginner-to-intermediate
We start from a 2D curve stored as discrete points and build a complete GX-TXT scientific workflow:
2D point Dataset
↓
Python Script Workspace
↓
Canonical Dataset API
↓
NUMERIC_API_v1 least-squares fit
↓
dense fitted 2D profile
↓
Dataset Publication API v2
↓
mirror profile into closed section
↓
extrude along Z
↓
triangle mesh
↓
VTP PolyData
↓
Dataset File Publication API
↓
geometry.mesh Dataset
↓
Native 3D
The example is deliberately simple enough that every geometry step can be understood.
The supplied:
profile_curve_points.csv
contains:
x_mm
half_height_mm
The points describe the upper half of a symmetric section.
The script assumes:
upper boundary = +h(x)
lower boundary = -h(x)
This is an explicit modeling assumption.
Define:
[ u=\frac{x-x_{\min}}{x_{\max}-x_{\min}} ]
and fit:
[ h(u)=u(1-u) \left( a_0+a_1u+a_2u^2+a_3u^3 \right) ]
The factor:
[ u(1-u) ]
forces:
[ h(0)=h(1)=0 ]
which gives a naturally closed front and rear point after mirroring.
The coefficient problem is linear least squares:
[ A\mathbf{a}\approx\mathbf{h} ]
and is solved through:
NUMERIC_API_v1
→ linear_matrix
→ solve
Python defines the scientific basis matrix.
GX-TXT's public numeric provider performs the numerical linear algebra.
The same provider is then used again to evaluate the fitted profile using:
linear_matrix / multiply
This is a useful division of responsibility:
Python script
→ scientific model and topology
NUMERIC_API
→ reusable numerical operations
The bundle contains:
profile_curve_points.csv
profile_curve_to_extruded_mesh.py
reference_extruded_profile_mesh.vtp
The reference VTP is only an example of the expected geometry format. The script generates its own fresh mesh in the GX-TXT run directory.
Import:
profile_curve_points.csv
as a normal table Dataset.
A convenient ID is:
profile_curve_points
Verify that the two columns are numeric.
Create/import:
profile_curve_to_extruded_mesh.py
through the Python Script Workspace / Script Library workflow.
Suggested script ID:
tutorial.profile_to_mesh
Assign it to the current Session and select it in:
Analysis → Python Script
Set the primary Analysis Source to the imported curve Dataset.
Declare:
CANONICAL_DATASET_API_v2@2;
DATASET_VARIABLE_SCHEMA_API_v3@3;
NUMERIC_API_v1@1:math.numeric+complex_linear_algebra;
DATASET_PUBLICATION_API_v2@2;
DATASET_FILE_PUBLICATION_API_v1@1;
SESSION_PERSISTENCE_API_v1@1
These are also checked in the script with:
gxtxt_api_require(...)
The script gets:
ctx = gxtxt_context()
source_id = ctx["inputs"]["primary"]["dataset_id"]
It resolves stable Variable IDs with:
DATASET_VARIABLE_SCHEMA_API_v3
and reads data with:
CANONICAL_DATASET_API_v2 / read_range
It never reopens the original CSV.
The tutorial requires:
at least 6 finite points
strictly increasing X after sorting
non-negative half-height
positive X span
If the scientific input is invalid, the script stops before fitting or mesh generation.
linear_matrix / solveThe basis matrix contains four columns.
The script calls:
fit = gxtxt_api_call(
"NUMERIC_API_v1",
"linear_matrix",
[
"solve",
{"real": design},
{"real": rhs},
{"rank_policy": "error"},
],
)
For a full-rank overdetermined matrix, this is least squares.
Inspect:
residual_norm
rank
condition_number
Do not treat coefficients as trustworthy if the system is badly conditioned.
The script samples 81 X positions and evaluates the fitted model with:
NUMERIC_API_v1 / linear_matrix / multiply
The fitted half-height is then constrained to the physical domain:
h >= 0
with exact zero at the endpoints.
The script publishes:
tutorial.python.fitted_profile
as a structured:
table.generic
Dataset using:
DATASET_PUBLICATION_API_v2
Variables:
v_x
v_half_height
This intermediate Dataset gives the mesh explicit scientific provenance.
The upper ring is:
(x, +h)
The lower ring is:
(x, -h)
traversed in reverse.
The endpoints are not duplicated.
With 81 half-profile samples the closed ring contains:
160 vertices
The tutorial uses:
extrusion_depth = 12 mm
Two copies of the ring are created at:
Z = -6 mm
Z = +6 mm
This gives front and back section rings.
Each corresponding pair of ring edges forms a quad.
Each quad becomes two triangles.
This produces the extruded side wall.
The tutorial adds one center vertex to each end and creates fan triangles.
This is valid for the simple convex-like profile used here.
It is not a general polygon triangulation algorithm.
Concave or self-intersecting profiles require a robust triangulator.
With the supplied settings:
half-profile samples = 81
closed ring vertices = 160
mesh vertices = 322
mesh triangles = 640
The extra two vertices are the front/back cap centers.
GX-TXT already has a standard mesh contract:
geometry.mesh
and Native 3D understands:
VTK XML PolyData (.vtp)
Therefore the script writes a standards-based VTP rather than inventing a private CSV topology format.
Once:
extruded_profile_mesh.vtp
is complete inside the framework-owned script output directory, the script calls:
DATASET_FILE_PUBLICATION_API_v1 / publish
with:
dataset_id = tutorial.python.extruded_profile_mesh
contract = geometry.mesh
format = vtp
media_type = application/vnd.vtk
GX-TXT computes the authoritative SHA-256 and commits the Dataset Registry entry.
The tutorial publishes two different scientific products.
Structured numeric variables:
v_x
v_half_height
Use:
DATASET_PUBLICATION_API_v2
Already a complete standards-based VTP geometry object.
Use:
DATASET_FILE_PUBLICATION_API_v1
Do not flatten the mesh into an artificial CSV just to use the table writer.
The mesh Dataset records lineage back to:
original point Dataset
fitted profile Dataset
and stores structured metadata such as:
geometry.kind
geometry.vertex_count
geometry.triangle_count
geometry.extrusion_depth
geometry.coordinate_unit
The script calls:
gxtxt_api_call(
"SESSION_PERSISTENCE_API_v1",
"commit",
[],
)
The script never edits:
metadata/datasets.ini
manifest.ini
directly.
Expected log content includes:
Profile coefficients: ...
Fit residual norm: ...
Design condition number: ...
Published fitted profile Dataset: tutorial.python.fitted_profile
Mesh: vertices=322 triangles=640 depth=12
Published 3D mesh Dataset: tutorial.python.extruded_profile_mesh
PASS PROFILE_MESH_TUTORIAL ...
Look for:
tutorial.python.fitted_profile
This is the dense 2D profile used for geometry generation.
Look for:
tutorial.python.extruded_profile_mesh
Contract:
geometry.mesh
Format:
vtp
The mesh is intentionally an opaque geometry payload rather than a fake table of triangle columns.
Open Native 3D and select:
tutorial.python.extruded_profile_mesh
The shared viewer can read the VTP mesh directly.
No custom Python renderer is required.
Python/NumPy handles:
sorting
coordinate normalization
basis construction
profile mirroring
extrusion
triangle indexing
VTP serialization
This is appropriate domain logic.
GX-TXT APIs handle:
Dataset identity
Variable identity
scientific input read
least-squares numerical solve
matrix evaluation
structured Dataset publication
mesh Dataset registration
SHA-256
provenance
Session persistence
Use the framework where it owns a reusable scientific or persistence service.
Do not route trivial Python list operations through an API only for appearances.
This is an extrusion, not a CAD kernel.
It does not support:
lofting
sweeps along curved paths
twist
holes
multiple contour loops
booleans
B-rep topology
automatic remeshing
adaptive curvature refinement
The basis forces zero thickness at both endpoints.
That is a deliberate model assumption.
For a profile with non-zero end thickness, choose a different basis.
A center fan is not valid for arbitrary concave polygons.
For a production general-profile tool, use a robust polygon triangulation method.
The example input is in millimetres.
The generated mesh coordinates remain in millimetres.
The script records the coordinate unit in Dataset metadata.
VTP itself does not automatically convert your coordinates to SI.
Edit:
extrusion_depth = 12.0
for example:
extrusion_depth = 25.0
Rerun.
The same stable mesh Dataset is replaced through the public transaction.
Change:
profile_samples = 81
to:
profile_samples = 161
The fitted mathematical profile remains conceptually the same, but the geometric discretization becomes denser.
The current basis contains four terms.
Try removing or adding a term and compare:
residual_norm
condition_number
visual smoothness
Do not increase polynomial complexity blindly.
Wrong:
np.loadtxt("/path/profile_curve_points.csv")
Correct:
Dataset ID
→ Canonical Dataset API
For a geometry intended for Native 3D, use the existing:
geometry.mesh
contract and a supported geometry format such as VTP.
Do not invent a new topology convention unless the framework genuinely needs one.
A successful call is not proof that the chosen basis is good.
Inspect:
rank
condition_number
residual_norm
before trusting the geometry.
This tutorial constructs a symmetric profile.
An asymmetric section needs upper and lower curves independently.
It is not.
Use it only for a suitable simple section.
A useful second exercise is to add a scientific point scalar to the VTP mesh.
For example:
normalized X coordinate
local half-height
temperature
material index
Then Native 3D can use the scalar for colormapping.
Turn the workflow into a dedicated GX-TXT module when you need:
GUI parameters for fit order
GUI extrusion depth
unit validation
asymmetric profiles
mesh-quality controls
multiple section inputs
repeatable production geometry
formal output contracts
automatic Viewer scenes
The Script Workspace is the right place to establish and test the scientific method first.
The workflow is:
measured Dataset
↓
stable Variable IDs
↓
public numeric service
↓
scientific fitted profile
↓
canonical structured Dataset
↓
Python geometry algorithm
↓
standard VTP mesh
↓
canonical geometry.mesh Dataset
↓
Native 3D
The key principle is:
Let GX-TXT own Dataset identity, numerical service boundaries, publication, provenance and persistence. Let Python own the domain-specific geometry algorithm.