Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
427 changes: 356 additions & 71 deletions src/pages/docs/api/cdl-parser.astro

Large diffs are not rendered by default.

272 changes: 147 additions & 125 deletions src/pages/docs/api/crystal-geometry.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ import { Container } from '../../../components/ui-astro';

const geometryAttrs = [
{ name: 'vertices', type: 'np.ndarray', description: 'Nx3 array of vertex coordinates' },
{ name: 'faces', type: 'list[Face]', description: 'List of Face objects' },
{ name: 'normals', type: 'np.ndarray', description: 'Nx3 array of face normals' },
{ name: 'face_miller_indices', type: 'list[MillerIndex]', description: 'Miller indices for each face' },
{ name: 'center', type: 'tuple[float, float, float]', description: 'Centroid of the geometry' },
{ name: 'bounds', type: 'tuple[tuple, tuple]', description: 'Bounding box (min, max)' },
{ name: 'faces', type: 'list[list[int]]', description: 'List of faces (each face is a list of vertex indices)' },
{ name: 'face_normals', type: 'list[np.ndarray]', description: 'Normal vectors for each face' },
{ name: 'face_millers', type: 'list[tuple]', description: 'Miller indices for each face' },
{ name: 'face_forms', type: 'list[int]', description: 'Form index for each face (for color-by-form rendering)' },
{ name: 'twin', type: 'TwinMetadata | None', description: 'Twin metadata if geometry is twinned' },
];

