TurtleGL-3d 1.2.4__tar.gz → 1.2.7__tar.gz

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 (32) hide show
  1. turtlegl_3d-1.2.7/PKG-INFO +700 -0
  2. turtlegl_3d-1.2.7/README.md +476 -0
  3. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/pyproject.toml +1 -1
  4. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/setup.py +1 -1
  5. turtlegl_3d-1.2.7/src/TurtleGL_3d.egg-info/PKG-INFO +700 -0
  6. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_grating_example.py +3 -0
  7. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/src/camera.py +126 -57
  8. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/src/scene.py +14 -3
  9. turtlegl_3d-1.2.4/PKG-INFO +0 -554
  10. turtlegl_3d-1.2.4/README.md +0 -330
  11. turtlegl_3d-1.2.4/src/TurtleGL_3d.egg-info/PKG-INFO +0 -554
  12. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/LICENSE +0 -0
  13. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/setup.cfg +0 -0
  14. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/TurtleGL_3d.egg-info/SOURCES.txt +0 -0
  15. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/TurtleGL_3d.egg-info/dependency_links.txt +0 -0
  16. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/TurtleGL_3d.egg-info/requires.txt +0 -0
  17. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/TurtleGL_3d.egg-info/top_level.txt +0 -0
  18. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/__init__.py +0 -0
  19. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/airplane_game.py +0 -0
  20. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/christmas tree/turtleGL_christmas_tree_example.py +0 -0
  21. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/racing_game.py +0 -0
  22. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/texture example/turtleGL_texture_example.py +0 -0
  23. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_anime_example.py +0 -0
  24. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_cabin_example.py +0 -0
  25. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_cube_example.py +0 -0
  26. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_focal_example.py +0 -0
  27. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_from_file_example.py +0 -0
  28. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_obj_example.py +0 -0
  29. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_plot3D_example.py +0 -0
  30. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/example/turtleGL_volume_example.py +0 -0
  31. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/src/plot3d.py +0 -0
  32. {turtlegl_3d-1.2.4 → turtlegl_3d-1.2.7}/src/turtleGL/src/volume.py +0 -0
