diffinytrace 2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. diffinytrace/__init__.py +122 -0
  2. diffinytrace/basis_functions/__init__.py +14 -0
  3. diffinytrace/basis_functions/bspline.py +521 -0
  4. diffinytrace/basis_functions/chebyshev.py +3 -0
  5. diffinytrace/basis_functions/legendre.py +77 -0
  6. diffinytrace/basis_functions/zernike.py +235 -0
  7. diffinytrace/config.py +140 -0
  8. diffinytrace/constraints.py +54 -0
  9. diffinytrace/element.py +1660 -0
  10. diffinytrace/export/__init__.py +8 -0
  11. diffinytrace/export/cad.py +253 -0
  12. diffinytrace/gaussian_smoother.py +530 -0
  13. diffinytrace/hat_smoother.py +44 -0
  14. diffinytrace/integrators.py +452 -0
  15. diffinytrace/intersection.py +285 -0
  16. diffinytrace/optimize.py +808 -0
  17. diffinytrace/physical_object.py +150 -0
  18. diffinytrace/plotting/__init__.py +16 -0
  19. diffinytrace/plotting/core.py +92 -0
  20. diffinytrace/plotting/quantity2D.py +188 -0
  21. diffinytrace/plotting/system2D.py +220 -0
  22. diffinytrace/plotting/system3D.py +327 -0
  23. diffinytrace/plotting/wavelength.py +231 -0
  24. diffinytrace/refractive_index.py +101 -0
  25. diffinytrace/render.py +77 -0
  26. diffinytrace/source.py +661 -0
  27. diffinytrace/spectrum.py +79 -0
  28. diffinytrace/surface.py +468 -0
  29. diffinytrace/target_grid.py +399 -0
  30. diffinytrace/transforms.py +472 -0
  31. diffinytrace/utils/__init__.py +7 -0
  32. diffinytrace/utils/autograd.py +116 -0
  33. diffinytrace/utils/irradiance_importer.py +134 -0
  34. diffinytrace-2.1.dist-info/METADATA +26 -0
  35. diffinytrace-2.1.dist-info/RECORD +38 -0
  36. diffinytrace-2.1.dist-info/WHEEL +5 -0
  37. diffinytrace-2.1.dist-info/licenses/LICENSE +21 -0
  38. diffinytrace-2.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,8 @@