const faceAttrs = [
{ name: 'vertex_indices', type: 'list[int]', description: 'Indices into vertices array (CCW order)' },
{ name: 'normal', type: 'tuple[float, float, float]', description: 'Outward-facing normal vector' },
{ name: 'miller_index', type: 'MillerIndex', description: 'Miller indices for this face' },
{ name: 'area', type: 'float', description: 'Surface area of the face' },
{ name: 'centroid', type: 'tuple[float, float, float]', description: 'Center point of the face' },
const latticeAttrs = [
{ name: 'a', type: 'float', description: 'Unit cell parameter a' },
{ name: 'b', type: 'float', description: 'Unit cell parameter b' },
{ name: 'c', type: 'float', description: 'Unit cell parameter c' },
{ name: 'alpha', type: 'float', description: 'Angle alpha in degrees' },
{ name: 'beta', type: 'float', description: 'Angle beta in degrees' },
{ name: 'gamma', type: 'float', description: 'Angle gamma in degrees' },
];
---

Expand All @@ -37,19 +38,20 @@ const faceAttrs = [

<p class="lead">
Generate 3D crystal geometry from CDL descriptions using half-space intersection
and crystallographic symmetry operations.
and crystallographic symmetry operations. Version 1.0.5.
</p>

<CodeBlock code="pip install crystal-geometry" lang="bash" />
<CodeBlock code="pip install gemmology-crystal-geometry" lang="bash" />

<h2>Functions</h2>
<h2>Core Functions</h2>

<APISignature
name="cdl_to_geometry"
signature="cdl_to_geometry(description: CrystalDescription) → CrystalGeometry"
/>

<p>Convert a parsed CDL description into 3D geometry.</p>
<p>Convert a parsed CDL description into 3D geometry. Uses <code>desc.flat_forms()</code>
internally to handle <code>FormGroup</code> nodes.</p>

<CodeBlock
lang="python"
Expand All @@ -59,7 +61,7 @@ from crystal_geometry import cdl_to_geometry
desc = parse_cdl("cubic[m3m]:{111}@1.0 + {100}@1.3")
geom = cdl_to_geometry(desc)

print(f"Vertices: {len(geom.vertices)}") # 14
print(f"Vertices: {len(geom.vertices)}") # 24
print(f"Faces: {len(geom.faces)}") # 14`}
/>

Expand All @@ -71,178 +73,198 @@ print(f"Faces: {len(geom.faces)}") # 14`}
<p><strong>Returns:</strong> <code>CrystalGeometry</code> object with vertices, faces, and normals</p>

<APISignature
name="apply_symmetry"
signature="apply_symmetry(planes: list[Plane], point_group: str) → list[Plane]"
name="cdl_string_to_geometry"
signature="cdl_string_to_geometry(cdl_string: str) → CrystalGeometry"
/>

<p>Apply point group symmetry operations to generate all equivalent planes.</p>
<p>Convenience function that parses a CDL string and generates geometry in one call.</p>

<CodeBlock
lang="python"
code={`from crystal_geometry import apply_symmetry, Plane
code={`from crystal_geometry import cdl_string_to_geometry

# Single {111} plane
planes = [Plane(normal=(1, 1, 1), distance=1.0)]

# Apply m3m symmetry -> 8 equivalent planes
all_planes = apply_symmetry(planes, "m3m")
print(len(all_planes)) # 8`}
geom = cdl_string_to_geometry("cubic[m3m]:{111}")
print(len(geom.vertices)) # 6
print(len(geom.faces)) # 8`}
/>

<APISignature
name="halfspace_intersection"
signature="halfspace_intersection(planes: list[Plane]) → CrystalGeometry"
name="halfspace_intersection_3d"
signature="halfspace_intersection_3d(normals, distances) → tuple[ndarray, list[list[int]]]"
/>

<p>Compute the convex polyhedron defined by the intersection of half-spaces.</p>
<p>Compute the convex polyhedron defined by half-space intersection.
Returns vertices and faces.</p>

<h2>Convenience Constructors</h2>

<CodeBlock
lang="python"
code={`from crystal_geometry import halfspace_intersection, Plane

# Define a cube with 6 planes
planes = [
Plane(normal=(1, 0, 0), distance=1.0),
Plane(normal=(-1, 0, 0), distance=1.0),
Plane(normal=(0, 1, 0), distance=1.0),
Plane(normal=(0, -1, 0), distance=1.0),
Plane(normal=(0, 0, 1), distance=1.0),
Plane(normal=(0, 0, -1), distance=1.0),
]
code={`from crystal_geometry import (
create_octahedron,
create_cube,
create_dodecahedron,
create_truncated_octahedron,
)

geom = halfspace_intersection(planes)
print(len(geom.vertices)) # 8
print(len(geom.faces)) # 6`}
# Create common crystal forms directly
geom = create_octahedron() # {111} in m3m
geom = create_cube() # {100} in m3m
geom = create_dodecahedron() # {110} in m3m
geom = create_truncated_octahedron() # {111} + {100}`}
/>

<h2>Symmetry Operations</h2>

<APISignature
name="apply_twin"
signature="apply_twin(geometry: CrystalGeometry, twin_law: str) → CrystalGeometry"
name="get_point_group_operations"
signature="get_point_group_operations(point_group: str) → list[np.ndarray]"
/>

<p>Apply a twin law to create twinned crystal geometry.</p>
<p>Get the 3x3 rotation/reflection matrices for a crystallographic point group.</p>

<CodeBlock
lang="python"
code={`from crystal_geometry import cdl_to_geometry, apply_twin
code={`from crystal_geometry import get_point_group_operations

geom = cdl_to_geometry(desc)
twinned = apply_twin(geom, "spinel_law")`}
matrices = get_point_group_operations("m3m")
print(len(matrices)) # 48 operations

matrices = get_point_group_operations("-3m")
print(len(matrices)) # 12 operations`}
/>

<p><strong>Supported twin laws:</strong></p>
<ul>
<li><code>spinel_law</code> - Cubic {'{111}'} contact twin</li>
<li><code>dauphine</code> - Quartz 180° rotation about c-axis</li>
<li><code>brazil</code> - Quartz reflection twin</li>
<li><code>japan_law</code> - Quartz {'{11-22}'} contact twin</li>
<li><code>carlsbad</code> - Feldspar twin</li>
</ul>
<APISignature
name="generate_equivalent_faces"
signature="generate_equivalent_faces(miller, point_group: str) → list[ndarray]"
/>

<h2>Classes</h2>
<p>Generate all symmetry-equivalent face normals from a single Miller index.</p>

<h3 id="CrystalGeometry"><code>CrystalGeometry</code></h3>
<APISignature
name="miller_to_normal"
signature="miller_to_normal(h, k, l, lattice) → ndarray"
/>

<p>Container for 3D crystal geometry data.</p>
<p>Convert Miller indices to a Cartesian normal vector using lattice parameters.</p>

<PropsTable
columns={[
{ key: 'name', header: 'Attribute', mono: true },
{ key: 'type', header: 'Type', mono: true },
{ key: 'description', header: 'Description' }
]}
rows={geometryAttrs}
<APISignature
name="get_lattice_for_system"
signature="get_lattice_for_system(system: str) → LatticeParams"
/>

<p>Get default lattice parameters for a crystal system.</p>

<h2>Modification Functions</h2>

<APISignature
name="apply_modifications"
signature="apply_modifications(vertices, modifications) → ndarray"
/>

<h4>Methods</h4>
<p>Apply morphological modifications (elongate, flatten, taper) to vertices.</p>

<CodeBlock
lang="python"
code={`# Transform the geometry
geom.translate(dx, dy, dz)
geom.scale(factor)
geom.rotate(axis, angle)
code={`from crystal_geometry import apply_elongation, apply_flatten, apply_taper

# Elongate along c-axis
vertices = apply_elongation(vertices, axis='c', ratio=1.5)

# Get geometry info
volume = geom.volume()
surface_area = geom.surface_area()
# Flatten along c-axis
vertices = apply_flatten(vertices, axis='c', ratio=0.5)

# Export to different formats
geom.to_mesh() # Returns vertices, faces arrays
geom.to_trimesh() # Returns trimesh.Trimesh object`}
# Taper toward one end
vertices = apply_taper(vertices, direction='c', factor=0.3)`}
/>

<h3 id="Face"><code>Face</code></h3>
<h2>Twin System</h2>

<p>Represents a single crystal face.</p>
<CodeBlock
lang="python"
code={`from crystal_geometry import (
get_twin_law,
list_twin_laws,
get_gemstone_twins,
TwinLaw,
)

<PropsTable
columns={[
{ key: 'name', header: 'Attribute', mono: true },
{ key: 'type', header: 'Type', mono: true },
{ key: 'description', header: 'Description' }
]}
rows={faceAttrs}
/>
# List all available twin laws
laws = list_twin_laws()
print(laws) # ['spinel', 'iron_cross', 'brazil', ...]

# Get a specific twin law
law = get_twin_law("spinel")
print(law.name) # 'spinel'
print(law.axis) # Twin axis
print(law.angle) # Rotation angle

<h3 id="Plane"><code>Plane</code></h3>
# Get all twin laws for a specific gemstone
twins = get_gemstone_twins("quartz")
print(twins) # ['dauphine', 'brazil', 'japan']`}
/>

<p>Represents a half-space boundary plane.</p>
<h2>Habit System</h2>

<CodeBlock
lang="python"
code={`from crystal_geometry import Plane

# Create from normal and distance
plane = Plane(normal=(1, 1, 1), distance=1.0)
code={`from crystal_geometry import (
get_habit,
list_habits,
get_gemstone_habits,
CrystalHabit,
)

# Create from Miller indices
plane = Plane.from_miller(h=1, k=1, l=1, distance=1.0)`}
/>
# List all registered habits
habits = list_habits()
print(habits) # ['octahedron', 'cube', 'hexagonal_prism', ...]

<h2>Symmetry Operations</h2>
# Get a specific habit
habit = get_habit("hexagonal_prism")
geom = habit.generate()

<APISignature
name="get_symmetry_matrices"
signature="get_symmetry_matrices(point_group: str) → list[np.ndarray]"
# Get habits for a specific gemstone
gem_habits = get_gemstone_habits("diamond")
print(gem_habits) # ['octahedron', 'cube', 'dodecahedron']`}
/>

<p>Get the 3x3 rotation/reflection matrices for a point group.</p>
<h2>Classes</h2>

<CodeBlock
lang="python"
code={`from crystal_geometry import get_symmetry_matrices
<h3 id="CrystalGeometry"><code>CrystalGeometry</code></h3>

matrices = get_symmetry_matrices("m3m")
print(len(matrices)) # 48 operations
<p>Container for 3D crystal geometry data.</p>

matrices = get_symmetry_matrices("-3m")
print(len(matrices)) # 12 operations`}
<PropsTable
columns={[
{ key: 'name', header: 'Attribute', mono: true },
{ key: 'type', header: 'Type', mono: true },
{ key: 'description', header: 'Description' }
]}
rows={geometryAttrs}
/>

<h2>Unit Cells</h2>
<h3 id="LatticeParams"><code>LatticeParams</code></h3>

<APISignature
name="get_unit_cell"
signature="get_unit_cell(system: CrystalSystem, a: float, b: float, c: float, alpha: float, beta: float, gamma: float) → UnitCell"
<p>Unit cell lattice parameters.</p>

<PropsTable
columns={[
{ key: 'name', header: 'Attribute', mono: true },
{ key: 'type', header: 'Type', mono: true },
{ key: 'description', header: 'Description' }
]}
rows={latticeAttrs}
/>

<p>Create a unit cell with specified parameters.</p>
<h2>Backend Acceleration</h2>

<CodeBlock
lang="python"
code={`from crystal_geometry import get_unit_cell
from cdl_parser import CrystalSystem

# Quartz unit cell
cell = get_unit_cell(
system=CrystalSystem.TRIGONAL,
a=4.913, b=4.913, c=5.405,
alpha=90, beta=90, gamma=120
)
code={`from crystal_geometry import get_backend, get_backend_info

# Get transformation matrix
transform = cell.cartesian_matrix()`}
# Check which backend is active
print(get_backend()) # 'native' or 'python'
print(get_backend_info()) # Detailed backend information`}
/>
</article>

Expand Down
Loading
Loading