@@ -0,0 +1,700 @@
1
+ Metadata-Version: 2.4
2
+ Name: TurtleGL-3d
3
+ Version: 1.2.7
4
+ Summary: A 3D grafics library based on turtle
5
+ Home-page: https://github.com/MichaelHyan/turtleGL
6
+ Author: Han Yan
7
+ Author-email: Han Yan <3367461801@qq.com>
8
+ License:
9
+ Apache License
10
+ Version 2.0, January 2004
11
+ http://www.apache.org/licenses/
12
+
13
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
14
+
15
+ 1. Definitions.
16
+
17
+ "License" shall mean the terms and conditions for use, reproduction,
18
+ and distribution as defined by Sections 1 through 9 of this document.
19
+
20
+ "Licensor" shall mean the copyright owner or entity authorized by
21
+ the copyright owner that is granting the License.
22
+
23
+ "Legal Entity" shall mean the union of the acting entity and all
24
+ other entities that control, are controlled by, or are under common
25
+ control with that entity. For the purposes of this definition,
26
+ "control" means (i) the power, direct or indirect, to cause the
27
+ direction or management of such entity, whether by contract or
28
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
29
+ outstanding shares, or (iii) beneficial ownership of such entity.
30
+
31
+ "You" (or "Your") shall mean an individual or Legal Entity
32
+ exercising permissions granted by this License.
33
+
34
+ "Source" form shall mean the preferred form for making modifications,
35
+ including but not limited to software source code, documentation
36
+ source, and configuration files.
37
+
38
+ "Object" form shall mean any form resulting from mechanical
39
+ transformation or translation of a Source form, including but
40
+ not limited to compiled object code, generated documentation,
41
+ and conversions to other media types.
42
+
43
+ "Work" shall mean the work of authorship, whether in Source or
44
+ Object form, made available under the License, as indicated by a
45
+ copyright notice that is included in or attached to the work
46
+ (an example is provided in the Appendix below).
47
+
48
+ "Derivative Works" shall mean any work, whether in Source or Object
49
+ form, that is based on (or derived from) the Work and for which the
50
+ editorial revisions, annotations, elaborations, or other modifications
51
+ represent, as a whole, an original work of authorship. For the purposes
52
+ of this License, Derivative Works shall not include works that remain
53
+ separable from, or merely link (or bind by name) to the interfaces of,
54
+ the Work and Derivative Works thereof.
55
+
56
+ "Contribution" shall mean any work of authorship, including
57
+ the original version of the Work and any modifications or additions
58
+ to that Work or Derivative Works thereof, that is intentionally
59
+ submitted to Licensor for inclusion in the Work by the copyright owner
60
+ or by an individual or Legal Entity authorized to submit on behalf of
61
+ the copyright owner. For the purposes of this definition, "submitted"
62
+ means any form of electronic, verbal, or written communication sent
63
+ to the Licensor or its representatives, including but not limited to
64
+ communication on electronic mailing lists, source code control systems,
65
+ and issue tracking systems that are managed by, or on behalf of, the
66
+ Licensor for the purpose of discussing and improving the Work, but
67
+ excluding communication that is conspicuously marked or otherwise
68
+ designated in writing by the copyright owner as "Not a Contribution."
69
+
70
+ "Contributor" shall mean Licensor and any individual or Legal Entity
71
+ on behalf of whom a Contribution has been received by Licensor and
72
+ subsequently incorporated within the Work.
73
+
74
+ 2. Grant of Copyright License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ copyright license to reproduce, prepare Derivative Works of,
78
+ publicly display, publicly perform, sublicense, and distribute the
79
+ Work and such Derivative Works in Source or Object form.
80
+
81
+ 3. Grant of Patent License. Subject to the terms and conditions of
82
+ this License, each Contributor hereby grants to You a perpetual,
83
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
84
+ (except as stated in this section) patent license to make, have made,
85
+ use, offer to sell, sell, import, and otherwise transfer the Work,
86
+ where such license applies only to those patent claims licensable
87
+ by such Contributor that are necessarily infringed by their
88
+ Contribution(s) alone or by combination of their Contribution(s)
89
+ with the Work to which such Contribution(s) was submitted. If You
90
+ institute patent litigation against any entity (including a
91
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
92
+ or a Contribution incorporated within the Work constitutes direct
93
+ or contributory patent infringement, then any patent licenses
94
+ granted to You under this License for that Work shall terminate
95
+ as of the date such litigation is filed.
96
+
97
+ 4. Redistribution. You may reproduce and distribute copies of the
98
+ Work or Derivative Works thereof in any medium, with or without
99
+ modifications, and in Source or Object form, provided that You
100
+ meet the following conditions:
101
+
102
+ (a) You must give any other recipients of the Work or
103
+ Derivative Works a copy of this License; and
104
+
105
+ (b) You must cause any modified files to carry prominent notices
106
+ stating that You changed the files; and
107
+
108
+ (c) You must retain, in the Source form of any Derivative Works
109
+ that You distribute, all copyright, patent, trademark, and
110
+ attribution notices from the Source form of the Work,
111
+ excluding those notices that do not pertain to any part of
112
+ the Derivative Works; and
113
+
114
+ (d) If the Work includes a "NOTICE" text file as part of its
115
+ distribution, then any Derivative Works that You distribute must
116
+ include a readable copy of the attribution notices contained
117
+ within such NOTICE file, excluding those notices that do not
118
+ pertain to any part of the Derivative Works, in at least one
119
+ of the following places: within a NOTICE text file distributed
120
+ as part of the Derivative Works; within the Source form or
121
+ documentation, if provided along with the Derivative Works; or,
122
+ within a display generated by the Derivative Works, if and
123
+ wherever such third-party notices normally appear. The contents
124
+ of the NOTICE file are for informational purposes only and
125
+ do not modify the License. You may add Your own attribution
126
+ notices within Derivative Works that You distribute, alongside
127
+ or as an addendum to the NOTICE text from the Work, provided
128
+ that such additional attribution notices cannot be construed
129
+ as modifying the License.
130
+
131
+ You may add Your own copyright statement to Your modifications and
132
+ may provide additional or different license terms and conditions
133
+ for use, reproduction, or distribution of Your modifications, or
134
+ for any such Derivative Works as a whole, provided Your use,
135
+ reproduction, and distribution of the Work otherwise complies with
136
+ the conditions stated in this License.
137
+
138
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
139
+ any Contribution intentionally submitted for inclusion in the Work
140
+ by You to the Licensor shall be under the terms and conditions of
141
+ this License, without any additional terms or conditions.
142
+ Notwithstanding the above, nothing herein shall supersede or modify
143
+ the terms of any separate license agreement you may have executed
144
+ with Licensor regarding such Contributions.
145
+
146
+ 6. Trademarks. This License does not grant permission to use the trade
147
+ names, trademarks, service marks, or product names of the Licensor,
148
+ except as required for reasonable and customary use in describing the
149
+ origin of the Work and reproducing the content of the NOTICE file.
150
+
151
+ 7. Disclaimer of Warranty. Unless required by applicable law or
152
+ agreed to in writing, Licensor provides the Work (and each
153
+ Contributor provides its Contributions) on an "AS IS" BASIS,
154
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
155
+ implied, including, without limitation, any warranties or conditions
156
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
157
+ PARTICULAR PURPOSE. You are solely responsible for determining the
158
+ appropriateness of using or redistributing the Work and assume any
159
+ risks associated with Your exercise of permissions under this License.
160
+
161
+ 8. Limitation of Liability. In no event and under no legal theory,
162
+ whether in tort (including negligence), contract, or otherwise,
163
+ unless required by applicable law (such as deliberate and grossly
164
+ negligent acts) or agreed to in writing, shall any Contributor be
165
+ liable to You for damages, including any direct, indirect, special,
166
+ incidental, or consequential damages of any character arising as a
167
+ result of this License or out of the use or inability to use the
168
+ Work (including but not limited to damages for loss of goodwill,
169
+ work stoppage, computer failure or malfunction, or any and all
170
+ other commercial damages or losses), even if such Contributor
171
+ has been advised of the possibility of such damages.
172
+
173
+ 9. Accepting Warranty or Additional Liability. While redistributing
174
+ the Work or Derivative Works thereof, You may choose to offer,
175
+ and charge a fee for, acceptance of support, warranty, indemnity,
176
+ or other liability obligations and/or rights consistent with this
177
+ License. However, in accepting such obligations, You may act only
178
+ on Your own behalf and on Your sole responsibility, not on behalf
179
+ of any other Contributor, and only if You agree to indemnify,
180
+ defend, and hold each Contributor harmless for any liability
181
+ incurred by, or claims asserted against, such Contributor by reason
182
+ of your accepting any such warranty or additional liability.
183
+
184
+ END OF TERMS AND CONDITIONS
185
+
186
+ APPENDIX: How to apply the Apache License to your work.
187
+
188
+ To apply the Apache License to your work, attach the following
189
+ boilerplate notice, with the fields enclosed by brackets "[]"
190
+ replaced with your own identifying information. (Don't include
191
+ the brackets!) The text should be enclosed in the appropriate
192
+ comment syntax for the file format. We also recommend that a
193
+ file or class name and description of purpose be included on the
194
+ same "printed page" as the copyright notice for easier
195
+ identification within third-party archives.
196
+
197
+ Copyright [yyyy] [name of copyright owner]
198
+
199
+ Licensed under the Apache License, Version 2.0 (the "License");
200
+ you may not use this file except in compliance with the License.
201
+ You may obtain a copy of the License at
202
+
203
+ http://www.apache.org/licenses/LICENSE-2.0
204
+
205
+ Unless required by applicable law or agreed to in writing, software
206
+ distributed under the License is distributed on an "AS IS" BASIS,
207
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
208
+ See the License for the specific language governing permissions and
209
+ limitations under the License.
210
+
211
+ Project-URL: Homepage, https://github.com/MichaelHyan/turtleGL
212
+ Classifier: Programming Language :: Python :: 3
213
+ Classifier: License :: OSI Approved :: MIT License
214
+ Classifier: Operating System :: OS Independent
215
+ Requires-Python: >=3.8
216
+ Description-Content-Type: text/markdown
217
+ License-File: LICENSE
218
+ Requires-Dist: numpy>=1.24.4
219
+ Requires-Dist: opencv-python>=4.12.0
220
+ Dynamic: author
221
+ Dynamic: home-page
222
+ Dynamic: license-file
223
+ Dynamic: requires-python
224
+
225
+ # 🐢 TurtleGL-3d
226
+
227
+ **A 3D graphics library based on Python turtle and OpenGL-style rendering techniques.**
228
+
229
+ An object-oriented, intuitive Python 3D graphics library based on the turtle library.
230
+
231
+ ---
232
+
233
+ ## ✨ Features
234
+
235
+ - 🎥 **Camera System** — Independent camera object supporting perspective / cabinet / isometric / orthographic projection modes.
236
+ - 🎨 **Scene Management** — Structured scene object supporting line, face, and texture data management.
237
+ - 📐 **3D Function Plotting** — 3D function image plotting based on `plot3d` object.
238
+ - 📦 **Volume Calculation** — Ray method volume calculation supporting multi-directional checks and partitioning acceleration.
239
+ - 🖼️ **Texture Mapping** — Homography matrix-based texture mapping.
240
+ - 🌗 **Shading & Normal** — Three rendering modes: material preview / shadow mode / normal preview.
241
+ - 📁 **OBJ Import** — Support for importing `.obj` 3D models with normal correction.
242
+ - 🎬 **Image & Video Export** — OpenCV-based image export and video compositing.
243
+ - 🔄 **Transform** — Spatial transformations: rotation, translation, scaling, etc.
244
+ - 📊 **Depth Sorting** — Depth sorting algorithms for different projection modes.
245
+
246
+ ---
247
+
248
+ ## 📦 Installation
249
+
250
+ ```bash
251
+ pip install TurtleGL-3d
252
+ ```
253
+
254
+ ### Dependencies
255
+
256
+ - Python >= 3.8
257
+ - numpy >= 1.24.4
258
+ - opencv-python >= 4.12.0
259
+
260
+ ---
261
+
262
+ ## 🚀 Quick Start
263
+
264
+ ### Basic Example: Drawing a Colorful Cube
265
+
266
+ ```python
267
+ import turtleGL
268
+
269
+ # Instantiate the camera
270
+ camera = turtleGL.camera()
271
+ camera.camera_position = [100, 100, 100]
272
+ camera.to_target([0, 0, 0]) # Face the origin
273
+ camera.camera_focal = 300 # Focal length
274
+ camera.type = 1 # Perspective mode
275
+ camera.rend = 1 # Shadow mode
276
+
277
+ # Instantiate the scene
278
+ scene = turtleGL.scene()
279
+ scene.face = [
280
+ [[[50, 50, 0], [-50, 50, 0], [-50, -50, 0], [50, -50, 0]], '#FF0000'],
281
+ [[[50, 50, 100], [-50, 50, 100], [-50, -50, 100], [50, -50, 100]], '#00FF00'],
282
+ [[[50, 50, 0], [50, 50, 100], [50, -50, 100], [50, -50, 0]], '#0000FF'],
283
+ [[[-50, 50, 0], [-50, -50, 0], [-50, -50, 100], [-50, 50, 100]], '#FFFF00'],
284
+ [[[50, 50, 0], [-50, 50, 0], [-50, 50, 100], [50, 50, 100]], '#FF00FF'],
285
+ [[[-50, -50, 0], [50, -50, 0], [50, -50, 100], [-50, -50, 100]], '#00FFFF'],
286
+ ]
287
+
288
+ # Depth sorting and drawing
289
+ camera.draw_from_scene(scene.sort_all_avg(camera.camera_position))
290
+ camera.done()
291
+ ```
292
+
293
+ ### Importing an OBJ Model
294
+
295
+ ```python
296
+ import turtleGL, math
297
+
298
+ camera = turtleGL.camera('OBJ Example')
299
+ camera.camera_position = [-101, -121, -150]
300
+ camera.to_target([0, 0, 50])
301
+ camera.camera_focal = 500
302
+ camera.ray = [1, 1, -1]
303
+ camera.type = 1
304
+ camera.rend = 1
305
+
306
+ scene = turtleGL.scene()
307
+ scene.import_obj('model.obj', 50, '#66ccff') # Scale 50x, specify color
308
+ scene.check_obj_norm('model.obj') # Correct normals
309
+ scene.generate_line('#ffffff') # Generate edges
310
+
311
+ # Rotation animation
312
+ for i in range(360):
313
+ camera.clear()
314
+ camera.camera_position = [150 * math.cos(math.radians(i)),
315
+ 150 * math.sin(math.radians(i)),
316
+ 150]
317
+ camera.to_target([0, 0, 0])
318
+ camera.draw_from_scene(scene.sort_all_avg(camera.camera_position))
319
+ camera.update()
320
+ ```
321
+
322
+ ### 3D Function Plotting
323
+
324
+ ```python
325
+ import turtleGL
326
+
327
+ camera = turtleGL.camera('Plot3D Example')
328
+ camera.type = 0 # Cabinet mode
329
+
330
+ scene = turtleGL.plot3d()
331
+ scene.xlim = [-100, 100]
332
+ scene.ylim = [-100, 100]
333
+ scene.step = 10
334
+
335
+ def function(x, y):
336
+ return 0.01 * (x**2 - y**2)
337
+
338
+ scene.generate_face(function)
339
+ scene.generate_line(function, color='#000000')
340
+ camera.draw_from_scene(scene.sort_all_cabin())
341
+ camera.done()
342
+ ```
343
+
344
+ ### Volume Calculation
345
+
346
+ ```python
347
+ import turtleGL
348
+
349
+ camera = turtleGL.camera()
350
+ camera.camera_position = [10, 120, 10]
351
+ camera.to_target([0, 0, 0])
352
+ camera.camera_focal = 500
353
+ camera.type = 1
354
+ camera.rend = 1
355
+
356
+ scene = turtleGL.scene()
357
+ scene.import_obj('model.obj', 50, '#66ccff')
358
+ scene.check_obj_norm('model.obj')
359
+ scene.triangulation() # Triangulation is required for volume calculation
360
+ scene.generate_line('#ff0000')
361
+
362
+ volume = turtleGL.volume()
363
+ volume.sample_distance = 5 # Sampling distance
364
+ volume.check = True # Multi-directional check
365
+ volume.allow_edge = True # Allow edge intersections
366
+ volume.volume(scene.face) # Calculate volume
367
+
368
+ camera.draw_from_scene(scene.sort_line_avg(camera.camera_position))
369
+ for i in volume.points:
370
+ camera.dot(i)
371
+ camera.done()
372
+ ```
373
+
374
+ ### Texture Mapping & Image Export
375
+
376
+ ```python
377
+ import turtleGL
378
+
379
+ camera = turtleGL.camera('Texture Example')
380
+ camera.camera_position = [201, 201, 131]
381
+ camera.to_target([0, 0, 50])
382
+ camera.camera_focal = 500
383
+ camera.type = 1
384
+ camera.rend = 1
385
+
386
+ scene = turtleGL.scene()
387
+ scene.tex = [
388
+ [[[50, 50, 100], [-50, 50, 100], [-50, -50, 100], [50, -50, 100]], 'grass_up.png'],
389
+ [[[50, 50, 0], [-50, 50, 0], [-50, -50, 0], [50, -50, 0]], 'grass_bottom.png'],
390
+ ]
391
+
392
+ # Render and export using OpenCV
393
+ camera.image_size = [700, 700]
394
+ camera.create_image('#ffffff')
395
+ camera.draw_from_scene_cv2(scene.sort_all_avg(camera.camera_position))
396
+ camera.imshow() # Display
397
+ camera.imwrite('output.png') # Save image
398
+ ```
399
+
400
+ ---
401
+
402
+ ## 📖 API Reference
403
+
404
+ ### Camera Object
405
+
406
+ The camera object handles 3D to 2D projection and rendering.
407
+
408
+ #### Attributes
409
+
410
+ | Attribute | Type | Default | Description |
411
+ |-----------|------|---------|-------------|
412
+ | `camera_position` | `[x,y,z]` | `[0,0,0]` | Camera position |
413
+ | `camera_direction` | `[x,y,z]` | `[0,0,1]` | Camera look direction |
414
+ | `camera_rotation` | `float` | `0` | Camera rotation angle (radians), causing left/right tilt |
415
+ | `camera_focal` | `float` | `1` | Focal length |
416
+ | `point_behind_cam_type` | `int` | `0` | Handling method for points behind the camera (0/1/2/3) |
417
+ | `point_behind_cam_allow_count` | `int` | `0` | Number of allowed behind-camera points during material rendering |
418
+ | `ray` | `[x,y,z]` | `[0,0,-1]` | Light direction, used for shading |
419
+ | `rend` | `int` | `0` | Rendering type: 0 material preview / 1 shadow mode / 2 normal preview |
420
+ | `shade_value` | `int` | `128` | Multiply factor for shading (0-255) |
421
+ | `pensize` | `int` | `2` | Pen size (only affects lines) |
422
+ | `pencolor` | `str` | `'#000000'` | Pen color (only affects lines) |
423
+ | `type` | `int` | `1` | Camera type: 0 cabinet / 1 perspective / 2 isometric / -1 orthographic |
424
+ | `grating_size` | `[x,y]` | `[500,400]` | Raster rendering area size |
425
+ | `grating_length` | `int` | `1` | Raster sampling step |
426
+ | `image_size` | `[x,y]` | `[500,400]` | Export image size |
427
+ | `image` | `ndarray` | `[]` | Currently stored OpenCV image |
428
+
429
+ #### Handling Points Behind the Camera
430
+
431
+ | Mode | Description |
432
+ |------|-------------|
433
+ | `0` | No processing; points behind the camera appear in the opposite direction |
434
+ | `1` | Flip UV to bring points back to normal orientation |
435
+ | `2` | Use orthographic mode with small deviation |
436
+ | `3` | Use scaled orthographic perspective |
437
+
438
+ #### Rendering Modes
439
+
440
+ | Mode | Description |
441
+ |------|-------------|
442
+ | `0` — Material Preview | Faces display the specified color directly |
443
+ | `1` — Shadow Mode | Shadows calculated based on angle between light direction and normal; backlit faces use the multiply factor |
444
+ | `2` — Normal Mode | Normal direction cosine relative to camera direction > 0 displays blue, otherwise red |
445
+
446
+ #### Methods
447
+
448
+ ```python
449
+ # Basic Setup
450
+ setposition([x,y,z]) # Set camera position
451
+ setdirection([x,y,z]) # Set camera direction
452
+ setfocal(x) # Set focal length
453
+ settype(x) # Set projection type (supports 'focal'/'cabin'/'isometric')
454
+ to_target([x,y,z]) # Point camera toward target
455
+ status() # Print current camera attributes
456
+
457
+ # Coordinate Mapping
458
+ pointfocal([x,y,z]) # Perspective: 3D → 2D mapping, returns [[u,v], bool]
459
+ pointcabinet([x,y,z]) # Cabinet: 3D → 2D mapping
460
+ pointisometric([x,y,z]) # Isometric: 3D → 2D mapping
461
+ pointorthografic([x,y,z]) # Orthographic: 3D → 2D mapping
462
+ pointfocal_inverse([u,v]) # Perspective: 2D → 3D inverse mapping
463
+
464
+ # Drawing (turtle rendering)
465
+ dot([x,y,z], color) # Draw a single point
466
+ drawline(linedata) # Draw an edge
467
+ drawface(facedata) # Draw a face
468
+ drawtex(facedata) # Draw texture
469
+ draw_from_scene(scenedata) # Draw integrated data
470
+ draw_axis(l) # Draw coordinate axes
471
+ write(point, str) # Write text at a 3D position
472
+
473
+ # Drawing (OpenCV rendering)
474
+ drawline_cv2(linedata) # Draw edge with OpenCV
475
+ drawface_cv2(facedata) # Draw face with OpenCV
476
+ drawtex_cv2(facedata) # Draw texture with OpenCV
477
+ draw_from_scene_cv2(scenedata)# Draw integrated data with OpenCV
478
+
479
+ # Image Export
480
+ create_image(bgcolor) # Initialize image (can be called repeatedly to clear)
481
+ imshow() # Display current image
482
+ imwrite(path) # Save image to file
483
+ capture(path, index) # Capture frame by index (for video frames)
484
+ to_video(path, fps=30) # Compose video
485
+
486
+ # Raster Algorithm (experimental)
487
+ grating(face) # Perform raster calculation
488
+ grating_cv2(face) # Raster with OpenCV
489
+ show_grating_limit() # Show rendering area border
490
+
491
+ # Utilities
492
+ tracer(t) # Control animation switch
493
+ delay() # Delay
494
+ clear() # Clear canvas
495
+ bgcolor(color) # Set background color
496
+ update() # Update canvas
497
+ done() # Prevent window from closing automatically
498
+ ```
499
+
500
+ ---
501
+
502
+ ### Scene Object
503
+
504
+ The scene object stores line, face, and texture data, and supports spatial transformations and depth sorting.
505
+
506
+ #### Data Format
507
+
508
+ ```python
509
+ # Edge data
510
+ [[[x1,y1,z1], [x2,y2,z2]], '#RRGGBB']
511
+
512
+ # Face data (enter vertices in counterclockwise order; normal points outward)
513
+ [[[x1,y1,z1], [x2,y2,z2], ..., [xn,yn,zn]], '#RRGGBB']
514
+
515
+ # Texture data (4 vertices, color replaced by image path)
516
+ [[[x1,y1,z1], [x2,y2,z2], [x3,y3,z3], [x4,y4,z4]], 'texture.png']
517
+ ```
518
+
519
+ #### Attributes
520
+
521
+ | Attribute | Description |
522
+ |-----------|-------------|
523
+ | `line` | List of edge data |
524
+ | `face` | List of face data |
525
+ | `tex` | List of texture data |
526
+ | `center` | Center point of the scene |
527
+
528
+ #### Methods
529
+
530
+ ```python
531
+ # Add Data
532
+ addline([[x1,y1,z1],[x2,y2,z2],'#color']) # Add an edge
533
+ addface([[x1,y1,z1],...,[xn,yn,zn],'#color'])# Add a face
534
+
535
+ # Import/Export
536
+ import_line(path) # Import line data (CSV)
537
+ import_face(path) # Import face data (CSV)
538
+ export_line(path) # Export line data (CSV)
539
+ export_face(path) # Export face data (CSV)
540
+
541
+ # OBJ Model
542
+ import_obj(path, scale, color) # Import OBJ model (random color if color is empty)
543
+ import_obj_normal(path) # Import OBJ normal data
544
+ check_obj_norm(path) # Correct face orientation based on normals
545
+ add_obj(filepath, scale, color)# Import OBJ and append to existing face data
546
+
547
+ # Spatial Transformations
548
+ rotate(rotate_vector, center) # Rotate around center (rotation vector in radians)
549
+ move(move_vector) # Translate
550
+ scale(scale_vector, center) # Scale
551
+ rotate_edge() # Cycle edges (change triangulation partition)
552
+
553
+ # Depth Sorting — Perspective/Orthographic Modes
554
+ sort_line_avg(camera_pos) # Sort edges (modifies object attribute and returns)
555
+ sort_face_avg(camera_pos) # Sort faces
556
+ sort_tex_avg(camera_pos) # Sort textures
557
+ sort_all_avg(camera_pos) # Sort all (returns data without modifying object)
558
+
559
+ # Depth Sorting — Cabinet Mode
560
+ sort_line_cabin() # Sort edges
561
+ sort_face_cabin() # Sort faces
562
+ sort_tex_cabin() # Sort textures
563
+ sort_all_cabin() # Sort all
564
+
565
+ # Depth Sorting — Isometric Mode
566
+ sort_line_isometric() # Sort edges
567
+ sort_face_isometric() # Sort faces
568
+ sort_tex_isometric() # Sort textures
569
+ sort_all_isometric() # Sort all
570
+
571
+ # Other
572
+ reverse_normvect(i) # Reverse normal direction of the i-th face
573
+ generate_line(color) # Generate edges from face data
574
+ triangulation() # Triangulate faces
575
+ get_center() # Calculate and return the scene center point
576
+ ```
577
+
578
+ ---
579
+
580
+ ### Plot3D Object
581
+
582
+ Object for drawing 3D function graphs, similar to Scene but data generation depends on the target function.
583
+
584
+ #### Attributes
585
+
586
+ | Attribute | Default | Description |
587
+ |-----------|---------|-------------|
588
+ | `xlim` | `[-10, 10]` | X domain |
589
+ | `ylim` | `[-10, 10]` | Y domain |
590
+ | `step` | `1` | Sampling step |
591
+ | `line` | `[]` | Edge data |
592
+ | `face` | `[]` | Face data |
593
+ | `center` | `[0,0,0]` | Center point |
594
+
595
+ #### Methods
596
+
597
+ ```python
598
+ generate_face(func, color=True) # Generate face data for the function (auto color by height)
599
+ generate_line(func, color) # Generate edge data for the function
600
+ rotate(rotate_vector, center) # Rotate
601
+ move(move_vector) # Translate
602
+ scale(scale_vector, center) # Scale
603
+ # Same depth sorting methods as Scene
604
+ ```
605
+
606
+ ---
607
+
608
+ ### Volume Object
609
+
610
+ Volume calculation object using ray casting to determine if a point is inside a closed triangular mesh.
611
+
612
+ #### Attributes
613
+
614
+ | Attribute | Default | Description |
615
+ |-----------|---------|-------------|
616
+ | `points` | `[]` | List of interior points after calculation |
617
+ | `sample_distance` | `1` | Sampling grid spacing |
618
+ | `grid_limit` | `inf` | Threshold for enabling partitioning acceleration (triangle count) |
619
+ | `check` | `True` | Enable multi-directional check |
620
+ | `allow_edge` | `True` | Allow counting edge intersections |
621
+
622
+ #### Methods
623
+
624
+ ```python
625
+ volume(scene_face_data) # Calculate volume, return all interior points
626
+ ```
627
+
628
+ > ⚠️ The partitioning acceleration (`grid_limit`) is only recommended for convex polyhedra; irregular shapes may produce erroneous results.
629
+
630
+ ---
631
+
632
+ ## 🧪 Experimental: Rasterization
633
+
634
+ Raster algorithm is experimental and not yet stable.
635
+
636
+ ```python
637
+ scene.triangulation() # Triangulate faces (raster mode only supports triangles)
638
+ camera.grating_size = [500, 400] # Set rendering area size
639
+ camera.show_grating_limit() # Show rendering area border
640
+ camera.grating(face) # Execute raster calculation
641
+ ```
642
+
643
+ In rendering mode `rend=1`, raster mode does not use shadow calculation but computes the light path.
644
+
645
+ ---
646
+
647
+ ## 🎬 Image & Video Export
648
+
649
+ Since turtle itself does not support image capture, the library provides OpenCV-based image/video export:
650
+
651
+ ```python
652
+ # Initialization
653
+ camera.image_size = [500, 400]
654
+ camera.create_image('#ffffff') # Create image (can be called repeatedly to clear)
655
+
656
+ # Rendering
657
+ camera.draw_from_scene_cv2(scene_data) # Render with OpenCV
658
+
659
+ # Export
660
+ camera.imwrite('output.png') # Save image
661
+
662
+ # Video creation
663
+ camera.capture('frames', i) # Save frames by index → ./frames/00000001.png
664
+ camera.to_video('frames') # Compose video → frames.mp4
665
+ ```
666
+
667
+ ---
668
+
669
+ ## 📁 Project Structure
670
+
671
+ ```
672
+ turtleGL-3d/
673
+ ├── pyproject.toml
674
+ ├── setup.py
675
+ ├── LICENSE
676
+ ├── README.md
677
+ ├── README_zh.md
678
+ └── src/
679
+ └── turtleGL/
680
+ ├── __init__.py
681
+ ├── src/
682
+ │ ├── camera.py # Camera object
683
+ │ ├── scene.py # Scene object
684
+ │ ├── plot3d.py # 3D function plot object
685
+ │ └── volume.py # Volume calculation object
686
+ └── example/
687
+ ```
688
+
689
+ ---
690
+
691
+ ## 📄 License
692
+
693
+ This project is licensed under the Apache License 2.0 — see the [LICENSE](LICENSE) file for details.
694
+
695
+ ---
696
+
697
+ ## 🔗 Links
698
+
699
+ - **Homepage**: [https://github.com/MichaelHyan/turtleGL](https://github.com/MichaelHyan/turtleGL)
700
+ - **PyPI**: [https://pypi.org/project/TurtleGL-3d/](https://pypi.org/project/TurtleGL-3d/)