1
+ # Copyright (c) 2025 Martin Pflaum
2
+ # This file is part of the diffinytrace project, licensed under the MIT License.
3
+
4
+ __all__ = [
5
+ "cad"
6
+ ]
7
+
8
+ from . import cad
@@ -0,0 +1,253 @@
1
+ """
2
+ This module provides functions for exporting CAD data to different formats.
3
+ It includes functions for exporting to STEP, IGES, and STL formats.
4
+ """
5
+
6
+ # Copyright (c) 2025 Martin Pflaum
7
+ # This file is part of the diffinytrace project, licensed under the MIT License.
8
+
9
+ __all__ = [
10
+ "lens_to_solid",
11
+ "extract_knots_and_multiplicities",
12
+ "makeNurbsFace",
13
+ "makeBsplineFace",
14
+ "export_lens",
15
+ ]
16
+
17
+ import torch
18
+ import cadquery as cq
19
+ from collections import Counter
20
+ from typing import List, Tuple
21
+ import copy
22
+
23
+
24
+ from OCP.TColgp import TColgp_Array2OfPnt
25
+ from OCP.TColStd import TColStd_Array2OfReal, TColStd_Array1OfReal, TColStd_Array1OfInteger
26
+ from OCP.Message import Message, Message_Gravity
27
+
28
+ for printer in Message.DefaultMessenger_s().Printers():
29
+ printer.SetTraceLevel(Message_Gravity.Message_Fail)
30
+
31
+ from OCP.Precision import Precision
32
+ from OCP.Geom import Geom_BSplineSurface
33
+
34
+ from OCP.BRepBuilderAPI import (
35
+ BRepBuilderAPI_MakeFace,
36
+ )
37
+ import numpy as np
38
+
39
+
40
+ def lens_to_solid(lens,
41
+ resolution: int,
42
+ tol:float = 0.001,
43
+ smoothing = None,
44
+ minDeg: int = 1,
45
+ maxDeg: int = 3) -> cq.Solid:
46
+ """
47
+ Convert a lens object to a CAD solid.
48
+
49
+ Args:
50
+ lens: The lens object to be converted.
51
+ resolution (int): Resolution of the CAD model.
52
+ tol (float): Tolerance for the CAD model.
53
+ smoothing: Smoothing parameter for the CAD model.
54
+ minDeg (int): Minimum degree for the B-spline surface.
55
+ maxDeg (int): Maximum degree for the B-spline surface.
56
+ Returns:
57
+ cq.Solid: The CAD solid representing the lens.
58
+ """
59
+ #direction
60
+ dtype = torch.float
61
+ device = "cpu"
62
+ lens = copy.deepcopy(lens)
63
+ lens.to(dtype)
64
+ lens.to(device)
65
+
66
+ local_direction = torch.tensor([0.,0.,1.0],dtype=dtype,device=device)
67
+ transform = lens.surface1.get_transform()
68
+ direction = transform.to_global_dir(local_direction).detach().cpu().numpy()
69
+
70
+ lens_thickness = lens.lens_thickness.detach().cpu().numpy()
71
+ surface1,surface2 = lens.surface1,lens.surface2
72
+
73
+ face1 = surface1.get_CAD_face(resolution,tol=tol,smoothing=smoothing,minDeg=minDeg,maxDeg=maxDeg)
74
+ face2 = surface2.get_CAD_face(resolution,tol=tol,smoothing=smoothing,minDeg=minDeg,maxDeg=maxDeg)
75
+
76
+ if lens.is_square:
77
+ outer_face = cq.Face.makeRuledSurface(face1.outerWire(), face2.outerWire())
78
+ shell = cq.Shell.makeShell([outer_face,face1,face2])
79
+ solid = cq.Solid.makeSolid(shell)
80
+ return solid
81
+
82
+ lens_thickness = lens_thickness*5.
83
+ affine_matrix = lens.surface1.get_transform().get_transformation_matrix().detach().cpu().numpy()
84
+ off_vec = affine_matrix[:3, 3]
85
+ off_vec = off_vec-lens_thickness*direction
86
+ # Extract rotation (and scale)
87
+ cylinder_solid = cq.Solid.makeCylinder(lens.aperture_radius, lens_thickness*2., cq.Vector(off_vec[0],off_vec[1],off_vec[2]), cq.Vector(direction[0],direction[1],direction[2]))
88
+ #if not lens.is_square:
89
+ face1 = face1.intersect(cylinder_solid)
90
+ face2 = face2.intersect(cylinder_solid)
91
+
92
+ face1_edge = [edge for edge in face1.edges()]
93
+ face2_edge = [edge for edge in face2.edges()]
94
+ outer_faces = []
95
+ for k in range(len(face1_edge)):
96
+ outer_faces += [cq.Face.makeRuledSurface(face1_edge[k],face2_edge[k])]
97
+
98
+ shell = cq.Shell.makeShell(outer_faces+[face1,face2])
99
+ solid = cq.Solid.makeSolid(shell)
100
+ return solid
101
+
102
+
103
+ def extract_knots_and_multiplicities(knots: List[float]) -> Tuple[List[float], List[int]]:
104
+ """
105
+ Extract unique knots and their multiplicities from a knot vector.
106
+
107
+ Args:
108
+ knots (List[float]): The knot vector with implicit multiplicities.
109
+
110
+ Returns:
111
+ unique_knots (List[float]): A list of unique knots.
112
+ multiplicities (List[int]): A list of multiplicities corresponding to the unique knots.
113
+ """
114
+ unique_knots = []
115
+ multiplicities = []
116
+
117
+ # Count occurrences of each knot
118
+ knot_counts = Counter(knots)
119
+
120
+ # Sort the knots to ensure increasing order
121
+ sorted_knots = sorted(knot_counts.items())
122
+
123
+ for knot, count in sorted_knots:
124
+ unique_knots.append(knot)
125
+ multiplicities.append(count)
126
+
127
+ return unique_knots, multiplicities
128
+
129
+
130
+ def makeNurbsFace(
131
+ control_points,
132
+ weights,
133
+ U1,
134
+ U2,
135
+ u_degree: int,
136
+ v_degree: int,
137
+ u_periodic: bool = False,
138
+ v_periodic: bool = False
139
+ )->cq.Face:
140
+ """
141
+ Create a B-spline surface from control points, weights, and implicit knot vectors.
142
+
143
+ Args:
144
+ control_points (list): 2D list of control points as Vectors.
145
+ weights (list): 2D list of weights for each control point.
146
+ U1 (list): Knot vector in U direction with implicit multiplicities.
147
+ U2 (list): Knot vector in V direction with implicit multiplicities.
148
+ u_degree (int): Degree of the B-spline in the U direction.
149
+ v_degree (int): Degree of the B-spline in the V direction.
150
+ u_periodic (bool): If True, makes the surface periodic in the U direction.
151
+ v_periodic (bool): If True, makes the surface periodic in the V direction.
152
+
153
+ Returns:
154
+ cq.Face: Face instance representing the B-spline surface.
155
+ """
156
+ U1 = [float(elem) for elem in U1]
157
+ U2 = [float(elem) for elem in U2]
158
+ # Extract unique knots and multiplicities for U and V directions
159
+ u_knots, u_mults = extract_knots_and_multiplicities(U1)
160
+ v_knots, v_mults = extract_knots_and_multiplicities(U2)
161
+ # Initialize control points array
162
+ num_u = len(control_points)
163
+ num_v = len(control_points[0])
164
+ poles = TColgp_Array2OfPnt(1, num_u, 1, num_v)
165
+ for i, row in enumerate(control_points):
166
+ for j, _pt in enumerate(row):
167
+ pt = cq.Vector(_pt[0],_pt[1],_pt[2])
168
+ poles.SetValue(i + 1, j + 1, pt.toPnt())
169
+
170
+ # Initialize weights array
171
+ weights_array = TColStd_Array2OfReal(1, num_u, 1, num_v)
172
+ for i, row in enumerate(weights):
173
+ for j, w in enumerate(row):
174
+ weights_array.SetValue(i + 1, j + 1, float(w))
175
+
176
+ # Initialize knot arrays for U and V directions
177
+ u_knots_array = TColStd_Array1OfReal(1, len(u_knots))
178
+ v_knots_array = TColStd_Array1OfReal(1, len(v_knots))
179
+ u_mults_array = TColStd_Array1OfInteger(1, len(u_mults))
180
+ v_mults_array = TColStd_Array1OfInteger(1, len(v_mults))
181
+
182
+ for idx, val in enumerate(u_knots):
183
+ u_knots_array.SetValue(idx + 1, val)
184
+ for idx, val in enumerate(v_knots):
185
+ v_knots_array.SetValue(idx + 1, val)
186
+ for idx, mult in enumerate(u_mults):
187
+ u_mults_array.SetValue(idx + 1, mult)
188
+ for idx, mult in enumerate(v_mults):
189
+ v_mults_array.SetValue(idx + 1, mult)
190
+
191
+ # Create the B-spline surface
192
+ spline_surface = Geom_BSplineSurface(
193
+ poles,
194
+ weights_array,
195
+ u_knots_array,
196
+ v_knots_array,
197
+ u_mults_array,
198
+ v_mults_array,
199
+ u_degree,
200
+ v_degree,
201
+ u_periodic,
202
+ v_periodic
203
+ )
204
+
205
+ # Create a face from the B-spline surface
206
+ face = BRepBuilderAPI_MakeFace(spline_surface, Precision.Confusion_s()).Face()
207
+
208
+ # Return an instance of Face initialized with the generated face
209
+ return cq.Face(face)
210
+
211
+ def makeBsplineFace(
212
+ control_points,
213
+ U1,
214
+ U2,
215
+ u_degree: int,
216
+ v_degree: int,
217
+ u_periodic: bool = False,
218
+ v_periodic: bool = False
219
+ )->cq.Face:
220
+ """
221
+ Create a non-rational B-spline surface face from control points and knot vectors.
222
+
223
+ Args:
224
+ control_points (np.ndarray): 2D array of control points (shape: [num_u, num_v, 3]).
225
+ U1 (list): Knot vector in U direction with implicit multiplicities.
226
+ U2 (list): Knot vector in V direction with implicit multiplicities.
227
+ u_degree (int): Degree of the B-spline in the U direction.
228
+ v_degree (int): Degree of the B-spline in the V direction.
229
+ u_periodic (bool, optional): If True, makes the surface periodic in the U direction. Defaults to False.
230
+ v_periodic (bool, optional): If True, makes the surface periodic in the V direction. Defaults to False.
231
+
232
+ Returns:
233
+ cq.Face: Face instance representing the B-spline surface.
234
+ """
235
+
236
+ weights = np.ones((control_points.shape[0],control_points.shape[1]),dtype=float)
237
+ return makeNurbsFace(control_points,weights,U1,U2,u_degree,v_degree,u_periodic,v_periodic)
238
+
239
+ def export_lens(file_path:str, lens, resolution:int, tol:float = 0.001):
240
+ """
241
+ Export a lens to a CAD file.
242
+
243
+ Args:
244
+ file_path (str): The path to save the CAD file.
245
+ lens: The lens object to be exported.
246
+ resolution (int): Resolution of the CAD model.
247
+ tol (float): Tolerance for the CAD model.
248
+ """
249
+
250
+ solid = lens_to_solid(lens,resolution,tol=tol)
251
+ cq.exporters.export(solid, file_path)
252
+
253
+