ソースを参照

Add files via upload

0000OOOO0000 5 年 前
コミット
774f049e12
コミット者のEメールアドレスに関連付けられたアカウントが存在しません
共有52 個のファイルを変更した19571 個の追加0 個の削除を含む
  1. 2
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/BOOKMARKS.TXT
  2. 1
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/PLATFORM_SUPPORT.TXT
  3. 1
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/RECENT-FILES.TXT
  4. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/STARTUP.BLEND
  5. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/USERPREF.BLEND
  6. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/DATAFILES/STUDIOLIGHTS/MATCAP/ЯXƎ..O_PAϽTAM_O.LƧO.O_REDAHS_ETIHW_TNEIDARG_ENISOC_TOOR_REWOP_57864084_91_O_19_48046875_POWER_ROOT_COSINE_GRADIENT_WHITE_SHADER_O.OSL.O_MATCAP_O..EXR
  7. 48
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/DATAFILES/STUDIOLIGHTS/STUDIO/LƧ.SL
  8. 1304
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ADD_MESH_CLUSTER.PY
  9. 164
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_CALC_FUNC.PY
  10. 1223
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY
  11. 219
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_OPERATORS.PY
  12. 210
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_PANEL.PY
  13. 103
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/CFG.PY
  14. 68
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__INIT__.PY
  15. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_CALC_FUNC.CPYTHON-37.PYC
  16. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_INTERFACE.CPYTHON-37.PYC
  17. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_OPERATORS.CPYTHON-37.PYC
  18. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_PANEL.CPYTHON-37.PYC
  19. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/CFG.CPYTHON-37.PYC
  20. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/__INIT__.CPYTHON-37.PYC
  21. 298
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/MESH_SOLIDIFY_WIREFRAME.PY
  22. 421
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/OBJECT_RENDER_WIRE.PY
  23. 158
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/PRECISE_RENDER_BORDER_ADJUST_V1-3.PY
  24. 307
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/RENDER-BORDER.PY
  25. 125
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/RA_DRAW_UI.PY
  26. 666
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__INIT__.PY
  27. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__PYCACHE__/RA_DRAW_UI.CPYTHON-37.PYC
  28. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__PYCACHE__/__INIT__.CPYTHON-37.PYC
  29. 1360
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/SPACE_VIEW_3D_DISPLAY_TOOLS.PY
  30. 3235
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/COLORS_GROUPS_EXCHANGER.PY
  31. 345
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/DUAL_MESH.PY
  32. 488
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/GCODE_EXPORT.PY
  33. 477
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/LATTICE.PY
  34. 54
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/NUMBA_FUNCTIONS.PY
  35. 40
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/README.MD
  36. 4280
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/TESSELLATE_NUMPY.PY
  37. 462
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/UTILS.PY
  38. 178
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/UV_TO_MESH.PY
  39. 151
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__INIT__.PY
  40. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/COLORS_GROUPS_EXCHANGER.CPYTHON-37.PYC
  41. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/DUAL_MESH.CPYTHON-37.PYC
  42. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/GCODE_EXPORT.CPYTHON-37.PYC
  43. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/LATTICE.CPYTHON-37.PYC
  44. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/NUMBA_FUNCTIONS.CPYTHON-37.PYC
  45. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/TESSELLATE_NUMPY.CPYTHON-37.PYC
  46. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/UTILS.CPYTHON-37.PYC
  47. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/UV_TO_MESH.CPYTHON-37.PYC
  48. バイナリ
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/__INIT__.CPYTHON-37.PYC
  49. 86
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/__INIT__.PY
  50. 1
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/PRESETS/BKIT.JSON
  51. 1489
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/PRESETS/INTERFACE_THEME/⠀.XML
  52. 1607
    0
      ◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/PRESETS/KEYCONFIG/YP.O_PAMYEK_REDNELB_O_BLENDER_KEYMAP_O.PY

+ 2
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/BOOKMARKS.TXT ファイルの表示

@@ -0,0 +1,2 @@
1
+[Bookmarks]
2
+[Recent]

+ 1
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/PLATFORM_SUPPORT.TXT ファイルの表示

@@ -0,0 +1 @@
1
+{NVIDIA Corporation/GeForce GTX 460/PCIe/SSE2/4.5.0 NVIDIA 391.35}=SUPPORTED

+ 1
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/RECENT-FILES.TXT ファイルの表示

@@ -0,0 +1 @@
1
+

バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/STARTUP.BLEND ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/CONFIG/USERPREF.BLEND ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/DATAFILES/STUDIOLIGHTS/MATCAP/ЯXƎ..O_PAϽTAM_O.LƧO.O_REDAHS_ETIHW_TNEIDARG_ENISOC_TOOR_REWOP_57864084_91_O_19_48046875_POWER_ROOT_COSINE_GRADIENT_WHITE_SHADER_O.OSL.O_MATCAP_O..EXR ファイルの表示


+ 48
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/DATAFILES/STUDIOLIGHTS/STUDIO/LƧ.SL ファイルの表示

@@ -0,0 +1,48 @@
1
+version 1
2
+light_ambient.x 0.000000
3
+light_ambient.y 0.000000
4
+light_ambient.z 0.000000
5
+light[0].flag 1
6
+light[0].smooth 0.000000
7
+light[0].col.x 1.000000
8
+light[0].col.y 1.000000
9
+light[0].col.z 1.000000
10
+light[0].spec.x 0.000000
11
+light[0].spec.y 0.000000
12
+light[0].spec.z 0.000000
13
+light[0].vec.x -0.000000
14
+light[0].vec.y -0.000000
15
+light[0].vec.z 1.000000
16
+light[1].flag 0
17
+light[1].smooth 0.000000
18
+light[1].col.x 0.521083
19
+light[1].col.y 0.538226
20
+light[1].col.z 0.538226
21
+light[1].spec.x 0.599030
22
+light[1].spec.y 0.599030
23
+light[1].spec.z 0.599030
24
+light[1].vec.x -0.406780
25
+light[1].vec.y 0.203390
26
+light[1].vec.z 0.890597
27
+light[2].flag 0
28
+light[2].smooth 0.478261
29
+light[2].col.x 0.038403
30
+light[2].col.y 0.034357
31
+light[2].col.z 0.049530
32
+light[2].spec.x 0.106102
33
+light[2].spec.y 0.125981
34
+light[2].spec.z 0.158523
35
+light[2].vec.x -0.135593
36
+light[2].vec.y 0.101695
37
+light[2].vec.z 0.985532
38
+light[3].flag 0
39
+light[3].smooth 0.200000
40
+light[3].col.x 0.090838
41
+light[3].col.y 0.082080
42
+light[3].col.z 0.072255
43
+light[3].spec.x 0.106535
44
+light[3].spec.y 0.084771
45
+light[3].spec.z 0.066080
46
+light[3].vec.x 0.624519
47
+light[3].vec.y -0.562067
48
+light[3].vec.z -0.542269

+ 1304
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ADD_MESH_CLUSTER.PY
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 164
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_CALC_FUNC.PY ファイルの表示

@@ -0,0 +1,164 @@
1
+# -*- coding: utf-8 -*-
2
+import bpy
3
+import math
4
+import random
5
+
6
+from mathutils import Matrix
7
+from mathutils import Vector
8
+
9
+from . import cfg
10
+
11
+
12
+def at_random_fill(min, max):
13
+    first = random.uniform(min, max)
14
+    second = random.uniform(min, max)
15
+    if first <= second:
16
+        return(first, second)
17
+    else:
18
+        return(second, first)
19
+
20
+
21
+def at_random(seed, totalc, totalr, mint, maxt, mins, maxs, minr, maxr, btr, bsc, brot, uniform,
22
+    tr1, tr2, sc1, sc2, r1, r2, pivot, varia, valign):
23
+    """Random function for translation, scale and rotation,
24
+        seed : seed for random
25
+        totalc : number of elements in column
26
+        totalr : number of elements in row
27
+        mint : minimum for translation
28
+        maxt : maximum for translation
29
+        mins : minimum for scale
30
+        maxs : maximum for scale
31
+        minr : minimum for rotation
32
+        maxr : maximun for rotation
33
+        btr : (boolean) use translation or not
34
+        bsc : (boolean) use scale or not
35
+        brot : (boolean) use rotation or not
36
+        uniform : (boolean) use uniform scale or not
37
+        tr1 : translation offset of the column
38
+        tr2 : translation offset of the row
39
+        sc1 : scale offset of the column
40
+        sc2 : scale offset of the row
41
+        r1 : rotation offset of the column
42
+        r2 : rotation offset of the row
43
+        pivot : pivot
44
+        varia : variation of rows
45
+        valign : Vector of align of rows
46
+    """
47
+    random.seed(seed)
48
+    tr, sc, rot = [0, 0, 0], [0, 0, 0], [0, 0, 0]
49
+    xyz_vec = (x_axis(), y_axis(), z_axis())
50
+    ref_name = cfg.atools_objs[0][0]
51
+    for j in range(totalr):
52
+        for k in range(totalc + j*varia):
53
+            elem_name = cfg.atools_objs[j][k]
54
+            if elem_name == ref_name:
55
+                continue
56
+            elem = bpy.data.objects[elem_name]
57
+            for i in range(3):
58
+                tr[i] = random.uniform(mint[i], maxt[i])
59
+                sc[i] = random.uniform(mins[i]/100, maxs[i]/100)
60
+                rot[i] = random.uniform(minr[i], maxr[i])
61
+            if uniform:
62
+                    sc[0] = sc[1] = sc[2]
63
+            mt = Matrix.Translation(tr)
64
+            ms = Matrix.Scale(sc[0], 4, (1, 0, 0)) @ Matrix.Scale(sc[1], 4, (0, 1, 0)) @ Matrix.Scale(sc[2], 4, (0, 0, 1))
65
+            mr = Matrix.Rotation(rot[0], 4, (1, 0, 0)) @ Matrix.Rotation(rot[1], 4, (0, 1, 0)) @ Matrix.Rotation(rot[2], 4, (0, 0, 1))
66
+
67
+            # recalculate the position...
68
+            vt, vs, vr = tsr(cfg.ref_mtx, k, j, tr1, tr2, sc1, sc2, Vector(r1), Vector(r2), valign)
69
+            
70
+            if pivot is not None:
71
+                emat = at_all_in_one(cfg.ref_mtx, vr, xyz_vec, vt, vs, pivot.location)
72
+            else:
73
+                emat = at_all_in_one(cfg.ref_mtx, vr, xyz_vec, vt, vs, cfg.ref_mtx.translation)
74
+            elem.matrix_world = emat
75
+            if btr:
76
+                elem.matrix_world @= mt
77
+            if bsc:
78
+                elem.matrix_world @= ms
79
+            if brot:
80
+                elem.matrix_world @= mr
81
+
82
+def x_axis():
83
+    """Get the x axis"""
84
+    return Vector((1.0, 0.0, 0.0))
85
+
86
+
87
+def y_axis():
88
+    """Get the y axis"""
89
+    return Vector((0.0, 1.0, 0.0))
90
+
91
+
92
+def z_axis():
93
+    """Get the z axis"""
94
+    return Vector((0.0, 0.0, 1.0))
95
+
96
+
97
+def xyz_axis():
98
+    """Get the xyz axis"""
99
+    return Vector((1.0, 1.0, 1.0))
100
+
101
+
102
+def at_all_in_one(ref, angle, vecxyz, vec_tr, vec_sc, pivot):
103
+    """Return the matrix of transformations"""
104
+    # Matrix is composed by location @ rotation @ scale
105
+    loc_ref, rot_ref, sc_ref = ref.decompose()
106
+    # ref_location = bpy.data.objects[cfg.atools_objs[0][0]].location
107
+
108
+    loc_ma = Matrix.Translation(loc_ref)
109
+    rot_ma = rot_ref.to_matrix().to_4x4()
110
+    sc_ma = Matrix.Scale(sc_ref[0], 4, (1, 0, 0)) @ Matrix.Scale(sc_ref[1], 4, (0, 1, 0)) @ Matrix.Scale(sc_ref[2], 4, (0, 0, 1))
111
+
112
+    mt = Matrix.Translation(pivot - loc_ref)
113
+    mr = Matrix.Rotation(angle[0], 4, vecxyz[0]) @ Matrix.Rotation(angle[1], 4, vecxyz[1]) @ Matrix.Rotation(angle[2], 4, vecxyz[2])
114
+    mra = mt @ mr @ mt.inverted()
115
+
116
+    trm = Matrix.Translation(vec_tr)
117
+    scm = Matrix.Scale(vec_sc[0], 4, (1, 0, 0)) @ Matrix.Scale(vec_sc[1], 4, (0, 1, 0)) @ Matrix.Scale(vec_sc[2], 4, (0, 0, 1))
118
+
119
+    if pivot == loc_ref:
120
+        mw = loc_ma @ rot_ma @ trm @ scm @ sc_ma @ mr
121
+    else:
122
+        mw = loc_ma @ mra @ rot_ma @ trm @ scm @ sc_ma
123
+    return mw
124
+
125
+
126
+def fill_rotation(context):
127
+    prop = context.scene.arraytools_prop
128
+    offset = prop.rot_offset
129
+
130
+    for i in range(3):
131
+        if offset[i] == 0.0:
132
+            prop.rot_min[i], prop.rot_max[i] = at_random_fill(-math.pi, math.pi)
133
+        else:
134
+            prop.rot_min[i], prop.rot_max[i] = at_random_fill(-offset[i]*2, offset[i]*2)
135
+
136
+
137
+def sum_serie(n, factor):
138
+    """Return the sum of the serie 1+2+3+4+...+n
139
+    with a factor
140
+    """
141
+    return ((n * (n - 1)) / 2) * factor
142
+
143
+
144
+# (T)ranslate (S)cale (R)otation vector
145
+def tsr(mat, col, row, tcol, trow, scol, srow, rcol, rrow, ralign):
146
+    """Retrieve the translation, scale and rotation vector according
147
+    to the position in the array
148
+        mat : matrix of the reference object
149
+        col : position in column
150
+        row : position in row
151
+        tcol : translate offset in column
152
+        trow : translate offset in row
153
+        scol : scale offset in column
154
+        srow : scale offset in row
155
+        rcol : rotation offset in column
156
+        rrow : rotation offset in row
157
+        ralign : row align
158
+    """
159
+    translate = col * tcol + row * trow + row * ralign
160
+    rotate = col * Vector(rcol) + row * Vector(rrow)
161
+    s1 = col * (mat.to_scale() - (scol/100))
162
+    s2 = row * (mat.to_scale() - (srow/100))
163
+    scale = xyz_axis() - s1 - s2
164
+    return translate, scale, rotate

+ 1223
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_INTERFACE.PY
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 219
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_OPERATORS.PY ファイルの表示

@@ -0,0 +1,219 @@
1
+# -*- coding: utf-8 -*-
2
+# ---------------------------- Operators ------------------------
3
+import bpy
4
+import math
5
+
6
+from mathutils import Vector
7
+
8
+from . import cfg
9
+from . import at_interface
10
+from . at_calc_func import at_random_fill, fill_rotation
11
+
12
+
13
+class OBJECT_OT_at_start(bpy.types.Operator):
14
+    """Start and init the addon"""
15
+    bl_idname = 'scene.at_op'
16
+    bl_label = "Start array"
17
+
18
+    @classmethod
19
+    def poll(cls, context):
20
+        return not context.scene.arraytools_prop.already_start
21
+
22
+    def execute(self, context):
23
+        cfg.init_array_tool(context)
24
+        return {'FINISHED'}
25
+
26
+
27
+class OBJECT_OT_at_done(bpy.types.Operator):
28
+    """Apply the settings"""
29
+    bl_idname = 'scene.at_done'
30
+    bl_label = "Done !"
31
+
32
+    def execute(self, context):
33
+        cfg.atools_objs.clear()
34
+        #cfg.at_mtx_list.clear()
35
+        array_col = bpy.data.collections.get(cfg.col_name)
36
+        cfg.col_name = "Array_collection"
37
+        context.scene.arraytools_prop.up_ui_reset()
38
+        context.scene.arraytools_prop.already_start = False
39
+        return {'FINISHED'}
40
+
41
+
42
+class OBJECT_OT_at_cancel(bpy.types.Operator):
43
+    """Cancel the settings"""
44
+    bl_idname = 'scene.at_cancel'
45
+    bl_label = "Cancel"
46
+
47
+    def execute(self, context):
48
+        scn = context.scene
49
+        scn.arraytools_prop.at_del_all(True)
50
+        scn.arraytools_prop.up_ui_reset()
51
+        scn.arraytools_prop.already_start = False
52
+        cfg.col_name = "Array_collection"
53
+        return {'FINISHED'}
54
+
55
+
56
+class OBJECT_OT_fill_tr(bpy.types.Operator):
57
+    """Fill the random translation fields"""
58
+    bl_idname = 'scene.fill_tr'
59
+    bl_label = "Fill"
60
+
61
+    def execute(self, context):
62
+        prop = context.scene.arraytools_prop
63
+        offset = prop.tr_offset
64
+
65
+        for i in range(3):
66
+            if offset[i] == 0.0:
67
+                prop.tr_min[i], prop.tr_max[i] = at_random_fill(-3.0, 3.0)
68
+            else:
69
+                prop.tr_min[i], prop.tr_max[i] = at_random_fill(-offset[i]/2, offset[i]/2)
70
+        return{'FINISHED'}
71
+
72
+
73
+class OBJECT_OT_fill_sc(bpy.types.Operator):
74
+    """Fill the random scale fields"""
75
+    bl_idname = 'scene.fill_sc'
76
+    bl_label = "Fill"
77
+
78
+    def execute(self, context):
79
+        prop = context.scene.arraytools_prop
80
+        offset = prop.sc_offset
81
+
82
+        if 100 in [offset[0], offset[1], offset[2]]:
83
+            prop.sc_min_x, prop.sc_max_x = at_random_fill(40.0, 120.0)
84
+            prop.sc_min_y, prop.sc_max_y = at_random_fill(40.0, 120.0)
85
+            prop.sc_min_z, prop.sc_max_z = at_random_fill(40.0, 120.0)
86
+        else:
87
+            rand = [(100 - offset[i]) / 2 for i in range(3)]
88
+            print(rand)
89
+            prop.sc_min_x, prop.sc_max_x = at_random_fill(offset[0]-rand[0], offset[0]+rand[0])
90
+            prop.sc_min_y, prop.sc_max_y = at_random_fill(offset[1]-rand[1], offset[1]+rand[1])
91
+            prop.sc_min_z, prop.sc_max_z = at_random_fill(offset[2]-rand[2], offset[2]+rand[2])
92
+        if prop.sc_all:
93
+            prop.sc_min_x = prop.sc_min_y = prop.sc_min_z
94
+            prop.sc_max_x = prop.sc_max_y = prop.sc_max_z
95
+        return {'FINISHED'}
96
+
97
+
98
+class OBJECT_OT_fill_rot(bpy.types.Operator):
99
+    """Fill the random rotation fields"""
100
+    bl_idname = 'scene.fill_rot'
101
+    bl_label = "Fill"
102
+
103
+    def execute(self, context):
104
+        fill_rotation(context)
105
+        return {'FINISHED'}
106
+
107
+
108
+class OBJECT_OT_x360(bpy.types.Operator):
109
+    """Quick 360 degrees on X axis"""
110
+    bl_idname = 'scene.x360'
111
+    bl_label = "360"
112
+
113
+    def execute(self, context):
114
+        prop = context.scene.arraytools_prop
115
+        prop.tr_offset = Vector((0.0, 0.0, 0.0))
116
+        prop.rot_global = Vector((math.pi/180*360, 0.0, 0.0))
117
+        return{'FINISHED'}
118
+
119
+
120
+class OBJECT_OT_y360(bpy.types.Operator):
121
+    """Quick 360 degrees on Y axis"""
122
+    bl_idname = 'scene.y360'
123
+    bl_label = "360"
124
+
125
+    def execute(self, context):
126
+        prop = context.scene.arraytools_prop
127
+        prop.tr_offset = Vector((0.0, 0.0, 0.0))
128
+        prop.rot_global = Vector((0.0, math.pi/180*360, 0.0))
129
+        return{'FINISHED'}
130
+
131
+
132
+class OBJECT_OT_z360(bpy.types.Operator):
133
+    """Quick 360 degrees on Z axis"""
134
+    bl_idname = 'scene.z360'
135
+    bl_label = "360"
136
+
137
+    def execute(self, context):
138
+        prop = context.scene.arraytools_prop
139
+        prop.tr_offset = Vector((0.0, 0.0, 0.0))
140
+        prop.rot_global = Vector((0.0, 0.0, math.pi/180*360))
141
+        return{'FINISHED'}
142
+
143
+
144
+class OBJECT_OT_reset_tr(bpy.types.Operator):
145
+    """Reset the settings of random translation"""
146
+    bl_idname = 'scene.at_reset_tr'
147
+    bl_label = 'Reset'
148
+
149
+    def execute(self, context):
150
+        prop = context.scene.arraytools_prop
151
+        prop.tr_min[0], prop.tr_min[1], prop.tr_min[2] = 0.0, 0.0, 0.0
152
+        prop.tr_max[0], prop.tr_max[1], prop.tr_max[2] = 0.0, 0.0, 0.0
153
+
154
+        # if operator is used many times
155
+        # get weird result != 0 with vector
156
+        # prop.tr_max = Vector((0.0, 0.0, 0.0))
157
+        return {'FINISHED'}
158
+
159
+
160
+class OBJECT_OT_reset_sc(bpy.types.Operator):
161
+    """Reset the settings of random scale"""
162
+    bl_idname = 'scene.at_reset_sc'
163
+    bl_label = 'Reset'
164
+
165
+    def execute(self, context):
166
+        prop = context.scene.arraytools_prop
167
+        prop.sc_min_x, prop.sc_min_y, prop.sc_min_z = 100, 100, 100
168
+        prop.sc_max_x, prop.sc_max_y, prop.sc_max_z = 100, 100, 100
169
+        return{'FINISHED'}
170
+
171
+
172
+class OBJECT_OT_reset_rot(bpy.types.Operator):
173
+    """Reset the settings of random rotation"""
174
+    bl_idname = 'scene.at_reset_rot'
175
+    bl_label = 'Reset'
176
+
177
+    def execute(self, context):
178
+        prop = context.scene.arraytools_prop
179
+        prop.rot_min[0], prop.rot_min[1], prop.rot_min[2] = 0.0, 0.0, 0.0
180
+        prop.rot_max[0], prop.rot_max[1], prop.rot_max[2] = 0.0, 0.0, 0.0
181
+        return{'FINISHED'}
182
+
183
+
184
+class OBJECT_OT_reset_second(bpy.types.Operator):
185
+    """Reset the settings of row options"""
186
+    bl_idname = 'scene.at_reset_second'
187
+    bl_label = 'Reset'
188
+
189
+    def execute(self, context):
190
+        prop = context.scene.arraytools_prop
191
+        prop.tr_second = (0,0,0)
192
+        prop.sc_second = (100,100,100)
193
+        prop.rot_second = (0,0,0)
194
+        return {'FINISHED'}
195
+
196
+
197
+class OBJECT_OT_error(bpy.types.Operator):
198
+    """Draw a message box to display error"""
199
+    bl_idname = "info.at_error"
200
+    bl_label = "Message info"
201
+
202
+    info: bpy.props.StringProperty(
203
+        name = "Message",
204
+        description = "Display a message",
205
+        default = ''
206
+    )
207
+
208
+    def execute(self, context):
209
+        self.report({'INFO'}, self.info)
210
+        print(self.info)
211
+        return {'FINISHED'}
212
+
213
+    def invoke(self, context, event):
214
+        return context.window_manager.invoke_props_dialog(self)
215
+
216
+    def draw(self, context):
217
+        layout = self.layout
218
+        layout.label(text=self.info)
219
+        layout.label(text="")

+ 210
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/AT_PANEL.PY ファイルの表示

@@ -0,0 +1,210 @@
1
+# -*- coding: utf-8 -*-
2
+from bpy.types import Panel
3
+
4
+from . import cfg
5
+
6
+# ---------------------------- Panel --------------------------------
7
+class UIPANEL_PT_def(Panel):
8
+    bl_space_type = "VIEW_3D"
9
+    bl_region_type = "UI"
10
+    bl_category = "Array Tools"
11
+
12
+
13
+class UIPANEL_PT_trans(UIPANEL_PT_def):
14
+    """Panel containing the settings for translation, scale and rotation array"""
15
+    bl_label = "Array Tools"
16
+
17
+    @classmethod
18
+    def poll(cls, context):
19
+        return (len(context.selected_objects) > 0 and (context.object.mode == 'OBJECT'))
20
+
21
+    def draw(self, context):
22
+        layout = self.layout
23
+        scn = context.scene
24
+        my_prop = scn.arraytools_prop
25
+
26
+        row = layout.row()
27
+        row.operator('scene.at_op')
28
+        row = layout.row()
29
+        if not my_prop.already_start:
30
+            row.alignment = 'CENTER'
31
+            row.label(text="~ Click to begin ~")
32
+        else:
33
+            row.prop(my_prop, 'is_copy')
34
+            row.prop(my_prop, 'count')
35
+            box = layout.box()
36
+            box.label(text="Translation")
37
+            col = box.column()
38
+            split = col.split()
39
+            split.prop(my_prop, 'tr_offset')
40
+            split.prop(my_prop, 'tr_global')
41
+
42
+            row = layout.row()
43
+            row.prop(my_prop, 'at_pivot')
44
+
45
+            box = layout.box()
46
+            box.label(text="Scaling (%)")
47
+            col = box.column()
48
+            split = col.split()
49
+            split.prop(my_prop, 'sc_offset')
50
+            split.prop(my_prop, 'sc_global')
51
+
52
+            box = layout.box()
53
+            if scn.unit_settings.system_rotation == 'DEGREES':
54
+                box.label(text="Rotation (degrees)")
55
+            else:
56
+                box.label(text="Rotation (radians)")
57
+            split = box.split(factor=0.08)
58
+
59
+            col = split.column(align=True)
60
+            col.label(text='')
61
+            col.operator('scene.x360', text='X')
62
+            col.operator('scene.y360', text='Y')
63
+            col.operator('scene.z360', text='Z')
64
+
65
+            col = split.column()
66
+            col.prop(my_prop, 'rot_offset')
67
+            col = split.column()
68
+            col.prop(my_prop, 'rot_global')
69
+
70
+            box = layout.box()
71
+            row = box.row()
72
+            row.scale_y = 1.5
73
+            row.operator('scene.at_done')
74
+            row.operator('scene.at_cancel')
75
+
76
+            row = box.row()
77
+            row.scale_y = 0.3
78
+            row.alignment = 'CENTER'
79
+            row.label(text="~ Tansforms are NOT applied ~")
80
+
81
+
82
+class UIPANEL_PT_rows(UIPANEL_PT_def):
83
+    """Panel containing the row options"""
84
+    bl_parent_id = 'UIPANEL_PT_trans'
85
+    bl_label = 'Rows options'
86
+    bl_options = {'DEFAULT_CLOSED'}
87
+
88
+    def draw(self, context):
89
+        layout = self.layout
90
+        my_prop = context.scene.arraytools_prop
91
+
92
+        if my_prop.already_start:
93
+            row = layout.row()
94
+            row.prop(my_prop, 'count')
95
+            row.prop(my_prop, 'row')
96
+            row = layout.row()
97
+
98
+            row.scale_y = 0.8
99
+            row.prop(my_prop, 'align', icon_only=True, expand=True)
100
+            row.prop(my_prop, 'alter')
101
+            row = layout.row()
102
+
103
+            row.alignment = 'CENTER'
104
+            row.scale_x = 1.5
105
+            row.scale_y = 0.6
106
+            row.label(text=" - Offset settings -")
107
+            row.scale_x = 0.8
108
+            row.operator('scene.at_reset_second')
109
+
110
+            layout.use_property_split = True
111
+
112
+            col = layout.column()
113
+            row = col.row(align=True)
114
+            row.prop(my_prop, 'tr_second')
115
+            col = layout.column()
116
+            row = col.row(align=True)
117
+            row.prop(my_prop, 'sc_second')
118
+            col = layout.column()
119
+            row = col.row(align=True)
120
+            row.prop(my_prop, 'rot_second')
121
+
122
+            row = layout.row()
123
+            row.scale_y = 0.5
124
+            row.label(text="Total : " + my_prop.total + "    |    current row : " + my_prop.erow)
125
+            """
126
+            box = layout.box()
127
+            box.prop(my_prop, 'tr_second')
128
+            #row = layout.row()
129
+            box.prop(my_prop, 'sc_second')
130
+            #row = layout.row()
131
+            box.prop(my_prop, 'rot_second')
132
+            """
133
+
134
+
135
+class UIPANEL_PT_options(UIPANEL_PT_def):
136
+    """Panel containing the random options"""
137
+    bl_parent_id = 'UIPANEL_PT_trans'
138
+    bl_label = 'Random options'
139
+    bl_options = {'DEFAULT_CLOSED'}
140
+
141
+    def draw(self, context):
142
+        layout = self.layout
143
+        my_prop = context.scene.arraytools_prop
144
+
145
+        layout.enabled = my_prop.already_start
146
+        row = layout.row()
147
+        row.alignment = 'CENTER'
148
+        row.prop(my_prop, 'at_seed')
149
+        row = layout.row()
150
+        row.prop(my_prop, 'at_mode', expand=True)
151
+        row = layout.row()
152
+        if my_prop.at_mode == 'SIM':
153
+            row.prop(my_prop, 'at_is_tr')
154
+            row = layout.row()
155
+            row.prop(my_prop, 'tr_rand')
156
+            row = layout.row()
157
+            row.prop(my_prop, 'at_is_sc')
158
+            row = layout.row()
159
+            row.prop(my_prop, 'sc_rand')
160
+            row = layout.row()
161
+            row.prop(my_prop, 'at_is_rot')
162
+            row = layout.row()
163
+            row.prop(my_prop, 'rot_rand')
164
+        else:
165
+            row.label(text='  ')
166
+            row.label(text='X')
167
+            row.label(text='Y')
168
+            row.label(text='Z')
169
+            row = layout.row()
170
+            row.prop(my_prop, 'at_is_tr')
171
+            row.scale_x = 0.5
172
+            row.scale_y = 0.7
173
+            row.operator('scene.at_reset_tr')
174
+            row.operator('scene.fill_tr')
175
+            row = layout.row()
176
+            row.prop(my_prop, 'tr_min')
177
+            row = layout.row()
178
+            row.prop(my_prop, 'tr_max')
179
+            row = layout.row()
180
+
181
+            row.prop(my_prop, 'at_is_sc')
182
+            row.scale_x = 0.5
183
+            row.scale_y = 0.7
184
+            row.operator('scene.at_reset_sc')
185
+            row.operator('scene.fill_sc')
186
+            row = layout.row()
187
+            row.alignment = "CENTER"
188
+            row.scale_y = 0.7
189
+            row.prop(my_prop, 'sc_all')
190
+            row = layout.row(align=True)
191
+            row.label(text='min:')
192
+            row.prop(my_prop, 'sc_min_x', text='')
193
+            row.prop(my_prop, 'sc_min_y', text='')
194
+            row.prop(my_prop, 'sc_min_z', text='')
195
+            row = layout.row(align=True)
196
+            row.label(text='max:')
197
+            row.prop(my_prop, 'sc_max_x', text='')
198
+            row.prop(my_prop, 'sc_max_y', text='')
199
+            row.prop(my_prop, 'sc_max_z', text='')
200
+
201
+            row = layout.row()
202
+            row.prop(my_prop, "at_is_rot")
203
+            row.scale_x = 0.5
204
+            row.scale_y = 0.7
205
+            row.operator('scene.at_reset_rot')
206
+            row.operator('scene.fill_rot')
207
+            row = layout.row()
208
+            row.prop(my_prop, 'rot_min')
209
+            row = layout.row()
210
+            row.prop(my_prop, 'rot_max')

+ 103
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/CFG.PY ファイルの表示

@@ -0,0 +1,103 @@
1
+# -*- coding: utf-8 -*-
2
+import bpy
3
+
4
+# count values, contains only 2 values : old count and current
5
+at_count_values = []
6
+# row value, contains old row and current
7
+at_row_values = []
8
+# alter values, contains old and current
9
+at_alter = []
10
+# maximun row according to column and alter 
11
+maxrow = 1
12
+# list of the copies / list of lists
13
+atools_objs = []
14
+ref_mtx = [] # reference matrix
15
+# collection name
16
+col_name = "Array_collection"
17
+
18
+
19
+def init_array_tool(context):
20
+    """Initialisation of the array tools"""
21
+    global at_count_values
22
+    global at_row_values
23
+    global at_alter
24
+    global atools_objs
25
+    global ref_mtx
26
+    global col_name
27
+
28
+    prop = context.scene.arraytools_prop
29
+    name = col_name
30
+    i = 1
31
+    collect = bpy.data.collections.get(col_name)
32
+    # create and link the new collection
33
+    if collect is None:
34
+        array_col = bpy.data.collections.new(col_name)
35
+        bpy.context.scene.collection.children.link(array_col)
36
+    else:
37
+        # if a collection already exist, create a new one
38
+        while bpy.data.collections.get(name) is not None:
39
+            name = col_name + str(i)
40
+            i += 1
41
+        array_col = bpy.data.collections.new(name)
42
+        bpy.context.scene.collection.children.link(array_col)
43
+        col_name = name
44
+
45
+    if not prop.already_start:
46
+        at_count_values = [1, 2]
47
+        at_row_values = [0, 1]
48
+        at_alter = [0, 0]
49
+        active = context.active_object
50
+        prop.already_start = True
51
+        prop.is_tr_off_last = True
52
+        if active is not None:
53
+            atools_objs.append([active.name])
54
+            ref_mtx = active.matrix_world.copy()
55
+            del active
56
+            prop.add_in_column(prop.row)
57
+        # no need anymore
58
+        else:
59
+            print("No object selected")
60
+    else:
61
+        print("Already started!")
62
+
63
+
64
+def add_count(value):
65
+    """Save the current count"""
66
+    global at_count_values
67
+    at_count_values.append(value)
68
+
69
+
70
+def del_count():
71
+    """Del the previous count"""
72
+    global at_count_values
73
+    del at_count_values[0]
74
+
75
+
76
+def add_row(value):
77
+    """Save the current row"""
78
+    global at_row_values
79
+    at_row_values.append(value)
80
+
81
+
82
+def del_row():
83
+    """ Del the previous row value"""
84
+    global at_row_values
85
+    del at_row_values[0]
86
+
87
+
88
+def add_alter(value):
89
+    """save the current variation"""
90
+    global at_alter
91
+    at_alter.append(value)
92
+
93
+
94
+def del_alter():
95
+    """Remove previous variation"""
96
+    global at_alter
97
+    del at_alter[0]
98
+
99
+
100
+def display_error(msg):
101
+    """Call the operator to display an error message"""
102
+    bpy.ops.info.at_error('INVOKE_DEFAULT', info = msg)
103
+

+ 68
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__INIT__.PY ファイルの表示

@@ -0,0 +1,68 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+# This program is free software; you can redistribute it and/or modify
4
+# it under the terms of the GNU General Public License as published by
5
+# the Free Software Foundation; either version 3 of the License, or
6
+# (at your option) any later version.
7
+#
8
+# This program is distributed in the hope that it will be useful, but
9
+# WITHOUT ANY WARRANTY; without even the implied warranty of
10
+# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+# General Public License for more details.
12
+#
13
+# You should have received a copy of the GNU General Public License
14
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+import bpy
16
+
17
+from . import cfg
18
+from . import at_interface
19
+
20
+bl_info = {
21
+    "name": "Array_tools",
22
+    "author": "Elreenys",
23
+    "description": "Tools to create array of objects",
24
+    "blender": (2, 80, 0),
25
+    "version": (1, 2, 1),
26
+    "location": "View3D > sidebar > array tools tab",
27
+    "category": "Object"
28
+}
29
+
30
+classes = (
31
+    at_operators.OBJECT_OT_at_start,
32
+    at_operators.OBJECT_OT_at_cancel,
33
+    at_operators.OBJECT_OT_at_done,
34
+    at_operators.OBJECT_OT_fill_tr,
35
+    at_operators.OBJECT_OT_fill_sc,
36
+    at_operators.OBJECT_OT_fill_rot,
37
+    at_operators.OBJECT_OT_x360,
38
+    at_operators.OBJECT_OT_y360,
39
+    at_operators.OBJECT_OT_z360,
40
+    at_operators.OBJECT_OT_reset_tr,
41
+    at_operators.OBJECT_OT_reset_sc,
42
+    at_operators.OBJECT_OT_reset_rot,
43
+    at_operators.OBJECT_OT_reset_second,
44
+    at_operators.OBJECT_OT_error,
45
+    at_panel.UIPANEL_PT_trans,
46
+    at_panel.UIPANEL_PT_rows,
47
+    at_panel.UIPANEL_PT_options,
48
+    at_interface.ArrayTools_props
49
+)
50
+
51
+
52
+def register():
53
+    scene = bpy.types.Scene
54
+    pp = bpy.props.PointerProperty
55
+
56
+    for cls in classes:
57
+        bpy.utils.register_class(cls)
58
+    scene.arraytools_prop = pp(type=at_interface.ArrayTools_props)
59
+
60
+
61
+def unregister():
62
+    del bpy.types.Scene.arraytools_prop
63
+    for cls in reversed(classes):
64
+        bpy.utils.unregister_class(cls)
65
+
66
+
67
+if __name__ == '__main__':
68
+    register()

バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_CALC_FUNC.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_INTERFACE.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_OPERATORS.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/AT_PANEL.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/CFG.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/ARRAY_TOOLS_1-2-1/__PYCACHE__/__INIT__.CPYTHON-37.PYC ファイルの表示


+ 298
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/MESH_SOLIDIFY_WIREFRAME.PY ファイルの表示

@@ -0,0 +1,298 @@
1
+#!BPY
2
+
3
+bl_info = {
4
+    "name": "Solidify Wireframe",
5
+    "author": "Yorik van Havre, Alejandro Sierra, Howard Trickey",
6
+    "description": "Turns the selected edges of a mesh into solid geometry",
7
+    "version": (2, 3),
8
+    "blender": (2, 5, 8),
9
+    "category": "Mesh",
10
+    "location": "Mesh > Solidify Wireframe",
11
+    "warning": '',
12
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Modeling/Solidify_Wireframe",
13
+    "tracker_url": "http://projects.blender.org/tracker/?func=detail&group_id=153&aid=26997&atid=467",
14
+    }
15
+
16
+# ***** BEGIN GPL LICENSE BLOCK *****
17
+#
18
+# This program is free software; you can redistribute it and/or
19
+# modify it under the terms of the GNU General Public License
20
+# as published by the Free Software Foundation; either version 2
21
+# of the License, or (at your option) any later version.
22
+#
23
+# This program is distributed in the hope that it will be useful,
24
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See th
26
+# GNU General Public License for more details.
27
+#
28
+# You should have received a copy of the GNU General Public License
29
+# along with this program; if not, write to the Free Software Foundation,
30
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31
+#
32
+# ***** END GPL LICENCE BLOCK *****
33
+
34
+import bpy, mathutils
35
+
36
+cube_faces = [ [0,3,2,1], [5,6,7,4], [0,1,5,4],
37
+               [7,6,2,3], [2,6,5,1], [0,4,7,3] ]
38
+cube_normals = [ mathutils.Vector((0,0,-1)),
39
+                 mathutils.Vector((0,0,1)),
40
+                 mathutils.Vector((0,-1,0)),
41
+                 mathutils.Vector((0,1,0)),
42
+                 mathutils.Vector((1,0,0)),
43
+                 mathutils.Vector((-1,0,0)) ]
44
+
45
+def create_cube(me, v, d):
46
+    x = v.co.x
47
+    y = v.co.y
48
+    z = v.co.z
49
+    coords=[ [x-d,y-d,z-d], [x+d,y-d,z-d], [x+d,y+d,z-d], [x-d,y+d,z-d],
50
+         [x-d,y-d,z+d], [x+d,y-d,z+d], [x+d,y+d,z+d], [x-d,y+d,z+d] ]
51
+    for coord in coords:
52
+        me.vertices.add(1)
53
+        me.vertices[-1].co = mathutils.Vector(coord)
54
+
55
+def norm_dot(e, k, fnorm, me):
56
+    v = me.vertices[e[1]].co - me.vertices[e[0]].co
57
+    if k == 1:
58
+        v = -v
59
+    v.normalize()
60
+    return v * fnorm
61
+
62
+def fill_cube_face(me, index, f):
63
+    return [index + cube_faces[f][i] for i in range(4)]
64
+
65
+# Coords of jth point of face f in cube instance i
66
+def cube_face_v(me, f, i, j):
67
+    return me.vertices[i + cube_faces[f][j]].co
68
+
69
+def cube_face_center(me, f, i):
70
+    return 0.5 * (cube_face_v(me, f, i, 0) + \
71
+                  cube_face_v(me, f, i, 2))
72
+
73
+# Return distance between points on two faces when
74
+# each point is projected onto the plane that goes through
75
+# the face center and is perpendicular to the line
76
+# through the face centers.
77
+def projected_dist(me, i1, i2, f1, f2, j1, j2):
78
+    f1center = cube_face_center(me, f1, i1)
79
+    f2center = cube_face_center(me, f2, i2)
80
+    axis_norm = (f2center - f1center).normalized()
81
+    v1 = cube_face_v(me, f1, i1, j1)
82
+    v2 = cube_face_v(me, f2, i2, j2)
83
+    v1proj = v1 - (axis_norm * (v1 - f1center)) * axis_norm
84
+    v2proj = v2 - (axis_norm * (v2 - f2center)) * axis_norm
85
+    return (v2proj - v1proj).length
86
+
87
+def skin_edges(me, i1, i2, f1, f2):
88
+    # Connect verts starting at i1 forming cube face f1
89
+    # to those starting at i2 forming cube face f2.
90
+    # Need to find best alignment to avoid a twist.
91
+    shortest_length = 1e6
92
+    f2_start_index = 0
93
+    for i in range(4):
94
+        x = projected_dist(me, i1, i2, f1, f2, 0, i)
95
+        if x < shortest_length:
96
+            shortest_length = x
97
+            f2_start_index = i
98
+    ans = []
99
+    j = f2_start_index
100
+    for i in range(4):
101
+        fdata = [i1 + cube_faces[f1][i],
102
+                 i2 + cube_faces[f2][j],
103
+                 i2 + cube_faces[f2][(j + 1) % 4],
104
+                 i1 + cube_faces[f1][(i - 1) % 4]]
105
+        if fdata[3] == 0:
106
+            fdata = [fdata[3]] + fdata[0:3]
107
+        ans.extend(fdata)
108
+        j = (j - 1) % 4
109
+    return ans
110
+            
111
+
112
+# Return map: v -> list of length len(node_normals) where
113
+# each element of the list is either None (no assignment)
114
+# or ((v0, v1), 0 or 1) giving an edge and direction that face is assigned to.
115
+def find_assignment(me, edges, vert_edges, node_normals):
116
+    nf = len(node_normals)
117
+    feasible = {}
118
+    for e in edges:
119
+        for k in (0, 1):
120
+            fds = [(f, norm_dot(e, k, node_normals[f], me)) for f in range(nf)]
121
+            feasible[(e, k)] = [fd for fd in fds if fd[1] > 0.01]
122
+    assignment = {}
123
+    for v, ves in vert_edges.items():
124
+        assignment[v] = best_assignment(ves, feasible, nf)
125
+    return assignment
126
+
127
+def best_assignment(ves, feasible, nf):
128
+    apartial = [ None ] * nf
129
+    return best_assign_help(ves, feasible, apartial, 0.0)[0]
130
+
131
+def best_assign_help(ves, feasible, apartial, sumpartial):
132
+    if len(ves) == 0:
133
+        return (apartial, sumpartial)
134
+    else:
135
+        ek0 = ves[0]
136
+        vesrest = ves[1:]
137
+        feas = feasible[ek0]
138
+        bestsum = 0
139
+        besta = None
140
+        for (f, d) in feas:
141
+            if apartial[f] is None:
142
+                ap = apartial[:]
143
+                ap[f] = ek0
144
+                # sum up d**2 to penalize smaller d's more
145
+                sp = sumpartial + d*d
146
+                (a, s) = best_assign_help(vesrest, feasible, ap, sp)
147
+                if s > bestsum:
148
+                    bestsum = s
149
+                    besta = a
150
+        if besta:
151
+            return (besta, bestsum)
152
+        else:
153
+            # not feasible to assign e0, k0; try to assign rest
154
+            return best_assign_help(vesrest, feasible, apartial, sumpartial)
155
+
156
+def assigned_face(e, assignment):
157
+    (v0, v1), dir = e
158
+    a = assignment[v1]
159
+    for j, ee in enumerate(a):
160
+        if e == ee:
161
+            return j
162
+    return -1
163
+
164
+def create_wired_mesh(me2, me, thick):
165
+    edges = []
166
+    vert_edges = {}
167
+    for be in me.edges:
168
+        if be.select and not be.hide:
169
+            e = (be.key[0], be.key[1])
170
+            edges.append(e)
171
+            for k in (0, 1):
172
+                if e[k] not in vert_edges:
173
+                    vert_edges[e[k]] = []
174
+                vert_edges[e[k]].append((e, k))
175
+
176
+    assignment = find_assignment(me, edges, vert_edges, cube_normals)
177
+
178
+    # Create the geometry
179
+    n_idx = {}   
180
+    for v in assignment:
181
+        vpos = me.vertices[v]
182
+        index = len(me2.vertices)
183
+        # We need to associate each node with the new geometry
184
+        n_idx[v] = index   
185
+        # Geometry for the nodes, each one a cube
186
+        create_cube(me2, vpos, thick)
187
+
188
+    # Skin using the new geometry 
189
+    cfaces = []  
190
+    for k, f in assignment.items():
191
+        # Skin the nodes
192
+        for i in range(len(cube_faces)):
193
+            if f[i] is None:
194
+                cfaces.extend(fill_cube_face(me2, n_idx[k], i))
195
+            else:
196
+                (v0, v1), dir = f[i]
197
+                # only skin between edges in forward direction
198
+                # to avoid making doubles
199
+                if dir == 1:
200
+                    # but first make sure other end actually assigned
201
+                    i2 = assigned_face(((v0, v1), 0), assignment)
202
+                    if i2 == -1:
203
+                        cfaces.extend(fill_cube_face(me2, n_idx[k], i))
204
+                    continue
205
+                i2 = assigned_face(((v0, v1), 1), assignment)
206
+                if i2 != -1:
207
+                    cfaces.extend(skin_edges(me2, n_idx[v0], n_idx[v1], i, i2))
208
+                else:
209
+                    # assignment failed for this edge
210
+                    cfaces.extend(fill_cube_face(me2, n_idx[k], i))
211
+
212
+    # adding faces to the mesh
213
+    me2.faces.add(len(cfaces) // 4)
214
+    me2.faces.foreach_set("vertices_raw", cfaces)
215
+    me2.update(calc_edges=True)
216
+
217
+# panel containing tools
218
+class VIEW3D_PT_tools_SolidifyWireframe(bpy.types.Panel):
219
+    bl_space_type = 'VIEW_3D'
220
+    bl_region_type = 'TOOLS'
221
+    bl_context = "mesh_edit"
222
+    bl_label = "Solidify Wireframe"
223
+
224
+    def draw(self, context):
225
+        active_obj = context.active_object
226
+        layout = self.layout
227
+        col = layout.column(align=True)
228
+        col.operator("mesh.solidify_wireframe", text="Solidify")
229
+        col.prop(context.scene, "swThickness")
230
+        col.prop(context.scene, "swSelectNew")
231
+
232
+# a class for your operator
233
+class SolidifyWireframe(bpy.types.Operator):
234
+    '''Turns the selected edges of a mesh into solid objects'''
235
+    bl_idname = "mesh.solidify_wireframe"
236
+    bl_label = "Solidify Wireframe"
237
+    bl_options = {'REGISTER', 'UNDO'}
238
+    
239
+    def invoke(self, context, event):
240
+        return self.execute(context)
241
+
242
+    @classmethod
243
+    def poll(cls, context):
244
+        ob = context.active_object
245
+        return ob and ob.type == 'MESH'
246
+
247
+    def execute(self, context):
248
+        # Get the active object
249
+        ob_act = context.active_object
250
+        # getting current edit mode
251
+        currMode = ob_act.mode
252
+        # switching to object mode
253
+        bpy.ops.object.mode_set(mode='OBJECT')
254
+        bpy.ops.object.select_all(action='DESELECT')
255
+        # getting mesh data
256
+        mymesh = ob_act.data
257
+        #getting new mesh
258
+        newmesh = bpy.data.meshes.new(mymesh.name + " wire")
259
+        obj = bpy.data.objects.new(newmesh.name,newmesh)
260
+        obj.location = ob_act.location
261
+        obj.rotation_euler = ob_act.rotation_euler
262
+        obj.scale = ob_act.scale
263
+        context.scene.objects.link(obj)
264
+        create_wired_mesh(newmesh, mymesh, context.scene.swThickness)
265
+
266
+        # restoring original editmode if needed
267
+        if context.scene.swSelectNew:
268
+            obj.select = True
269
+            context.scene.objects.active = obj
270
+        else:
271
+            bpy.ops.object.mode_set(mode=currMode)
272
+
273
+        # returning after everything is done
274
+        return {'FINISHED'}
275
+
276
+# Register the operator
277
+def solidifyWireframe_menu_func(self, context):
278
+        self.layout.operator(SolidifyWireframe.bl_idname, text="Solidify Wireframe", icon='PLUGIN')
279
+
280
+# Add "Solidify Wireframe" menu to the "Mesh" menu.
281
+def register():
282
+        bpy.utils.register_module(__name__)
283
+        bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness",
284
+                                                              description="Thickness of the skinned edges",
285
+                                                              default=0.02)
286
+        bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire",
287
+                                                             description="If checked, the wire object will be selected after creation",
288
+                                                             default=True)
289
+        bpy.types.VIEW3D_MT_edit_mesh_edges.append(solidifyWireframe_menu_func)
290
+
291
+# Remove "Solidify Wireframe" menu entry from the "Mesh" menu.
292
+def unregister():
293
+        bpy.utils.register_module(__name__)
294
+        del bpy.types.Scene.swThickness
295
+        bpy.types.VIEW3D_MT_edit_mesh_edges.remove(solidifyWireframe_menu_func)
296
+
297
+if __name__ == "__main__":
298
+        register()

+ 421
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/OBJECT_RENDER_WIRE.PY ファイルの表示

@@ -0,0 +1,421 @@
1
+# ***** BEGIN GPL LICENSE BLOCK *****
2
+#
3
+# This program is free software; you can redistribute it and/or
4
+# modify it under the terms of the GNU General Public License
5
+# as published by the Free Software Foundation; either version 2
6
+# of the License, or (at your option) any later version.
7
+#
8
+# This program is distributed in the hope that it will be useful,
9
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See th
11
+# GNU General Public License for more details.
12
+#
13
+# You should have received a copy of the GNU General Public License
14
+# along with this program; if not, write to the Free Software Foundation,
15
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16
+#
17
+# object_render_wire.py liero, meta-androcto,
18
+# Yorik van Havre, Alejandro Sierra, Howard Trickey
19
+# ***** END GPL LICENCE BLOCK *****
20
+
21
+bl_info = {
22
+    "name": "Render Wireframe",
23
+    "author": "Community",
24
+    "description": " WireRender & WireSoild modes",
25
+    "version": (2, 3),
26
+    "blender": (2, 63, 0),
27
+    "location": "Object > Render Wireframe",
28
+    "warning": '',
29
+    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts',
30
+    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
31
+                   'func=detail&aid=26997',
32
+    'category': 'Object'}
33
+
34
+import bpy, mathutils
35
+
36
+cube_faces = [ [0,3,2,1], [5,6,7,4], [0,1,5,4],
37
+               [7,6,2,3], [2,6,5,1], [0,4,7,3] ]
38
+cube_normals = [ mathutils.Vector((0,0,-1)),
39
+                 mathutils.Vector((0,0,1)),
40
+                 mathutils.Vector((0,-1,0)),
41
+                 mathutils.Vector((0,1,0)),
42
+                 mathutils.Vector((1,0,0)),
43
+                 mathutils.Vector((-1,0,0)) ]
44
+
45
+def create_cube(me, v, d):
46
+    x = v.co.x
47
+    y = v.co.y
48
+    z = v.co.z
49
+    coords=[ [x-d,y-d,z-d], [x+d,y-d,z-d], [x+d,y+d,z-d], [x-d,y+d,z-d],
50
+         [x-d,y-d,z+d], [x+d,y-d,z+d], [x+d,y+d,z+d], [x-d,y+d,z+d] ]
51
+    for coord in coords:
52
+        me.vertices.add(1)
53
+        me.vertices[-1].co = mathutils.Vector(coord)
54
+
55
+def norm_dot(e, k, fnorm, me):
56
+    v = me.vertices[e[1]].co - me.vertices[e[0]].co
57
+    if k == 1:
58
+        v = -v
59
+    v.normalize()
60
+    return v * fnorm
61
+
62
+def fill_cube_face(me, index, f):
63
+    return [index + cube_faces[f][i] for i in range(4)]
64
+
65
+# Coords of jth point of face f in cube instance i
66
+def cube_face_v(me, f, i, j):
67
+    return me.vertices[i + cube_faces[f][j]].co
68
+
69
+def cube_face_center(me, f, i):
70
+    return 0.5 * (cube_face_v(me, f, i, 0) + \
71
+                  cube_face_v(me, f, i, 2))
72
+
73
+# Return distance between points on two faces when
74
+# each point is projected onto the plane that goes through
75
+# the face center and is perpendicular to the line
76
+# through the face centers.
77
+def projected_dist(me, i1, i2, f1, f2, j1, j2):
78
+    f1center = cube_face_center(me, f1, i1)
79
+    f2center = cube_face_center(me, f2, i2)
80
+    axis_norm = (f2center - f1center).normalized()
81
+    v1 = cube_face_v(me, f1, i1, j1)
82
+    v2 = cube_face_v(me, f2, i2, j2)
83
+    v1proj = v1 - (axis_norm * (v1 - f1center)) * axis_norm
84
+    v2proj = v2 - (axis_norm * (v2 - f2center)) * axis_norm
85
+    return (v2proj - v1proj).length
86
+
87
+def skin_edges(me, i1, i2, f1, f2):
88
+    # Connect verts starting at i1 forming cube face f1
89
+    # to those starting at i2 forming cube face f2.
90
+    # Need to find best alignment to avoid a twist.
91
+    shortest_length = 1e6
92
+    f2_start_index = 0
93
+    for i in range(4):
94
+        x = projected_dist(me, i1, i2, f1, f2, 0, i)
95
+        if x < shortest_length:
96
+            shortest_length = x
97
+            f2_start_index = i
98
+    ans = []
99
+    j = f2_start_index
100
+    for i in range(4):
101
+        fdata = [i1 + cube_faces[f1][i],
102
+                 i2 + cube_faces[f2][j],
103
+                 i2 + cube_faces[f2][(j + 1) % 4],
104
+                 i1 + cube_faces[f1][(i - 1) % 4]]
105
+        if fdata[3] == 0:
106
+            fdata = [fdata[3]] + fdata[0:3]
107
+        ans.extend(fdata)
108
+        j = (j - 1) % 4
109
+    return ans
110
+            
111
+
112
+# Return map: v -> list of length len(node_normals) where
113
+# each element of the list is either None (no assignment)
114
+# or ((v0, v1), 0 or 1) giving an edge and direction that face is assigned to.
115
+def find_assignment(me, edges, vert_edges, node_normals):
116
+    nf = len(node_normals)
117
+    feasible = {}
118
+    for e in edges:
119
+        for k in (0, 1):
120
+            fds = [(f, norm_dot(e, k, node_normals[f], me)) for f in range(nf)]
121
+            feasible[(e, k)] = [fd for fd in fds if fd[1] > 0.01]
122
+    assignment = {}
123
+    for v, ves in vert_edges.items():
124
+        assignment[v] = best_assignment(ves, feasible, nf)
125
+    return assignment
126
+
127
+def best_assignment(ves, feasible, nf):
128
+    apartial = [ None ] * nf
129
+    return best_assign_help(ves, feasible, apartial, 0.0)[0]
130
+
131
+def best_assign_help(ves, feasible, apartial, sumpartial):
132
+    if len(ves) == 0:
133
+        return (apartial, sumpartial)
134
+    else:
135
+        ek0 = ves[0]
136
+        vesrest = ves[1:]
137
+        feas = feasible[ek0]
138
+        bestsum = 0
139
+        besta = None
140
+        for (f, d) in feas:
141
+            if apartial[f] is None:
142
+                ap = apartial[:]
143
+                ap[f] = ek0
144
+                # sum up d**2 to penalize smaller d's more
145
+                sp = sumpartial + d*d
146
+                (a, s) = best_assign_help(vesrest, feasible, ap, sp)
147
+                if s > bestsum:
148
+                    bestsum = s
149
+                    besta = a
150
+        if besta:
151
+            return (besta, bestsum)
152
+        else:
153
+            # not feasible to assign e0, k0; try to assign rest
154
+            return best_assign_help(vesrest, feasible, apartial, sumpartial)
155
+
156
+def assigned_face(e, assignment):
157
+    (v0, v1), dir = e
158
+    a = assignment[v1]
159
+    for j, ee in enumerate(a):
160
+        if e == ee:
161
+            return j
162
+    return -1
163
+
164
+def create_wired_mesh(me2, me, thick):
165
+    edges = []
166
+    vert_edges = {}
167
+    for be in me.edges:
168
+        if be.select and not be.hide:
169
+            e = (be.key[0], be.key[1])
170
+            edges.append(e)
171
+            for k in (0, 1):
172
+                if e[k] not in vert_edges:
173
+                    vert_edges[e[k]] = []
174
+                vert_edges[e[k]].append((e, k))
175
+
176
+    assignment = find_assignment(me, edges, vert_edges, cube_normals)
177
+
178
+    # Create the geometry
179
+    n_idx = {}   
180
+    for v in assignment:
181
+        vpos = me.vertices[v]
182
+        index = len(me2.vertices)
183
+        # We need to associate each node with the new geometry
184
+        n_idx[v] = index   
185
+        # Geometry for the nodes, each one a cube
186
+        create_cube(me2, vpos, thick)
187
+
188
+    # Skin using the new geometry 
189
+    cfaces = []  
190
+    for k, f in assignment.items():
191
+        # Skin the nodes
192
+        for i in range(len(cube_faces)):
193
+            if f[i] is None:
194
+                cfaces.extend(fill_cube_face(me2, n_idx[k], i))
195
+            else:
196
+                (v0, v1), dir = f[i]
197
+                # only skin between edges in forward direction
198
+                # to avoid making doubles
199
+                if dir == 1:
200
+                    # but first make sure other end actually assigned
201
+                    i2 = assigned_face(((v0, v1), 0), assignment)
202
+                    if i2 == -1:
203
+                        cfaces.extend(fill_cube_face(me2, n_idx[k], i))
204
+                    continue
205
+                i2 = assigned_face(((v0, v1), 1), assignment)
206
+                if i2 != -1:
207
+                    cfaces.extend(skin_edges(me2, n_idx[v0], n_idx[v1], i, i2))
208
+                else:
209
+                    # assignment failed for this edge
210
+                    cfaces.extend(fill_cube_face(me2, n_idx[k], i))
211
+
212
+    # adding faces to the mesh
213
+    me2.tessfaces.add(len(cfaces) // 4)
214
+    me2.tessfaces.foreach_set("vertices_raw", cfaces)
215
+    me2.update(calc_edges=True)
216
+
217
+# Add built in wireframe
218
+def wire_add(mallas):
219
+    if mallas:
220
+        bpy.ops.object.select_all(action='DESELECT')
221
+        bpy.context.scene.objects.active = mallas[0]
222
+        for o in mallas: o.select = True
223
+        bpy.ops.object.duplicate()
224
+        obj, sce = bpy.context.object, bpy.context.scene
225
+        for mod in obj.modifiers: obj.modifiers.remove(mod)
226
+        bpy.ops.object.join()
227
+        bpy.ops.object.mode_set(mode='EDIT')
228
+        bpy.ops.mesh.wireframe(thickness=0.005)
229
+        bpy.ops.object.mode_set()
230
+        for mat in obj.material_slots: bpy.ops.object.material_slot_remove()
231
+        if 'wire_object' in sce.objects.keys():
232
+            sce.objects.get('wire_object').data = obj.data
233
+            sce.objects.get('wire_object').matrix_world = mallas[0].matrix_world
234
+            sce.objects.unlink(obj)
235
+        else:
236
+            obj.name = 'wire_object'
237
+        obj.data.materials.append(bpy.data.materials.get('mat_wireobj'))
238
+
239
+    return{'FINISHED'}
240
+'''
241
+class VIEW3D_PT_tools_SolidifyWireframe(bpy.types.Panel):
242
+    bl_space_type = 'VIEW_3D'
243
+    bl_region_type = 'TOOLS'
244
+    bl_context = "mesh_edit"
245
+    bl_label = "Solidify Wireframe"
246
+
247
+    def draw(self, context):
248
+        active_obj = context.active_object
249
+        layout = self.layout
250
+        col = layout.column(align=True)
251
+        col.operator("mesh.solidify_wireframe", text="Solidify")
252
+        col.prop(context.scene, "swThickness")
253
+        col.prop(context.scene, "swSelectNew")
254
+'''
255
+# a class for your operator
256
+class SolidifyWireframe(bpy.types.Operator):
257
+    """Turns the selected edges of a mesh into solid objects"""
258
+    bl_idname = "mesh.solidify_wireframe"
259
+    bl_label = "Solidify Wireframe"
260
+    bl_options = {'REGISTER', 'UNDO'}
261
+    
262
+    def invoke(self, context, event):
263
+        return self.execute(context)
264
+
265
+    @classmethod
266
+    def poll(cls, context):
267
+        ob = context.active_object
268
+        return ob and ob.type == 'MESH'
269
+
270
+    def execute(self, context):
271
+        # Get the active object
272
+        ob_act = context.active_object
273
+        # getting current edit mode
274
+        currMode = ob_act.mode
275
+        # switching to object mode
276
+        bpy.ops.object.mode_set(mode='OBJECT')
277
+        bpy.ops.object.select_all(action='DESELECT')
278
+        # getting mesh data
279
+        mymesh = ob_act.data
280
+        #getting new mesh
281
+        newmesh = bpy.data.meshes.new(mymesh.name + " wire")
282
+        obj = bpy.data.objects.new(newmesh.name,newmesh)
283
+        obj.location = ob_act.location
284
+        obj.rotation_euler = ob_act.rotation_euler
285
+        obj.scale = ob_act.scale
286
+        context.scene.objects.link(obj)
287
+        create_wired_mesh(newmesh, mymesh, context.scene.swThickness)
288
+
289
+        # restoring original editmode if needed
290
+        if context.scene.swSelectNew:
291
+            obj.select = True
292
+            context.scene.objects.active = obj
293
+        else:
294
+            bpy.ops.object.mode_set(mode=currMode)
295
+
296
+        # returning after everything is done
297
+        return {'FINISHED'}
298
+		
299
+class WireMaterials(bpy.types.Operator):
300
+    bl_idname = 'scene.wire_render'
301
+    bl_label = 'Apply Materials'
302
+    bl_description = 'Set Up Materials for a Wire Render'
303
+    bl_options = {'REGISTER', 'UNDO'}
304
+
305
+    def execute(self, context):
306
+        wm = bpy.context.window_manager
307
+        sce = bpy.context.scene
308
+
309
+        if 'mat_clay' not in bpy.data.materials:
310
+            mat = bpy.data.materials.new('mat_clay')
311
+            mat.specular_intensity = 0
312
+        else: mat = bpy.data.materials.get('mat_clay')
313
+        mat.diffuse_color = wm.col_clay
314
+        mat.use_shadeless = wm.shadeless_mat
315
+
316
+        if 'mat_wire' not in bpy.data.materials:
317
+            mat = bpy.data.materials.new('mat_wire')
318
+            mat.specular_intensity = 0
319
+            mat.use_transparency = True
320
+            mat.type = 'WIRE'
321
+            mat.offset_z = 0.05
322
+        else: mat = bpy.data.materials.get('mat_wire')
323
+        mat.diffuse_color = wm.col_wire
324
+        mat.use_shadeless = wm.shadeless_mat
325
+
326
+        try: bpy.ops.object.mode_set()
327
+        except: pass
328
+
329
+        if wm.selected_meshes: objetos = bpy.context.selected_objects
330
+        else: objetos = sce.objects
331
+
332
+        mallas = [o for o in objetos if o.type == 'MESH' and o.is_visible(sce) and o.name != 'wire_object']
333
+
334
+        for obj in mallas:
335
+            sce.objects.active = obj
336
+            print ('procesando >', obj.name)
337
+            obj.show_wire = wm.wire_view
338
+            for mat in obj.material_slots:
339
+                bpy.ops.object.material_slot_remove()
340
+            obj.data.materials.append(bpy.data.materials.get('mat_wire'))
341
+            obj.data.materials.append(bpy.data.materials.get('mat_clay'))
342
+            obj.material_slots.data.active_material_index = 1
343
+            bpy.ops.object.editmode_toggle()
344
+            bpy.ops.mesh.select_all(action='SELECT')
345
+            bpy.ops.object.material_slot_assign()
346
+            bpy.ops.object.mode_set()
347
+
348
+        if wm.wire_object:
349
+            if 'mat_wireobj' not in bpy.data.materials:
350
+                mat = bpy.data.materials.new('mat_wireobj')
351
+                mat.specular_intensity = 0
352
+            else: mat = bpy.data.materials.get('mat_wireobj')
353
+            mat.diffuse_color = wm.col_wire
354
+            mat.use_shadeless = wm.shadeless_mat
355
+            wire_add(mallas)
356
+
357
+        return{'FINISHED'}
358
+
359
+class PanelWMat(bpy.types.Panel):
360
+    bl_label = 'Setup Wire Render'
361
+    bl_space_type = 'VIEW_3D'
362
+    bl_region_type = 'TOOLS'
363
+    bl_options = {'DEFAULT_CLOSED'}
364
+
365
+    def draw(self, context):
366
+        wm = bpy.context.window_manager
367
+        active_obj = context.active_object
368
+        layout = self.layout
369
+
370
+        column = layout.column(align=True)
371
+        column.prop(wm, 'col_clay')
372
+        column.prop(wm, 'col_wire')
373
+        column = layout.column(align=True)
374
+        column.prop(wm, 'selected_meshes')
375
+        column.prop(wm, 'shadeless_mat')
376
+        column.prop(wm, 'wire_view')
377
+        column.prop(wm, 'wire_object')
378
+        column.separator()
379
+        column.operator('scene.wire_render')
380
+        column.label(text='- - - - - - - - - - - - - - - - - - - - - -')
381
+        col = layout.column(align=True)
382
+        column.label(text='Solid WireFrame')
383
+        layout.operator("mesh.solidify_wireframe", text="Create Mesh Object")
384
+        col.prop(context.scene, "swThickness")
385
+        col.prop(context.scene, "swSelectNew")
386
+bpy.types.WindowManager.selected_meshes = bpy.props.BoolProperty(name='Selected Meshes', default=False, description='Apply materials to Selected Meshes / All Visible Meshes')
387
+bpy.types.WindowManager.shadeless_mat = bpy.props.BoolProperty(name='Shadeless', default=False, description='Generate Shadeless Materials')
388
+bpy.types.WindowManager.col_clay = bpy.props.FloatVectorProperty(name='', description='Clay Color', default=(1.0, 0.9, 0.8), min=0, max=1, step=1, precision=3, subtype='COLOR_GAMMA', size=3)
389
+bpy.types.WindowManager.col_wire = bpy.props.FloatVectorProperty(name='', description='Wire Color', default=(0.1 ,0.0 ,0.0), min=0, max=1, step=1, precision=3, subtype='COLOR_GAMMA', size=3)
390
+bpy.types.WindowManager.wire_view = bpy.props.BoolProperty(name='Viewport Wires', default=False, description='Overlay wires display over solid in Viewports')
391
+bpy.types.WindowManager.wire_object = bpy.props.BoolProperty(name='Create Mesh Object', default=False, description='Add a Wire Object to scene to be able to render wires in Cycles')
392
+bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness", description="Thickness of the skinned edges", default=0.01)
393
+bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire", description="If checked, the wire object will be selected after creation", default=True)
394
+
395
+# Register the operator
396
+def solidifyWireframe_menu_func(self, context):
397
+        self.layout.operator(SolidifyWireframe.bl_idname, text="Solidify Wireframe", icon='PLUGIN')
398
+
399
+# Add "Solidify Wireframe" menu to the "Mesh" menu.
400
+def register():
401
+        bpy.utils.register_class(WireMaterials)
402
+        bpy.utils.register_class(PanelWMat)
403
+        bpy.utils.register_module(__name__)
404
+        bpy.types.Scene.swThickness = bpy.props.FloatProperty(name="Thickness",
405
+                                                              description="Thickness of the skinned edges",
406
+                                                              default=0.01)
407
+        bpy.types.Scene.swSelectNew = bpy.props.BoolProperty(name="Select wire",
408
+                                                             description="If checked, the wire object will be selected after creation",
409
+                                                             default=True)
410
+        bpy.types.VIEW3D_MT_edit_mesh_edges.append(solidifyWireframe_menu_func)
411
+
412
+# Remove "Solidify Wireframe" menu entry from the "Mesh" menu.
413
+def unregister():
414
+        bpy.utils.unregister_class(WireMaterials)
415
+        bpy.utils.unregister_class(PanelWMat)
416
+        bpy.utils.unregister_module(__name__)
417
+        del bpy.types.Scene.swThickness
418
+        bpy.types.VIEW3D_MT_edit_mesh_edges.remove(solidifyWireframe_menu_func)
419
+
420
+if __name__ == "__main__":
421
+        register()

+ 158
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/PRECISE_RENDER_BORDER_ADJUST_V1-3.PY ファイルの表示

@@ -0,0 +1,158 @@
1
+######################################################################################################
2
+# A simple add-on to allows the user to precisly place the border render region (Ctrl+B in cam view) #
3
+# using numerical input, witch can be animated                                                       #
4
+# Actualy uncommented (see further version)                                                          #
5
+# Author: Lapineige                                                                                  #
6
+# License: GPL v3                                                                                   #
7
+######################################################################################################
8
+
9
+
10
+############# Add-on description (used by Blender)
11
+
12
+bl_info = {
13
+    "name": "Precise Render Border Adjust",
14
+    "description": 'Allows to modify and animate the "Border Render" region with numerical input.',
15
+    "author": "Lapineige",
16
+    "version": (1, 3),
17
+    "blender": (2, 71, 0),
18
+    "location": "Properties > Render > Precise Render Border Adjust (panel)",
19
+    "warning": "", # used for warning icon and text in addons panel
20
+    "wiki_url": "http://le-terrier-de-lapineige.over-blog.com/2014/07/precise-render-border-adjust-mon-add-on-pour-positionner-precisement-le-border-render.html",
21
+    "tracker_url": "http://blenderclan.tuxfamily.org/html/modules/newbb/viewtopic.php?topic_id=42159",
22
+    "category": "Render"}
23
+
24
+##############
25
+
26
+import bpy
27
+
28
+bpy.types.Scene.x_min_pixels = bpy.props.IntProperty(min=0, description="Minimum X value (in pixel) for the render border")
29
+bpy.types.Scene.x_max_pixels = bpy.props.IntProperty(min=0, description="Maximum X value (in pixel) for the render border")
30
+bpy.types.Scene.y_min_pixels = bpy.props.IntProperty(min=0, description="Minimum Y value (in pixel) for the render border")
31
+bpy.types.Scene.y_max_pixels = bpy.props.IntProperty(min=0, description="Maximum Y value (in pixel) for the render border")
32
+
33
+
34
+class PreciseRenderBorderAdjust(bpy.types.Panel):
35
+    """Creates the tools in a Panel, in the scene context of the properties editor"""
36
+    bl_label = "Precise Render Border Adjust"
37
+    bl_idname = "Precise_Render_Border_Adjust"
38
+    bl_space_type = 'PROPERTIES'
39
+    bl_region_type = 'WINDOW'
40
+    bl_context = "render"
41
+
42
+    def draw(self, context):
43
+        layout = self.layout
44
+
45
+        scene = context.scene
46
+        
47
+        if not scene.render.use_border:
48
+            sub = layout.split(percentage=0.7)
49
+            sub.label(icon="ERROR", text="Border Render not activated:")
50
+            sub.prop(scene.render, "use_border")
51
+        
52
+        sub = layout.column()
53
+        row = sub.row()
54
+        row.label(text="")
55
+        row.prop(scene.render, "border_max_y", text="Max", slider=True)
56
+        row.label(text="")
57
+        row = sub.row(align=True)
58
+        row.prop(scene.render, "border_min_x", text="Min", slider=True)
59
+        row.prop(scene.render, "border_max_x", text="Max", slider=True)
60
+        row = sub.row()
61
+        row.label(text="")
62
+        row.prop(scene.render, "border_min_y", text="Min", slider=True)
63
+        row.label(text="")
64
+        
65
+        row = layout.row()
66
+        row.label(text="Convert values to pixels:")
67
+        row.operator("render.bordertopixels", text="Border -> Pixels")
68
+        
69
+        layout.label(text="Pixels position X:")
70
+        row = layout.row(align=True)
71
+        row.prop(scene, "x_min_pixels", text="Min")
72
+        row.prop(scene, "x_max_pixels", text="Max")
73
+        layout.label(text="Pixels position Y:")
74
+        row = layout.row(align=True)
75
+        row.prop(scene, "y_min_pixels", text="Min")
76
+        row.prop(scene, "y_max_pixels", text="Max")
77
+        
78
+        layout.label(icon="INFO", text="Don't forget to apply pixels values")
79
+        row = layout.row()
80
+        row.operator("render.pixelstoborder", text="Pixels -> Border")
81
+
82
+class PixelsToBorder(bpy.types.Operator):
83
+    """ Convert the pixel value into the proportion needed by the Blender native property """
84
+    bl_idname = "render.pixelstoborder"
85
+    bl_label = "Convert Pixels to Border proportion"
86
+    
87
+    @classmethod
88
+    def poll(cls, context):
89
+        return True
90
+
91
+    def execute(self, context):
92
+        C = bpy.context
93
+    
94
+        X = C.scene.render.resolution_x
95
+        Y = C.scene.render.resolution_y
96
+        
97
+        C.scene.render.border_min_x = C.scene.x_min_pixels / X
98
+        C.scene.render.border_max_x = C.scene.x_max_pixels / X
99
+        C.scene.render.border_min_y = C.scene.y_min_pixels / Y
100
+        C.scene.render.border_max_y = C.scene.y_max_pixels / Y
101
+        
102
+        if C.scene.x_min_pixels > X:
103
+            C.scene.x_min_pixels = X
104
+        if C.scene.x_max_pixels > X:
105
+            C.scene.x_max_pixels = X
106
+        if C.scene.y_min_pixels > Y:
107
+            C.scene.y_min_pixels = Y
108
+        if C.scene.y_max_pixels > Y:
109
+            C.scene.y_max_pixels = Y
110
+        
111
+        return {'FINISHED'}
112
+    
113
+class BorderToPixels(bpy.types.Operator):
114
+    """ Convert the Blender native property value to pixels"""
115
+    bl_idname = "render.bordertopixels"
116
+    bl_label = "Convert border values to pixels"
117
+    
118
+    @classmethod
119
+    def poll(cls, context):
120
+        return True
121
+
122
+    def execute(self, context):
123
+        C = bpy.context
124
+    
125
+        X = C.scene.render.resolution_x
126
+        Y = C.scene.render.resolution_y
127
+        
128
+        C.scene.x_min_pixels = int(C.scene.render.border_min_x * X)
129
+        C.scene.x_max_pixels = int(C.scene.render.border_max_x * X)
130
+        C.scene.y_min_pixels = int(C.scene.render.border_min_y * Y)
131
+        C.scene.y_max_pixels = int(C.scene.render.border_max_y * Y)
132
+                
133
+        return {'FINISHED'}
134
+
135
+def register():
136
+    bpy.utils.register_class(PreciseRenderBorderAdjust)
137
+    bpy.utils.register_class(PixelsToBorder)
138
+    bpy.utils.register_class(BorderToPixels)
139
+
140
+
141
+def unregister():
142
+    bpy.utils.unregister_class(PreciseRenderBorderAdjust)
143
+    bpy.utils.unregister_class(PixelsToBorder)
144
+    bpy.utils.unregister_class(BorderToPixels)
145
+
146
+
147
+if __name__ == "__main__":
148
+    C = bpy.context
149
+    
150
+    X = C.scene.render.resolution_x
151
+    Y = C.scene.render.resolution_y
152
+    
153
+    C.scene.x_min_pixels = 0
154
+    C.scene.x_max_pixels = X
155
+    C.scene.y_min_pixels = 0
156
+    C.scene.y_max_pixels = Y
157
+    
158
+    register()

+ 307
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/RENDER-BORDER.PY ファイルの表示

@@ -0,0 +1,307 @@
1
+# ##### BEGIN GPL LICENSE BLOCK #####
2
+#
3
+#  This program is free software; you can redistribute it and/or
4
+#  modify it under the terms of the GNU General Public License
5
+#  as published by the Free Software Foundation; either version 2
6
+#  of the License, or (at your option) any later version.
7
+#
8
+#  This program is distributed in the hope that it will be useful,
9
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+#  GNU General Public License for more details.
12
+#
13
+#  You should have received a copy of the GNU General Public License
14
+#  along with this program; if not, write to the Free Software Foundation,
15
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
+#
17
+# ##### END GPL LICENSE BLOCK #####
18
+
19
+bl_info = {
20
+    "name": "Render Border",
21
+    "description": "Render Border",
22
+    "author": "Christian Brinkmann, David Boho",
23
+    "version": (0, 0, 5),
24
+    "blender": (2, 80, 0),
25
+    "tracker_url": "https://github.com/p2or/blender-renderborder",
26
+    "location": "Camera > Properties > Data > Render Border",
27
+    "category": "Render"
28
+}
29
+
30
+import bpy
31
+from bpy.app.handlers import persistent
32
+
33
+
34
+def round_pixels(pixel_float):
35
+    return round(pixel_float, 2)
36
+
37
+def calc_normalized(pixels_int, pixel_max):
38
+    return pixels_int / pixel_max if pixel_max else 0.0
39
+
40
+def calc_pixels(normalized_float, pixel_max):
41
+    return normalized_float * pixel_max
42
+
43
+def calc_width(res_x, min_x, max_x):
44
+    return res_x * max_x - res_x * min_x
45
+
46
+def calc_height(res_y, min_y, max_y):
47
+    return res_y * max_y - res_y * min_y  
48
+
49
+def calc_centerX(res_x, min_x, width):
50
+    return res_x * min_x + width / 2
51
+
52
+def calc_centerY(res_y, min_y, height):
53
+    return res_y * min_y + height / 2
54
+
55
+
56
+# ------------------------------------------------------------------------
57
+#   Properties
58
+# ------------------------------------------------------------------------
59
+
60
+class RenderBorder(bpy.types.PropertyGroup):
61
+    
62
+    # static member
63
+    _rd = None
64
+    _resX = _resY = _minX = _maxX = _minY = _maxY = 0 
65
+    _width = _height = _centerX = _centerY = 0
66
+                       
67
+    def set_centerX(self, value):
68
+        diffX = calc_normalized((value - self._centerX), self._resX)
69
+        self._rd.border_min_x += diffX
70
+        self._rd.border_max_x += diffX
71
+        RenderBorder._minX = calc_pixels(self._rd.border_min_x, self._resX)
72
+        RenderBorder._maxX = calc_pixels(self._rd.border_max_x, self._resX)
73
+        RenderBorder._width = calc_width(self._resX, self._rd.border_min_x, self._rd.border_max_x)
74
+        RenderBorder._centerX = value
75
+    
76
+    def set_centerY(self, value):
77
+        diffY = calc_normalized((value - self._centerY), self._resY)
78
+        self._rd.border_min_y += diffY
79
+        self._rd.border_max_y += diffY
80
+        RenderBorder._minY = calc_pixels(self._rd.border_min_y, self._resY)
81
+        RenderBorder._maxY = calc_pixels(self._rd.border_max_y, self._resY)
82
+        RenderBorder._height = calc_height(self._resY, self._rd.border_min_y, self._rd.border_max_y)
83
+        RenderBorder._centerY = value
84
+    
85
+    def set_minX(self, value):
86
+        self._rd.border_min_x = calc_normalized(value, self._resX)
87
+        RenderBorder._minX = round_pixels(calc_pixels(self._rd.border_min_x, self._resX))
88
+        RenderBorder._width = calc_width(self._resX, self._rd.border_min_x, self._rd.border_max_x)
89
+        RenderBorder._centerX = calc_centerX(self._resX, self._rd.border_min_x, self._width)
90
+    
91
+    def set_maxX(self, value):
92
+        self._rd.border_max_x = calc_normalized(value, self._resX)
93
+        RenderBorder._maxX = round_pixels(calc_pixels(self._rd.border_max_x, self._resX))
94
+        RenderBorder._width = calc_width(self._resX, self._rd.border_min_x, self._rd.border_max_x)
95
+        RenderBorder._centerX = calc_centerX(self._resX, self._rd.border_min_x, self._width)
96
+
97
+    def set_minY(self, value):
98
+        self._rd.border_min_y = calc_normalized(value, self._resY)
99
+        RenderBorder._minY = round_pixels(calc_pixels(self._rd.border_min_y, self._resY))
100
+        RenderBorder._height = calc_height(self._resY, self._rd.border_min_y, self._rd.border_max_y)
101
+        RenderBorder._centerY = calc_centerY(self._resY, self._rd.border_min_y, self._height)
102
+        
103
+    def set_maxY(self, value):
104
+        self._rd.border_max_y = calc_normalized(value, self._resY)
105
+        RenderBorder._maxY = round_pixels(calc_pixels(self._rd.border_max_y, self._resY))
106
+        RenderBorder._height = calc_height(self._resY, self._rd.border_min_y, self._rd.border_max_y)
107
+        RenderBorder._centerY = calc_centerY(self._resY, self._rd.border_min_y, self._height)
108
+    
109
+    def set_useBorder(self, value):
110
+        self._rd.use_border = value
111
+           
112
+    def get_centerX(self):
113
+        return RenderBorder._centerX
114
+    
115
+    def get_centerY(self):
116
+        return RenderBorder._centerY
117
+        
118
+    def get_minX(self):
119
+        return RenderBorder._minX
120
+    
121
+    def get_maxX(self):
122
+        return RenderBorder._maxX
123
+    
124
+    def get_minY(self):
125
+        return RenderBorder._minY
126
+    
127
+    def get_maxY(self):
128
+        return RenderBorder._maxY
129
+
130
+    def get_width(self):
131
+        return abs(round_pixels(RenderBorder._width))
132
+    
133
+    def get_height(self):
134
+        return abs(round_pixels(RenderBorder._height))
135
+        
136
+    def get_useBorder(self):
137
+        bpy.ops.rborder.init_border()
138
+        return self._rd.use_border
139
+
140
+    center_x : bpy.props.IntProperty(
141
+        name = "Center X",
142
+        description =   ("Horizontal center of the render border box"),
143
+        min = 0, default = 0, get=get_centerX, set=set_centerX )
144
+    
145
+    center_y : bpy.props.IntProperty(
146
+        name = "Center Y",
147
+        description =   ("Vertical center of the render border box"),
148
+        min = 0, default = 0, get=get_centerY, set=set_centerY )
149
+
150
+    width : bpy.props.IntProperty(
151
+        name = "Width",
152
+        description =   ("Width of render border box"),
153
+        min = 0, default = 0, get=get_width)
154
+
155
+    height : bpy.props.IntProperty(
156
+        name = "Height",
157
+        description =   ("Height of render border box"),
158
+        min = 0, default = 0, get=get_height)
159
+                   
160
+    min_x : bpy.props.IntProperty(
161
+        description =   ("Pixel distance between the left edge "
162
+                        "of the camera border and the left "
163
+                        "side of the render border box"),
164
+        name = "Min X", min = 0, default = 0, get=get_minX, set=set_minX )
165
+    
166
+    max_x : bpy.props.IntProperty(
167
+        description =   ("Pixel distance between the right edge "
168
+                        "of the camera border and the right "
169
+                        "side of the render border box"),
170
+        name = "Max X",min = 0, default = 0, get=get_maxX, set=set_maxX )
171
+        
172
+    min_y : bpy.props.IntProperty(
173
+        description =   ("Pixel distance between the bottom edge "
174
+                        "of the camera border and the bottom "
175
+                        "edge of the render border box"),
176
+        name = "Min Y", min = 0, default = 0, get=get_minY, set=set_minY )
177
+   
178
+    max_y : bpy.props.IntProperty(
179
+        description =   ("Pixel distance between the top edge "
180
+                        "of the camera border and the top "
181
+                        "edge of the render border box"),
182
+        name = "Max Y", min = 0, default = 0, get=get_maxY, set=set_maxY )
183
+    
184
+    use_rborder : bpy.props.BoolProperty(
185
+        name = "Use render border", description = "Use render border", 
186
+        get=get_useBorder, set=set_useBorder)
187
+
188
+
189
+# ------------------------------------------------------------------------
190
+# Operators
191
+# ------------------------------------------------------------------------
192
+
193
+class RBORDER_OT_init_border(bpy.types.Operator):
194
+    bl_idname = "rborder.init_border"
195
+    bl_label = "Init Render Border"
196
+    bl_options = {'INTERNAL'}
197
+  
198
+    def execute(self, context):
199
+        scn = context.scene
200
+        RenderBorder._rd = scn.render
201
+        RenderBorder._resX = scn.render.resolution_x
202
+        RenderBorder._resY = scn.render.resolution_y
203
+        
204
+        rbx = scn.renderborder
205
+        rbx.min_x = round_pixels(calc_pixels(scn.render.border_min_x, scn.render.resolution_x))
206
+        rbx.min_y = round_pixels(calc_pixels(scn.render.border_min_y, scn.render.resolution_y))
207
+        rbx.max_x = round_pixels(calc_pixels(scn.render.border_max_x, scn.render.resolution_x))
208
+        rbx.max_y = round_pixels(calc_pixels(scn.render.border_max_y, scn.render.resolution_y))
209
+        return {'FINISHED'}
210
+
211
+
212
+class RBORDER_OT_reset_border(bpy.types.Operator):
213
+    bl_idname = "rborder.reset_border"
214
+    bl_label = "Reset Render Border"
215
+    bl_description = "Fit render border to the current camera resolution"
216
+    bl_options = {'REGISTER', 'UNDO'}
217
+    
218
+    def execute(self, context):
219
+        scn = context.scene
220
+        rbx = scn.renderborder
221
+        rbx.min_x = 0
222
+        rbx.min_y = 0
223
+        rbx.max_x = scn.render.resolution_x
224
+        rbx.max_y = scn.render.resolution_y
225
+        self.report({'INFO'}, "Render Border adapted")
226
+        return {'FINISHED'}
227
+
228
+
229
+# ------------------------------------------------------------------------
230
+#   Panel
231
+# ------------------------------------------------------------------------
232
+
233
+class RBORDER_PT_camera(bpy.types.Panel):
234
+    bl_label = "Render Border"
235
+    bl_space_type = 'PROPERTIES'
236
+    bl_region_type = 'WINDOW'
237
+    bl_context = "data"
238
+    
239
+    @classmethod
240
+    def poll(cls, context):
241
+        return context.active_object.type == "CAMERA"
242
+    
243
+    def draw_header(self, context):
244
+        scn = context.scene
245
+        rbx = scn.renderborder
246
+        self.layout.prop(rbx, "use_rborder", text="")
247
+    
248
+    def draw(self, context):
249
+        scn = context.scene
250
+        rbx = scn.renderborder
251
+        layout = self.layout
252
+      
253
+        row = layout.row()
254
+        col = row.column(align=True)
255
+        rowsub = col.row(align=True)
256
+        rowsub.prop(rbx, "min_x", text="X")
257
+        rowsub.prop(rbx, "max_x", text="R")
258
+        rowsub = col.row(align=True)
259
+        rowsub.prop(rbx, "min_y", text="Y")
260
+        rowsub.prop(rbx, "max_y", text="T")
261
+        col.prop(rbx, "center_x")
262
+        col.prop(rbx, "center_y")
263
+        col.operator("rborder.reset_border", text="Reset Render Border", icon='FILE_REFRESH')
264
+        row = layout.row()
265
+        col = layout.column(align=True)
266
+        rowsub = col.row(align=True)
267
+        rowsub = row.split(factor=0.3, align=True)
268
+        rowsub.prop(scn.render, "use_crop_to_border", text="Crop Image")
269
+        rowsub.alignment = 'RIGHT'
270
+        rowsub.label(text="Width: {}px Height: {}px".format(rbx.width, rbx.height))
271
+
272
+        
273
+# ------------------------------------------------------------------------
274
+#   Registration
275
+# ------------------------------------------------------------------------
276
+
277
+@persistent
278
+def init_renderborder_member(dummy):
279
+    bpy.ops.rborder.init_border()
280
+
281
+
282
+classes = (
283
+    RenderBorder,
284
+    RBORDER_OT_init_border,
285
+    RBORDER_OT_reset_border,
286
+    RBORDER_PT_camera
287
+)
288
+
289
+def register():
290
+    from bpy.utils import register_class
291
+    for cls in classes:
292
+        register_class(cls)
293
+    
294
+    bpy.types.Scene.renderborder = bpy.props.PointerProperty(type=RenderBorder)
295
+    bpy.app.handlers.load_post.append(init_renderborder_member)
296
+
297
+def unregister():
298
+    from bpy.utils import unregister_class
299
+    for cls in reversed(classes):
300
+        unregister_class(cls)
301
+    
302
+    bpy.app.handlers.load_post.remove(init_renderborder_member)
303
+    del bpy.types.Scene.renderborder
304
+
305
+
306
+if __name__ == "__main__":
307
+    register()

+ 125
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/RA_DRAW_UI.PY ファイルの表示

@@ -0,0 +1,125 @@
1
+import bpy
2
+import gpu
3
+import blf
4
+from gpu_extras.batch import batch_for_shader
5
+
6
+
7
+def RA_modal_Draw(self, context, prefs):
8
+    height = bpy.context.region.height
9
+    width = bpy.context.region.width
10
+    CO = context.object
11
+    
12
+    font_id = 0
13
+
14
+    #+ text
15
+    if CO.RA_Unq_mode == True:
16
+        blf.color (font_id,0.9,0.32,0.35,1)
17
+    else:
18
+        blf.color (font_id,0.85,0.85,0.85,1)
19
+    #* Offset
20
+    blf.position(font_id, (width/2) - 200, (height/2) - 250, 0)
21
+    blf.size(font_id, 20, 60)
22
+    blf.draw(font_id, ("{} {}".format("Offset: ",str(round(CO.RA_Offset, 2)))) )
23
+        
24
+    #* Object Selectable
25
+    blf.position(font_id, (width/2) + 50, (height/2) - 250, 0)    
26
+   
27
+    blf.draw(font_id, ("{} {}".format("Selectable: ",str(CO.RA_Sel_Status))) )
28
+    
29
+    #* Object Number "Count"
30
+    blf.position(font_id, (width/2) - 50, (height/2) - 250, 0)
31
+    if CO.RA_Unq_mode == True:
32
+        blf.color (font_id,0.5,0.5,0.5,1)
33
+    else:
34
+        blf.color (font_id,0.85,0.85,0.85,1)
35
+ 
36
+    blf.draw(font_id, ("{} {}".format("Count: ",str(round(CO.RA_ObjNum, 2)))) )    
37
+    #* Show/Hide Help
38
+    blf.color (font_id,1,1,1,1)
39
+    text = "Show/Hide Help 'H'"
40
+    blf.position(font_id, (width/2 - blf.dimensions(font_id, text)[0] / 2), (height/2) - 230, 0)
41
+   
42
+    blf.draw(font_id, text)
43
+    #+--------------------------------------------------------------+#
44
+    #* Unique Mode
45
+    blf.color (font_id,0.8,0.4,0.0,1)
46
+    text = "Unique Mode: "
47
+    blf.position(font_id, (width/2 - 84), (height/2) - 270, 0)
48
+    blf.draw(font_id, text)
49
+    #-------------------------#
50
+    if CO.RA_Unq_mode == True:
51
+        blf.color (font_id,0.1,0.94,0.4,1)
52
+        unq_text = "Active"
53
+    else:
54
+        blf.color (font_id,0.6,0.1,0.0,1)
55
+        unq_text = "--------"
56
+    blf.position(font_id, (width/2 + 34), (height/2) - 270, 0)
57
+    blf.draw(font_id, unq_text)
58
+    #+--------------------------------------------------------------+#
59
+    #* Help
60
+    blf.color (font_id,0.6,1,0.6,1)
61
+    if prefs.modal_help == True:
62
+        lines = ["Reset 'R'",
63
+        "Apply 'A'",
64
+        "Join 'J' ends radial mode and merges all objects",
65
+        "Grab 'G'",
66
+        "Unique Mode 'Q' unlinks objects data block",
67
+        "'RMB' and Esc to Cancel",
68
+        "'Shift' to snap offset",
69
+        "'Mouse Wheel' Increase/Decrease Count"
70
+        ]
71
+        for index, l  in enumerate(lines):
72
+            text = l
73
+            blf.position(font_id, (width/2) - 200, (height/2 -200) + 20 * index, 0)
74
+           
75
+            blf.draw(font_id, text)
76
+
77
+def RA_draw_B(self, context, prefs):
78
+    height = bpy.context.region.height
79
+    width = bpy.context.region.width
80
+    CO = bpy.context.object
81
+    #+-----------------------------------------------------------------------+#
82
+    vertices = (
83
+    (width/2 - 80 , height/2 - 215),(width/2 + 80, height/2 - 215),
84
+    (width/2 - 90, height/2 - 233),( width/2 + 90, height/2 - 233) ) 
85
+
86
+    indices = (
87
+        (0, 1, 2), (2, 1, 3))
88
+    
89
+    shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
90
+    batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)
91
+    
92
+    shader.bind()
93
+    
94
+    shader.uniform_float("color", (0.8,0.4,0.0,1))
95
+    batch.draw(shader)
96
+    #+-----------------------------------------------------------------------+#
97
+    vertices = (
98
+    (width/2 - 216 , height/2 - 234),(width/2 + 206, height/2 - 234),
99
+    (width/2 - 220, height/2 - 254),( width/2 + 200, height/2 - 254) ) 
100
+
101
+    indices = (
102
+        (0, 1, 2), (2, 1, 3))
103
+    
104
+    shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
105
+    batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)
106
+    
107
+    
108
+    
109
+    shader.bind()
110
+    shader.uniform_float("color", (0.15,0.15,0.15,1))
111
+    batch.draw(shader)
112
+    #+-----------------------------------------------------------------------+#
113
+    vertices = (
114
+    (width/2 - 96 , height/2 - 253),(width/2 + 96, height/2 - 253),
115
+    (width/2 - 86, height/2 - 274),( width/2 + 86, height/2 - 274) ) 
116
+
117
+    indices = (
118
+        (0, 1, 2), (2, 1, 3))
119
+    
120
+    shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
121
+    batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)
122
+    
123
+    shader.bind()
124
+    shader.uniform_float("color", (0.15,0.15,0.15,1))
125
+    batch.draw(shader)

+ 666
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__INIT__.PY ファイルの表示

@@ -0,0 +1,666 @@
1
+
2
+import bpy,math,mathutils,blf,rna_keymap_ui
3
+
4
+from .RA_draw_ui import *
5
+from mathutils import Matrix
6
+from bpy.types import (
7
+                        PropertyGroup,
8
+                        Menu
9
+                        )
10
+from bpy.props import (
11
+                        IntProperty,
12
+                        FloatProperty,
13
+                        BoolProperty
14
+                        )
15
+#// join objects option in modal operator
16
+#// Reset array option in modal operator
17
+#// Modal operator Ui
18
+#// add Radial Array hotkey 
19
+#// preferences add hotkey in addon preferences menu
20
+#// addon menu ui
21
+#// add modal selectable toggle
22
+#// add modal apply option
23
+#// add modal ui tooltips
24
+#// add make unique
25
+#// add create collection toggle
26
+
27
+
28
+bl_info = {
29
+    "name" : "R.Array",
30
+    "author" : "Syler",
31
+    "version": (0, 0, 1, 2),
32
+    "description": "Adds Radial Array Operator",
33
+    "blender" : (2, 80, 0),
34
+    "category" : "Object"
35
+}
36
+#+ handle the keymap
37
+addon_keymaps = []
38
+
39
+def add_hotkey(): 
40
+    #* Ctrl Q call R_Array
41
+    wm = bpy.context.window_manager
42
+    km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
43
+    kmi = km.keymap_items.new(R_Array.bl_idname, 'Q', 'PRESS', ctrl=True)
44
+    addon_keymaps.append(km)
45
+
46
+def remove_hotkey():
47
+    wm = bpy.context.window_manager
48
+    for km in addon_keymaps:
49
+        wm.keyconfigs.addon.keymaps.remove(km)
50
+    # clear the list
51
+    del addon_keymaps[:]
52
+#--------------------------------------------------------------------------------------#
53
+def RA_Update_Sel_Status(self, context):
54
+    if self.RA_Sel_Status == True:
55
+        for ob in self.RA_Parent.children:
56
+            ob.hide_select = False
57
+    if self.RA_Sel_Status == False:
58
+        for ob in self.RA_Parent.children:
59
+            ob.hide_select = True
60
+            
61
+def RA_Update_ObjNum(self, context):
62
+    
63
+    if self.RA_Status == True:
64
+        
65
+        if len(self.RA_Parent.children) == self.RA_ObjNum:  
66
+            pass
67
+        
68
+        #+ Add Objects
69
+        if len(self.RA_Parent.children) < self.RA_ObjNum:
70
+            object_list = []
71
+            object_to_copy = self.RA_Parent.children[0]
72
+            # append already existing objects to object list
73
+            for c in self.RA_Parent.children:
74
+                object_list.append(c)
75
+            
76
+            
77
+            for i in range (len(self.RA_Parent.children), self.RA_ObjNum):
78
+                object_list.append(object_to_copy.copy())
79
+                
80
+                
81
+                
82
+            # Add Objects To Collection
83
+            for index, ob in enumerate(object_list):
84
+                
85
+                # Reset Matrix
86
+                ob.matrix_basis = mathutils.Matrix()
87
+                
88
+                # set object location to RA_Parent + RA_Offset
89
+                ob.location[1] = self.RA_Parent.location[1] + self.RA_Parent.RA_Offset
90
+                # create angle variable 
91
+                angle = math.radians(360/self.RA_Parent.RA_ObjNum)               
92
+                
93
+                # rotate object
94
+                R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z')
95
+                T = mathutils.Matrix.Translation([0, 0, 0])     
96
+                M = T @ R @ T.inverted()
97
+                ob.location = M @ ob.location
98
+                ob.rotation_euler.rotate(M)
99
+                
100
+                
101
+                # Parent Object 
102
+                ob.parent = self.RA_Parent
103
+                self.RA_Parent.matrix_parent_inverse = ob.matrix_world.inverted()
104
+                ob.RA_Parent = self.RA_Parent
105
+                
106
+                # make objects selectable/unselectable
107
+                if self.RA_Sel_Status == True:
108
+                    ob.hide_select = False
109
+                if self.RA_Sel_Status == False:
110
+                    ob.hide_select = True
111
+    
112
+                # Change Object Name
113
+                ob.name = "RA - " + self.RA_Name + " - " + str(index)
114
+                # set RA Status
115
+                ob.RA_Status = True
116
+                # Link object
117
+                try:
118
+                    self.RA_Parent.users_collection[0].objects.link(ob)
119
+                    #print ("For LINK")
120
+                except:
121
+                    #print ("PASS Linking object to collection failed")
122
+                    pass
123
+    
124
+        #+ Remove Objects
125
+        if len(self.RA_Parent.children) > self.RA_ObjNum:
126
+                
127
+            # deselect all objects
128
+            for d in bpy.context.view_layer.objects:
129
+                d.select_set(False)
130
+            bpy.context.view_layer.objects.active = None
131
+            
132
+            # Make selectable and Select all objects that will be deleted
133
+            for i in range (self.RA_ObjNum, len(self.RA_Parent.children)):
134
+                self.RA_Parent.children[i].hide_select = False
135
+                self.RA_Parent.children[i].select_set(True)
136
+            # Delete Objects     
137
+            bpy.ops.object.delete()
138
+            # select control Object
139
+            bpy.context.view_layer.objects.active = self.RA_Parent
140
+            self.RA_Parent.select_set(True)
141
+            for index, ob in enumerate(self.RA_Parent.children):
142
+                # Reset Matrix
143
+                ob.matrix_basis = mathutils.Matrix()
144
+            
145
+                # set object location to RA_Parent + RA_Offset
146
+                ob.location[1] = self.RA_Parent.location[1] + self.RA_Parent.RA_Offset
147
+                # create angle variable 
148
+                angle = math.radians(360/self.RA_Parent.RA_ObjNum)
149
+            
150
+                # rotate object
151
+                R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z')
152
+                T = mathutils.Matrix.Translation([0, 0, 0])     
153
+                M = T @ R @ T.inverted()
154
+                ob.location = M @ ob.location
155
+                ob.rotation_euler.rotate(M)
156
+
157
+def RA_Update_Offset(self, context):
158
+    
159
+    if self.RA_Status == True:              
160
+        for ob in self.RA_Parent.children:      
161
+            # define variables
162
+            loc = mathutils.Vector((0.0, self.RA_Offset, 0.0))            
163
+            rot = ob.rotation_euler
164
+            # rotate location    
165
+            loc.rotate(rot)
166
+            # apply rotation
167
+            ob.location = loc
168
+    else:
169
+        pass
170
+#--------------------------------------------------------------------------------------#
171
+class R_Array(bpy.types.Operator):  
172
+    bl_idname = 'sop.r_array'
173
+    bl_label = 'Radial Array'
174
+    bl_description = 'Radial Array S.Operator'
175
+    bl_options = {'REGISTER', 'UNDO'}
176
+
177
+    
178
+    
179
+    
180
+    #?Useless !?
181
+    @classmethod
182
+    def poll(cls, context):
183
+       return True
184
+    
185
+    def execute(self, context):
186
+        
187
+        #Create Bpy.context Variable
188
+        C = bpy.context
189
+        active_object = C.active_object
190
+        
191
+        
192
+        # call modal if RA_Status = True
193
+        try:
194
+            if active_object.RA_Status == True:
195
+                bpy.ops.sop.ra_modal('INVOKE_DEFAULT')
196
+                return {'FINISHED'}
197
+        except:
198
+            pass
199
+        # Check Selected Cancel if NOT Mesh
200
+        if C.selected_objects == [] or C.active_object.type != 'MESH':
201
+            self.report({'INFO'}, "No Mesh Selected")
202
+            return {'CANCELLED'}
203
+        
204
+        
205
+        # Create Variables
206
+        L_Objects = []                              # object list 
207
+        ob = active_object                          # active object reference 
208
+        ob_collections = ob.users_collection        # active Object collections
209
+        f_name = ob.name                            # Object Name 
210
+        point = ob.location.copy()                  # Middle point 
211
+        is_col_new  = True
212
+
213
+        
214
+        # Create New Collection             
215
+        if bpy.context.preferences.addons[__name__].preferences.col_toggle == True:
216
+            for q in bpy.data.collections:
217
+                if q.name == "RA -" + f_name:
218
+                    collection = q
219
+                    is_col_new = False
220
+                    try:
221
+                        for col in ob_collections:
222
+                            col.objects.unlink(ob)
223
+                        collection.objects.link(ob)
224
+                    except:
225
+                        pass
226
+        
227
+                
228
+            if is_col_new == True:
229
+                # create and link new collection
230
+                collection = bpy.data.collections.new(name="RA -" + f_name)
231
+                bpy.context.scene.collection.children.link(collection)
232
+                print ("NEW")
233
+                # Move Object to collection
234
+                for col in ob_collections:
235
+                    col.objects.unlink(ob)
236
+                collection.objects.link(ob)
237
+        else:
238
+            collection = ob_collections[0]
239
+
240
+        # Create/Location/Name/Status/set RA_Parent/Link Empty and other memery
241
+        empty = bpy.data.objects.new( "empty", None )
242
+        empty.location = point
243
+        empty.name = ".RA - " + ob.name + " - Control Empty"
244
+        empty.RA_Status = True
245
+        empty.RA_Parent = empty
246
+        empty.RA_Name = f_name
247
+        empty.RA_Sel_Status = bpy.context.preferences.addons[__name__].preferences.selectable
248
+        collection.objects.link(empty)
249
+         
250
+        # Move object
251
+        ob.location[1] = ob.location[1] + ob.RA_Offset
252
+
253
+        # Deselect Active Object and select Control Object
254
+        ob.select_set(False)
255
+        empty.select_set(True)
256
+
257
+        # set empty as active object 
258
+        bpy.context.view_layer.objects.active = empty
259
+
260
+        # create duplicate objects
261
+        for o in range(0, empty.RA_ObjNum):
262
+
263
+            if o == 0:
264
+                L_Objects.append(ob)
265
+            if o != 0:
266
+                L_Objects.append(ob.copy())
267
+        # Add Objects To Collection
268
+        for index, ob in enumerate(L_Objects):
269
+            # create angle variable 
270
+            angle = math.radians(360/empty.RA_ObjNum)
271
+
272
+           
273
+            # rotate object
274
+            R = mathutils.Matrix.Rotation(angle * (index), 4, 'Z')
275
+            T = mathutils.Matrix.Translation([0, 0, 0])     
276
+            M = T @ R @ T.inverted()
277
+            ob.location = M @ ob.location
278
+            ob.rotation_euler.rotate(M)
279
+
280
+            # Parent Object 
281
+            ob.parent = empty
282
+            empty.matrix_parent_inverse = ob.matrix_world.inverted()
283
+            ob.RA_Parent = empty
284
+
285
+            # make objects selectable/unselectable
286
+            if empty.RA_Sel_Status == True:
287
+                ob.hide_select = False
288
+            if empty.RA_Sel_Status == False:
289
+                ob.hide_select = True
290
+
291
+            # Change Object Name
292
+            ob.name = "RA - " + str(f_name) + " - " + str(index)
293
+            # Set RA Status
294
+            ob.RA_Status = True
295
+            
296
+            # Link object
297
+            try:
298
+                collection.objects.link(ob)
299
+                #print ("For LINK")
300
+            except:
301
+                #print ("PASS Linking object to collection failed")
302
+                pass
303
+        bpy.ops.sop.ra_modal('INVOKE_DEFAULT')
304
+        
305
+        return {'FINISHED'} 
306
+#--------------------------------------------------------------------------------------#
307
+class RA_Modal(bpy.types.Operator):
308
+    # Change Radial Array
309
+    bl_idname = "sop.ra_modal"
310
+    bl_label = "Radial Array Modal"
311
+    bl_options = {"REGISTER", "UNDO", "BLOCKING", "GRAB_CURSOR", "INTERNAL"} #- add later!?  
312
+
313
+    first_mouse_x: IntProperty()
314
+    I_RA_Offset: FloatProperty()
315
+    I_RA_ObjNum: IntProperty()
316
+    unq_mode: BoolProperty()
317
+    
318
+
319
+    def modal(self, context, event):
320
+        
321
+        # context shortcut
322
+        C = context
323
+        OB = C.object
324
+        context.area.tag_redraw() #?
325
+        prefs = bpy.context.preferences.addons[__name__].preferences
326
+        # -------------------------------------------------------------#     
327
+        #+ change offset        
328
+        if event.type == 'MOUSEMOVE' :
329
+            delta = self.first_mouse_x - event.mouse_x
330
+            if event.shift:
331
+                C.object.RA_Offset = round((self.I_RA_Offset + delta * 0.01))
332
+            else:
333
+                C.object.RA_Offset = self.I_RA_Offset + delta * 0.01
334
+         # -------------------------------------------------------------#
335
+        #+ add/remove Objects      
336
+        if event.type == 'WHEELUPMOUSE' and OB.RA_Unq_mode == False:
337
+            OB.RA_ObjNum = OB.RA_ObjNum + 1
338
+            
339
+        if event.type == 'WHEELDOWNMOUSE' and OB.RA_Unq_mode == False:
340
+            OB.RA_ObjNum = OB.RA_ObjNum - 1
341
+        # -------------------------------------------------------------#
342
+        #+ call the tarnslation operator
343
+        if event.type == 'G' and event.value == "PRESS":
344
+               
345
+            C.tool_settings.use_snap = True
346
+            C.tool_settings.snap_elements = {'FACE'}
347
+            C.tool_settings.use_snap_align_rotation = True
348
+           
349
+            bpy.ops.transform.translate('INVOKE_DEFAULT')
350
+            bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
351
+            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
352
+            return {'FINISHED'}
353
+        # -------------------------------------------------------------#
354
+        
355
+        #+ join objects               
356
+        if event.type == 'J' and event.value == "PRESS":
357
+            objects = OB.RA_Parent.children
358
+            location = OB.RA_Parent.location
359
+            cursor_location = bpy.context.scene.cursor.location.copy()
360
+            
361
+            # deselect objects and select control object
362
+            for o in C.selected_objects:
363
+                o.select_set(False)
364
+            C.object.RA_Parent.hide_select = False
365
+            bpy.context.view_layer.objects.active = C.object.RA_Parent
366
+            C.object.RA_Parent.select_set(True)
367
+            
368
+            # Delete control object 
369
+            bpy.ops.object.delete()
370
+
371
+            for ob in objects:
372
+                ob.hide_select = False
373
+                ob.select_set(True)
374
+            bpy.context.view_layer.objects.active = objects[0]
375
+            
376
+                      
377
+            bpy.context.scene.cursor.location = location
378
+            bpy.ops.view3d.snap_selected_to_cursor(use_offset=True)                 
379
+            bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM')             
380
+            bpy.ops.object.join()
381
+            bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
382
+            bpy.context.scene.cursor.location = cursor_location 
383
+            bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
384
+            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
385
+            return {'FINISHED'}
386
+        # -------------------------------------------------------------#      
387
+        
388
+        #+ Reset                   
389
+        if event.type == 'R' and event.value == "PRESS":
390
+            
391
+            objects = OB.RA_Parent.children
392
+            name = OB.RA_Parent.RA_Name
393
+            # deslect all objects
394
+            for o in C.selected_objects:
395
+                o.select_set(False)
396
+            # select objects
397
+            for ob in objects:
398
+               if ob != objects[0]:
399
+                    ob.hide_select = False
400
+                    ob.select_set(True) 
401
+            # delete objects
402
+            bpy.ops.object.delete()
403
+                
404
+            # select object and clear parent and other memery
405
+            objects[0].location = objects[0].RA_Parent.location   
406
+            objects[0].RA_Parent.select_set(True)
407
+            bpy.ops.object.delete()
408
+            objects[0].hide_select = False
409
+            bpy.context.view_layer.objects.active = objects[0]
410
+            objects[0].select_set(True)
411
+            objects[0].parent = None
412
+            objects[0].name = name
413
+            try:
414
+                del objects[0]["RA_Parent"]
415
+                del objects[0]["RA_Status"]
416
+            except:
417
+                pass
418
+            
419
+            bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
420
+            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
421
+            return {'FINISHED'}
422
+        #+ Apply                   
423
+        if event.type == 'A' and event.value == "PRESS":
424
+            
425
+            objects = OB.RA_Parent.children
426
+            # deslect all objects
427
+            for o in C.selected_objects:
428
+                o.select_set(False)
429
+            # select and delete control object
430
+            objects[0].RA_Parent.select_set(True)
431
+            bpy.ops.object.delete()
432
+            # select objects    
433
+            for ob in objects:
434
+            
435
+               ob.hide_select = False
436
+               ob.select_set(True)
437
+               ob.RA_Status = False
438
+               ob.parent = None
439
+
440
+            bpy.context.view_layer.objects.active = objects[0]
441
+            bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
442
+            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
443
+            return {'FINISHED'}    
444
+        #+ Make Unique Mode toggle
445
+        if event.type == 'Q' and event.value == "PRESS":
446
+            objects = OB.RA_Parent.children
447
+            if OB.RA_Unq_mode == True:
448
+                for ob in objects:
449
+                    ob.data = objects[0].data
450
+                OB.RA_Unq_mode = False
451
+            else:
452
+            #* make unique data    
453
+                for ob in objects:
454
+                    ob.data = ob.data.copy()
455
+                OB.RA_Unq_mode = True
456
+        #+ Selectable toggle
457
+        if event.type == 'S' and event.value == "PRESS":
458
+            if OB.RA_Sel_Status == True:
459
+                OB.RA_Sel_Status = False
460
+            else:
461
+                OB.RA_Sel_Status = True
462
+        #+ Help Mode toggle
463
+        if event.type == 'H' and event.value == "PRESS":
464
+            if prefs.modal_help == True:
465
+                prefs.modal_help = False
466
+            else:
467
+                prefs.modal_help = True
468
+        # -------------------------------------------------------------# 
469
+        #+ Finish/Cancel Modal        
470
+        elif event.type == 'LEFTMOUSE':
471
+            bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
472
+            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
473
+            return {'FINISHED'}
474
+
475
+        elif event.type in {'RIGHTMOUSE', 'ESC'}:
476
+            C.object.RA_Offset = self.I_RA_Offset
477
+            C.object.RA_ObjNum = self.I_RA_ObjNum
478
+            bpy.types.SpaceView3D.draw_handler_remove(self.ra_draw_b, 'WINDOW')
479
+            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
480
+            return {'CANCELLED'}
481
+
482
+        return {'RUNNING_MODAL'}
483
+
484
+    def invoke(self, context, event):
485
+        # context shortcut
486
+        C = context
487
+        if  C.object.RA_Status == True:
488
+            for o in C.selected_objects:
489
+                o.select_set(False)
490
+            bpy.context.view_layer.objects.active = C.object.RA_Parent
491
+            C.object.RA_Parent.select_set(True)
492
+           
493
+            
494
+        
495
+        if C.object:
496
+            # set initial Variable values
497
+            self.first_mouse_x = event.mouse_x
498
+            self.I_RA_Offset = C.object.RA_Offset
499
+            self.I_RA_ObjNum = C.object.RA_ObjNum
500
+            self.unq_mode = C.object.RA_Unq_mode
501
+            self.prefs = bpy.context.preferences.addons[__name__].preferences
502
+            ###-------------------------------------------###
503
+            args = (self, context, self.prefs)
504
+            
505
+            
506
+            self.ra_draw_b = bpy.types.SpaceView3D.draw_handler_add(RA_draw_B, args, 'WINDOW', 'POST_PIXEL')
507
+            self._handle = bpy.types.SpaceView3D.draw_handler_add(RA_modal_Draw, args, 'WINDOW', 'POST_PIXEL')
508
+            
509
+            self.mouse_path = []
510
+
511
+            context.window_manager.modal_handler_add(self)
512
+            return {'RUNNING_MODAL'}
513
+        else:
514
+            self.report({'WARNING'}, "No active object, could not finish")
515
+            return {'CANCELLED'}
516
+#--------------------------------------------------------------------------------------#
517
+class RA_Prefs(bpy.types.AddonPreferences):
518
+    bl_idname = __name__
519
+    # here you define the addons customizable props
520
+    offset:     bpy.props.FloatProperty(default=5)
521
+    objnum:     bpy.props.IntProperty(default=6)
522
+    selectable: bpy.props.BoolProperty(default= True, description="False = Only Control Object is selectable")
523
+    modal_help: bpy.props.BoolProperty(default= False, description="True = Display Help text in modal")
524
+    col_toggle: bpy.props.BoolProperty(default= False, description="True = Create New Collection")
525
+    # here you specify how they are drawn
526
+    def draw(self, context):
527
+        layout = self.layout
528
+        box = layout.box()
529
+        split = box.split()
530
+        col = split.column() 
531
+        # Layout ---------------------------------------------------------------- #
532
+        col.label(text="Default Values:")
533
+        col.prop(self, "offset",text="Default Offset")
534
+        col.prop(self, "objnum",text="Default Count")
535
+        col.prop(self, "selectable",text="Selectable")
536
+        col.prop(self, "modal_help",text="Modal Help")
537
+        col.label(text ="Options:")
538
+        col.prop(self, "col_toggle",text="Create New Collection")
539
+        col.label(text="Keymap:")
540
+        
541
+        
542
+        wm = bpy.context.window_manager
543
+        kc = wm.keyconfigs.user
544
+        km = kc.keymaps['Object Mode']
545
+        #kmi = km.keymap_items[0]
546
+        kmi = get_hotkey_entry_item(km, 'sop.r_array', 'sop.r_array')
547
+        
548
+        if addon_keymaps:
549
+            km = addon_keymaps[0].active()
550
+            col.context_pointer_set("keymap", km)
551
+            rna_keymap_ui.draw_kmi([], kc, km, kmi, col, 0)
552
+
553
+    
554
+
555
+def get_addon_preferences():
556
+    ''' quick wrapper for referencing addon preferences '''
557
+    addon_preferences = bpy.context.user_preferences.addons[__name__].preferences
558
+    return addon_preferences
559
+def get_hotkey_entry_item(km, kmi_name, kmi_value):
560
+    '''
561
+    returns hotkey of specific type, with specific properties.name (keymap is not a dict, so referencing by keys is not enough
562
+    if there are multiple hotkeys!)
563
+    '''
564
+    for i, km_item in enumerate(km.keymap_items):
565
+        if km.keymap_items.keys()[i] == kmi_name:
566
+            if km.keymap_items[i].idname == kmi_value:
567
+                return km_item
568
+    return None 
569
+
570
+classes = (
571
+    RA_Prefs,
572
+    R_Array,
573
+    RA_Modal,
574
+)
575
+
576
+
577
+def register():
578
+    print ("----------------------------------")
579
+    print ("S.Ops Init")
580
+    print ("----------------------------------")
581
+    
582
+    #+ add hotkey
583
+    add_hotkey()
584
+
585
+    from bpy.utils import register_class
586
+    for cls in classes:
587
+        register_class(cls)
588
+    # Init Props 
589
+    
590
+    bpy.types.Object.RA_Parent = bpy.props.PointerProperty(
591
+    name="RA Parent",
592
+    description="RA Parent Object Reference",
593
+    type=bpy.types.Object
594
+    )
595
+
596
+    bpy.types.Object.RA_ObjNum = bpy.props.IntProperty(
597
+    name="RA ObjNum",
598
+    description="RA Object Number",
599
+    default = bpy.context.preferences.addons[__name__].preferences.objnum,
600
+    min = 1,
601
+    update = RA_Update_ObjNum
602
+    )
603
+   
604
+    bpy.types.Object.RA_Offset = bpy.props.FloatProperty(
605
+    name="Offset",
606
+    description="Radial Array Offset",
607
+    default = bpy.context.preferences.addons[__name__].preferences.offset,
608
+    update = RA_Update_Offset
609
+    )   
610
+       
611
+    bpy.types.Object.RA_Status = bpy.props.BoolProperty(
612
+    name="Status",
613
+    description="Radial Array Status",
614
+    default = False
615
+    )
616
+    
617
+    bpy.types.Object.RA_Sel_Status = bpy.props.BoolProperty(
618
+    name="Selectable",
619
+    description="False = Only Control Object is selectable",
620
+    default = bpy.context.preferences.addons[__name__].preferences.selectable,
621
+    update = RA_Update_Sel_Status
622
+    )
623
+
624
+    bpy.types.Object.RA_Unq_mode = bpy.props.BoolProperty(
625
+    name="Unique Mode",
626
+    description="True = all objects have a unique data block(Disables Count in Modal)",
627
+    default = False
628
+    )
629
+    bpy.types.Object.RA_Name = bpy.props.StringProperty(
630
+    name="Name",
631
+    description="Radial Array Name",
632
+    default = "Nameing Error"
633
+    )
634
+    
635
+   
636
+    print ("----------------------------------")
637
+    print ("S.Ops Register End")
638
+    print ("----------------------------------") 
639
+
640
+
641
+def unregister():
642
+    print ("----------------------------------")
643
+    print ("S.Ops unRegister Start")
644
+    print ("----------------------------------") 
645
+    #+ remove hotkey
646
+    remove_hotkey()
647
+    
648
+    from bpy.utils import unregister_class
649
+    for cls in classes:
650
+        unregister_class(cls)
651
+  
652
+
653
+ 
654
+   
655
+    
656
+    print ("----------------------------------")
657
+    print ("S.Ops unRegister End")
658
+    print ("----------------------------------") 
659
+  
660
+if __name__ == "__main__":
661
+    register()
662
+
663
+
664
+
665
+
666
+

バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__PYCACHE__/RA_DRAW_UI.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/R_ARRAY-MASTER/__PYCACHE__/__INIT__.CPYTHON-37.PYC ファイルの表示


+ 1360
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/SPACE_VIEW_3D_DISPLAY_TOOLS.PY
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 3235
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/COLORS_GROUPS_EXCHANGER.PY
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 345
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/DUAL_MESH.PY ファイルの表示

@@ -0,0 +1,345 @@
1
+# ##### BEGIN GPL LICENSE BLOCK #####
2
+#
3
+#  This program is free software; you can redistribute it and/or
4
+#  modify it under the terms of the GNU General Public License
5
+#  as published by the Free Software Foundation; either version 2
6
+#  of the License, or (at your option) any later version.
7
+#
8
+#  This program is distributed in the hope that it will be useful,
9
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+#  GNU General Public License for more details.
12
+#
13
+#  You should have received a copy of the GNU General Public License
14
+#  along with this program; if not, write to the Free Software Foundation,
15
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
+#
17
+# ##### END GPL LICENSE BLOCK #####
18
+
19
+# --------------------------------- DUAL MESH -------------------------------- #
20
+# -------------------------------- version 0.3 ------------------------------- #
21
+#                                                                              #
22
+# Convert a generic mesh to its dual. With open meshes it can get some wired   #
23
+# effect on the borders.                                                       #
24
+#                                                                              #
25
+#                        (c)   Alessandro Zomparelli                           #
26
+#                                    (2017)                                    #
27
+#                                                                              #
28
+# http://www.co-de-it.com/                                                     #
29
+#                                                                              #
30
+# ############################################################################ #
31
+
32
+
33
+import bpy
34
+from bpy.types import Operator
35
+from bpy.props import (
36
+        BoolProperty,
37
+        EnumProperty,
38
+        )
39
+import bmesh
40
+from .utils import *
41
+
42
+
43
+class dual_mesh_tessellated(Operator):
44
+    bl_idname = "object.dual_mesh_tessellated"
45
+    bl_label = "Dual Mesh"
46
+    bl_description = ("Generate a polygonal mesh using Tessellate. (Non-destructive)")
47
+    bl_options = {'REGISTER', 'UNDO'}
48
+
49
+    apply_modifiers : BoolProperty(
50
+        name="Apply Modifiers",
51
+        default=True,
52
+        description="Apply object's modifiers"
53
+        )
54
+
55
+    source_faces : EnumProperty(
56
+            items=[
57
+                ('QUAD', 'Quad Faces', ''),
58
+                ('TRI', 'Triangles', '')],
59
+            name="Source Faces",
60
+            description="Source polygons",
61
+            default="QUAD",
62
+            options={'LIBRARY_EDITABLE'}
63
+            )
64
+
65
+    def execute(self, context):
66
+        auto_layer_collection()
67
+        ob0 = context.object
68
+        name1 = "DualMesh_{}_Component".format(self.source_faces)
69
+        # Generate component
70
+        if self.source_faces == 'QUAD':
71
+            verts = [(0.0, 0.0, 0.0), (0.0, 0.5, 0.0),
72
+                    (0.0, 1.0, 0.0), (0.5, 1.0, 0.0),
73
+                    (1.0, 1.0, 0.0), (1.0, 0.5, 0.0),
74
+                    (1.0, 0.0, 0.0), (0.5, 0.0, 0.0),
75
+                    (1/3, 1/3, 0.0), (2/3, 2/3, 0.0)]
76
+            edges = [(0,1), (1,2), (2,3), (3,4), (4,5), (5,6), (6,7),
77
+                        (7,0), (1,8), (8,7), (3,9), (9,5), (8,9)]
78
+            faces = [(7,8,1,0), (8,9,3,2,1), (9,5,4,3), (9,8,7,6,5)]
79
+        else:
80
+            verts = [(0.0,0.0,0.0), (0.5,0.0,0.0), (1.0,0.0,0.0), (0.0,1.0,0.0), (0.5,1.0,0.0), (1.0,1.0,0.0)]
81
+            edges = [(0,1), (1,2), (2,5), (5,4), (4,3), (3,0), (1,4)]
82
+            faces = [(0,1,4,3), (1,2,5,4)]
83
+
84
+        # check pre-existing component
85
+        try:
86
+            _verts = [0]*len(verts)*3
87
+            __verts = [c for co in verts for c in co]
88
+            ob1 = bpy.data.objects[name1]
89
+            ob1.data.vertices.foreach_get("co",_verts)
90
+            for a, b in zip(_verts, __verts):
91
+                if abs(a-b) > 0.0001:
92
+                    raise ValueError
93
+        except:
94
+            me = bpy.data.meshes.new("Dual-Mesh")  # add a new mesh
95
+            me.from_pydata(verts, edges, faces)
96
+            me.update(calc_edges=True, calc_edges_loose=True)
97
+            if self.source_faces == 'QUAD': n_seams = 8
98
+            else: n_seams = 6
99
+            for i in range(n_seams): me.edges[i].use_seam = True
100
+            ob1 = bpy.data.objects.new(name1, me)
101
+            context.collection.objects.link(ob1)
102
+            # fix visualization issue
103
+            context.view_layer.objects.active = ob1
104
+            ob1.select_set(True)
105
+            bpy.ops.object.editmode_toggle()
106
+            bpy.ops.object.editmode_toggle()
107
+            ob1.select_set(False)
108
+            # hide component
109
+            ob1.hide_select = True
110
+            ob1.hide_render = True
111
+            ob1.hide_viewport = True
112
+        ob = convert_object_to_mesh(ob0,False,False)
113
+        ob.name = 'DualMesh'
114
+        #ob = bpy.data.objects.new("DualMesh", convert_object_to_mesh(ob0,False,False))
115
+        #context.collection.objects.link(ob)
116
+        #context.view_layer.objects.active = ob
117
+        #ob.select_set(True)
118
+        ob.tissue_tessellate.component = ob1
119
+        ob.tissue_tessellate.generator = ob0
120
+        ob.tissue_tessellate.gen_modifiers = self.apply_modifiers
121
+        ob.tissue_tessellate.merge = True
122
+        ob.tissue_tessellate.bool_dissolve_seams = True
123
+        if self.source_faces == 'TRI': ob.tissue_tessellate.fill_mode = 'FAN'
124
+        bpy.ops.object.update_tessellate()
125
+        ob.location = ob0.location
126
+        ob.matrix_world = ob0.matrix_world
127
+        return {'FINISHED'}
128
+
129
+    def invoke(self, context, event):
130
+        return context.window_manager.invoke_props_dialog(self)
131
+
132
+class dual_mesh(Operator):
133
+    bl_idname = "object.dual_mesh"
134
+    bl_label = "Convert to Dual Mesh"
135
+    bl_description = ("Convert a generic mesh into a polygonal mesh. (Destructive)")
136
+    bl_options = {'REGISTER', 'UNDO'}
137
+
138
+    quad_method : EnumProperty(
139
+            items=[('BEAUTY', 'Beauty',
140
+                    'Split the quads in nice triangles, slower method'),
141
+                    ('FIXED', 'Fixed',
142
+                    'Split the quads on the 1st and 3rd vertices'),
143
+                    ('FIXED_ALTERNATE', 'Fixed Alternate',
144
+                    'Split the quads on the 2nd and 4th vertices'),
145
+                    ('SHORTEST_DIAGONAL', 'Shortest Diagonal',
146
+                    'Split the quads based on the distance between the vertices')
147
+                    ],
148
+            name="Quad Method",
149
+            description="Method for splitting the quads into triangles",
150
+            default="FIXED",
151
+            options={'LIBRARY_EDITABLE'}
152
+            )
153
+    polygon_method : EnumProperty(
154
+            items=[
155
+                ('BEAUTY', 'Beauty', 'Arrange the new triangles evenly'),
156
+                ('CLIP', 'Clip',
157
+                 'Split the polygons with an ear clipping algorithm')],
158
+            name="Polygon Method",
159
+            description="Method for splitting the polygons into triangles",
160
+            default="BEAUTY",
161
+            options={'LIBRARY_EDITABLE'}
162
+            )
163
+    preserve_borders : BoolProperty(
164
+            name="Preserve Borders",
165
+            default=True,
166
+            description="Preserve original borders"
167
+            )
168
+    apply_modifiers : BoolProperty(
169
+            name="Apply Modifiers",
170
+            default=True,
171
+            description="Apply object's modifiers"
172
+            )
173
+
174
+    def execute(self, context):
175
+        mode = context.mode
176
+        if mode == 'EDIT_MESH':
177
+            mode = 'EDIT'
178
+        act = context.active_object
179
+        if mode != 'OBJECT':
180
+            sel = [act]
181
+            bpy.ops.object.mode_set(mode='OBJECT')
182
+        else:
183
+            sel = context.selected_objects
184
+        doneMeshes = []
185
+
186
+        for ob0 in sel:
187
+            if ob0.type != 'MESH':
188
+                continue
189
+            if ob0.data.name in doneMeshes:
190
+                continue
191
+            ob = ob0
192
+            mesh_name = ob0.data.name
193
+
194
+            # store linked objects
195
+            clones = []
196
+            n_users = ob0.data.users
197
+            count = 0
198
+            for o in bpy.data.objects:
199
+                if o.type != 'MESH':
200
+                    continue
201
+                if o.data.name == mesh_name:
202
+                    count += 1
203
+                    clones.append(o)
204
+                if count == n_users:
205
+                    break
206
+
207
+            if self.apply_modifiers:
208
+                bpy.ops.object.convert(target='MESH')
209
+            ob.data = ob.data.copy()
210
+            bpy.ops.object.select_all(action='DESELECT')
211
+            ob.select_set(True)
212
+            context.view_layer.objects.active = ob0
213
+            bpy.ops.object.mode_set(mode='EDIT')
214
+
215
+            # prevent borders erosion
216
+            bpy.ops.mesh.select_mode(
217
+                    use_extend=False, use_expand=False, type='EDGE'
218
+                    )
219
+            bpy.ops.mesh.select_non_manifold(
220
+                    extend=False, use_wire=False, use_boundary=True,
221
+                    use_multi_face=False, use_non_contiguous=False,
222
+                    use_verts=False
223
+                    )
224
+            bpy.ops.mesh.extrude_region_move(
225
+                    MESH_OT_extrude_region={"mirror": False},
226
+                    TRANSFORM_OT_translate={"value": (0, 0, 0)}
227
+                    )
228
+
229
+            bpy.ops.mesh.select_mode(
230
+                    use_extend=False, use_expand=False, type='VERT',
231
+                    action='TOGGLE'
232
+                    )
233
+            bpy.ops.mesh.select_all(action='SELECT')
234
+            bpy.ops.mesh.quads_convert_to_tris(
235
+                    quad_method=self.quad_method, ngon_method=self.polygon_method
236
+                    )
237
+            bpy.ops.mesh.select_all(action='DESELECT')
238
+            bpy.ops.object.mode_set(mode='OBJECT')
239
+            bpy.ops.object.modifier_add(type='SUBSURF')
240
+            ob.modifiers[-1].name = "dual_mesh_subsurf"
241
+            while True:
242
+                bpy.ops.object.modifier_move_up(modifier="dual_mesh_subsurf")
243
+                if ob.modifiers[0].name == "dual_mesh_subsurf":
244
+                    break
245
+
246
+            bpy.ops.object.modifier_apply(
247
+                    apply_as='DATA', modifier='dual_mesh_subsurf'
248
+                    )
249
+
250
+            bpy.ops.object.mode_set(mode='EDIT')
251
+            bpy.ops.mesh.select_all(action='DESELECT')
252
+
253
+            verts = ob.data.vertices
254
+
255
+            bpy.ops.object.mode_set(mode='OBJECT')
256
+            verts[-1].select = True
257
+            bpy.ops.object.mode_set(mode='EDIT')
258
+            bpy.ops.mesh.select_more(use_face_step=False)
259
+
260
+            bpy.ops.mesh.select_similar(
261
+                type='EDGE', compare='EQUAL', threshold=0.01)
262
+            bpy.ops.mesh.select_all(action='INVERT')
263
+
264
+            bpy.ops.mesh.dissolve_verts()
265
+            bpy.ops.mesh.select_all(action='DESELECT')
266
+
267
+            bpy.ops.mesh.select_non_manifold(
268
+                extend=False, use_wire=False, use_boundary=True,
269
+                use_multi_face=False, use_non_contiguous=False, use_verts=False)
270
+            bpy.ops.mesh.select_more()
271
+
272
+            # find boundaries
273
+            bpy.ops.object.mode_set(mode='OBJECT')
274
+            bound_v = [v.index for v in ob.data.vertices if v.select]
275
+            bound_e = [e.index for e in ob.data.edges if e.select]
276
+            bound_p = [p.index for p in ob.data.polygons if p.select]
277
+            bpy.ops.object.mode_set(mode='EDIT')
278
+
279
+            # select quad faces
280
+            context.tool_settings.mesh_select_mode = (False, False, True)
281
+            bpy.ops.mesh.select_face_by_sides(number=4, extend=False)
282
+
283
+            # deselect boundaries
284
+            bpy.ops.object.mode_set(mode='OBJECT')
285
+            for i in bound_v:
286
+                context.active_object.data.vertices[i].select = False
287
+            for i in bound_e:
288
+                context.active_object.data.edges[i].select = False
289
+            for i in bound_p:
290
+                context.active_object.data.polygons[i].select = False
291
+
292
+            bpy.ops.object.mode_set(mode='EDIT')
293
+
294
+            context.tool_settings.mesh_select_mode = (False, False, True)
295
+            bpy.ops.mesh.edge_face_add()
296
+            context.tool_settings.mesh_select_mode = (True, False, False)
297
+            bpy.ops.mesh.select_all(action='DESELECT')
298
+
299
+            # delete boundaries
300
+            bpy.ops.mesh.select_non_manifold(
301
+                    extend=False, use_wire=True, use_boundary=True,
302
+                    use_multi_face=False, use_non_contiguous=False, use_verts=True
303
+                    )
304
+            bpy.ops.mesh.delete(type='VERT')
305
+
306
+            # remove middle vertices
307
+            bm = bmesh.from_edit_mesh(ob.data)
308
+            for v in bm.verts:
309
+                if len(v.link_edges) == 2 and len(v.link_faces) < 3:
310
+                    v.select = True
311
+
312
+            # dissolve
313
+            bpy.ops.mesh.dissolve_verts()
314
+            bpy.ops.mesh.select_all(action='DESELECT')
315
+
316
+            # remove border faces
317
+            if not self.preserve_borders:
318
+                bpy.ops.mesh.select_non_manifold(
319
+                    extend=False, use_wire=False, use_boundary=True,
320
+                    use_multi_face=False, use_non_contiguous=False, use_verts=False
321
+                    )
322
+                bpy.ops.mesh.select_more()
323
+                bpy.ops.mesh.delete(type='FACE')
324
+
325
+            # clean wires
326
+            bpy.ops.mesh.select_non_manifold(
327
+                    extend=False, use_wire=True, use_boundary=False,
328
+                    use_multi_face=False, use_non_contiguous=False, use_verts=False
329
+                    )
330
+            bpy.ops.mesh.delete(type='EDGE')
331
+
332
+            bpy.ops.object.mode_set(mode='OBJECT')
333
+            ob0.data.name = mesh_name
334
+            doneMeshes.append(mesh_name)
335
+
336
+            for o in clones:
337
+                o.data = ob.data
338
+
339
+        for o in sel:
340
+            o.select_set(True)
341
+
342
+        context.view_layer.objects.active = act
343
+        bpy.ops.object.mode_set(mode=mode)
344
+
345
+        return {'FINISHED'}

+ 488
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/GCODE_EXPORT.PY ファイルの表示

@@ -0,0 +1,488 @@
1
+import bpy, os
2
+import numpy as np
3
+import mathutils
4
+from mathutils import Vector
5
+from math import pi
6
+from bpy.types import (
7
+        Operator,
8
+        Panel,
9
+        PropertyGroup,
10
+        )
11
+from bpy.props import (
12
+        BoolProperty,
13
+        EnumProperty,
14
+        FloatProperty,
15
+        IntProperty,
16
+        StringProperty,
17
+        PointerProperty
18
+        )
19
+from .utils import *
20
+
21
+def change_speed_mode(self, context):
22
+    props = context.scene.tissue_gcode
23
+    if props.previous_speed_mode != props.speed_mode:
24
+        if props.speed_mode == 'SPEED':
25
+            props.speed = props.feed/60
26
+            props.speed_vertical = props.feed_vertical/60
27
+            props.speed_horizontal = props.feed_horizontal/60
28
+        else:
29
+            props.feed = props.speed*60
30
+            props.feed_vertical = props.speed_vertical*60
31
+            props.feed_horizontal = props.speed_horizontal*60
32
+    props.previous_speed_mode == props.speed_mode
33
+    return
34
+
35
+class tissue_gcode_prop(PropertyGroup):
36
+    last_e : FloatProperty(name="Pull", default=5.0, min=0, soft_max=10)
37
+    path_length : FloatProperty(name="Pull", default=5.0, min=0, soft_max=10)
38
+
39
+    folder : StringProperty(
40
+        name="File", default="", subtype='FILE_PATH',
41
+        description = 'Destination folder.\nIf missing, the file folder will be used'
42
+        )
43
+    pull : FloatProperty(
44
+        name="Pull", default=5.0, min=0, soft_max=10,
45
+        description='Pull material before lift'
46
+        )
47
+    push : FloatProperty(
48
+        name="Push", default=5.0, min=0, soft_max=10,
49
+        description='Push material before start extruding'
50
+        )
51
+    dz : FloatProperty(
52
+        name="dz", default=2.0, min=0, soft_max=20,
53
+        description='Z movement for lifting the nozzle before travel'
54
+        )
55
+    flow_mult : FloatProperty(
56
+        name="Flow Mult", default=1.0, min=0, soft_max=3,
57
+        description = 'Flow multiplier.\nUse a single value or a list of values for changing it during the printing path'
58
+        )
59
+    feed : IntProperty(
60
+        name="Feed Rate (F)", default=3600, min=0, soft_max=20000,
61
+        description='Printing speed'
62
+        )
63
+    feed_horizontal : IntProperty(
64
+        name="Feed Horizontal", default=7200, min=0, soft_max=20000,
65
+        description='Travel speed'
66
+        )
67
+    feed_vertical : IntProperty(
68
+        name="Feed Vertical", default=3600, min=0, soft_max=20000,
69
+        description='Lift movements speed'
70
+        )
71
+
72
+    speed : IntProperty(
73
+        name="Speed", default=60, min=0, soft_max=100,
74
+        description='Printing speed'
75
+        )
76
+    speed_horizontal : IntProperty(
77
+        name="Travel", default=120, min=0, soft_max=200,
78
+        description='Travel speed'
79
+        )
80
+    speed_vertical : IntProperty(
81
+        name="Z-Lift", default=60, min=0, soft_max=200,
82
+        description='Lift movements speed'
83
+        )
84
+
85
+    esteps : FloatProperty(
86
+        name="E Steps/Unit", default=5, min=0, soft_max=100)
87
+    start_code : StringProperty(
88
+        name="Start", default='', description = 'Text block for starting code'
89
+        )
90
+    end_code : StringProperty(
91
+        name="End", default='', description = 'Text block for ending code'
92
+        )
93
+    auto_sort_layers : BoolProperty(
94
+        name="Auto Sort Layers", default=True,
95
+        description = 'Sort layers according to the Z of the median point'
96
+        )
97
+    auto_sort_points : BoolProperty(
98
+        name="Auto Sort Points", default=False,
99
+        description = 'Shift layer points trying to automatically reduce needed travel movements'
100
+        )
101
+    close_all : BoolProperty(
102
+        name="Close Shapes", default=False,
103
+        description = 'Repeat the starting point at the end of the vertices list for each layer'
104
+        )
105
+    nozzle : FloatProperty(
106
+        name="Nozzle", default=0.4, min=0, soft_max=10,
107
+        description='Nozzle diameter'
108
+        )
109
+    layer_height : FloatProperty(
110
+        name="Layer Height", default=0.1, min=0, soft_max=10,
111
+        description = 'Average layer height, needed for a correct extrusion'
112
+        )
113
+    filament : FloatProperty(
114
+        name="Filament (\u03A6)", default=1.75, min=0, soft_max=120,
115
+        description='Filament (or material container) diameter'
116
+        )
117
+
118
+    gcode_mode : EnumProperty(items=[
119
+            ("CONT", "Continuous", ""),
120
+            ("RETR", "Retraction", "")
121
+        ], default='CONT', name="Mode",
122
+        description = 'If retraction is used, then each separated list of vertices\nwill be considered as a different layer'
123
+        )
124
+    speed_mode : EnumProperty(items=[
125
+            ("SPEED", "Speed (mm/s)", ""),
126
+            ("FEED", "Feed (mm/min)", "")
127
+        ], default='SPEED', name="Speed Mode",
128
+        description = 'Speed control mode',
129
+        update = change_speed_mode
130
+        )
131
+    previous_speed_mode : StringProperty(
132
+        name="previous_speed_mode", default='', description = ''
133
+        )
134
+    retraction_mode : EnumProperty(items=[
135
+            ("FIRMWARE", "Firmware", ""),
136
+            ("GCODE", "Gcode", "")
137
+        ], default='GCODE', name="Retraction Mode",
138
+        description = 'If firmware retraction is used, then the retraction parameters will be controlled by the printer'
139
+        )
140
+    animate : BoolProperty(
141
+        name="Animate", default=False,
142
+        description = 'Show print progression according to current frame'
143
+        )
144
+
145
+
146
+class TISSUE_PT_gcode_exporter(Panel):
147
+    bl_category = "Tissue Gcode"
148
+    bl_space_type = "VIEW_3D"
149
+    bl_region_type = "UI"
150
+    #bl_space_type = 'PROPERTIES'
151
+    #bl_region_type = 'WINDOW'
152
+    #bl_context = "data"
153
+    bl_label = "Tissue Gcode Export"
154
+    #bl_options = {'DEFAULT_CLOSED'}
155
+
156
+    @classmethod
157
+    def poll(cls, context):
158
+        try: return context.object.type in ('CURVE','MESH')
159
+        except: return False
160
+
161
+    def draw(self, context):
162
+        props = context.scene.tissue_gcode
163
+
164
+        #addon = context.user_preferences.addons.get(sverchok.__name__)
165
+        #over_sized_buttons = addon.preferences.over_sized_buttons
166
+        layout = self.layout
167
+        col = layout.column(align=True)
168
+        row = col.row()
169
+        row.prop(props, 'folder', toggle=True, text='')
170
+        col = layout.column(align=True)
171
+        row = col.row()
172
+        row.prop(props, 'gcode_mode', expand=True, toggle=True)
173
+        #col = layout.column(align=True)
174
+        col = layout.column(align=True)
175
+        col.label(text="Extrusion:", icon='MOD_FLUIDSIM')
176
+        #col.prop(self, 'esteps')
177
+        col.prop(props, 'filament')
178
+        col.prop(props, 'nozzle')
179
+        col.prop(props, 'layer_height')
180
+        col.separator()
181
+        col.label(text="Speed (Feed Rate F):", icon='DRIVER')
182
+        col.prop(props, 'speed_mode', text='')
183
+        speed_prefix = 'feed' if props.speed_mode == 'FEED' else 'speed'
184
+        col.prop(props, speed_prefix, text='Print')
185
+        if props.gcode_mode == 'RETR':
186
+            col.prop(props, speed_prefix + '_vertical', text='Z Lift')
187
+            col.prop(props, speed_prefix + '_horizontal', text='Travel')
188
+        col.separator()
189
+        if props.gcode_mode == 'RETR':
190
+            col = layout.column(align=True)
191
+            col.label(text="Retraction Mode:", icon='NOCURVE')
192
+            row = col.row()
193
+            row.prop(props, 'retraction_mode', expand=True, toggle=True)
194
+            if props.retraction_mode == 'GCODE':
195
+                col.separator()
196
+                col.label(text="Retraction:", icon='PREFERENCES')
197
+                col.prop(props, 'pull', text='Retraction')
198
+                col.prop(props, 'dz', text='Z Hop')
199
+                col.prop(props, 'push', text='Preload')
200
+                col.separator()
201
+            #col.label(text="Layers options:", icon='ALIGN_JUSTIFY')
202
+        col.separator()
203
+        col.prop(props, 'auto_sort_layers', text="Sort Layers (Z)")
204
+        col.prop(props, 'auto_sort_points', text="Sort Points (XY)")
205
+        #col.prop(props, 'close_all')
206
+        col.separator()
207
+        col.label(text='Custom Code:', icon='TEXT')
208
+        col.prop_search(props, 'start_code', bpy.data, 'texts')
209
+        col.prop_search(props, 'end_code', bpy.data, 'texts')
210
+        col.separator()
211
+        row = col.row(align=True)
212
+        row.scale_y = 2.0
213
+        row.operator('scene.tissue_gcode_export')
214
+        #col.separator()
215
+        #col.prop(props, 'animate', icon='TIME')
216
+
217
+
218
+class tissue_gcode_export(Operator):
219
+    bl_idname = "scene.tissue_gcode_export"
220
+    bl_label = "Export Gcode"
221
+    bl_description = ("Export selected curve object as Gcode file")
222
+    bl_options = {'REGISTER', 'UNDO'}
223
+
224
+    @classmethod
225
+    def poll(cls, context):
226
+        try:
227
+            return context.object.type in ('CURVE', 'MESH')
228
+        except:
229
+            return False
230
+
231
+    def execute(self, context):
232
+        scene = context.scene
233
+        props = scene.tissue_gcode
234
+        # manage data
235
+        if props.speed_mode == 'SPEED':
236
+            props.feed = props.speed*60
237
+            props.feed_vertical = props.speed_vertical*60
238
+            props.feed_horizontal = props.speed_horizontal*60
239
+        feed = props.feed
240
+        feed_v = props.feed_vertical
241
+        feed_h = props.feed_horizontal
242
+        layer = props.layer_height
243
+        flow_mult = props.flow_mult
244
+        #if context.object.type != 'CURVE':
245
+        #    self.report({'ERROR'}, 'Please select a Curve object')
246
+        #    return {'CANCELLED'}
247
+        ob = context.object
248
+        matr = ob.matrix_world
249
+        if ob.type == 'MESH':
250
+            dg = context.evaluated_depsgraph_get()
251
+            mesh = ob.evaluated_get(dg).data
252
+            edges = [list(e.vertices) for e in mesh.edges]
253
+            verts = [v.co for v in mesh.vertices]
254
+            ordered_verts = find_curves(edges, len(mesh.vertices))
255
+            ob = curve_from_pydata(verts, ordered_verts, name='__temp_curve__', merge_distance=0.1, set_active=False)
256
+
257
+        vertices = [[matr @ p.co.xyz for p in s.points] for s in ob.data.splines]
258
+        cyclic_u = [s.use_cyclic_u for s in ob.data.splines]
259
+
260
+        if ob.name == '__temp_curve__': bpy.data.objects.remove(ob)
261
+
262
+        if len(vertices) == 1: props.gcode_mode = 'CONT'
263
+        export = True
264
+
265
+        # open file
266
+        if(export):
267
+            if props.folder == '':
268
+                folder = '//' + os.path.splitext(bpy.path.basename(bpy.context.blend_data.filepath))[0]
269
+            else:
270
+                folder = props.folder
271
+            if '.gcode' not in folder: folder += '.gcode'
272
+            path = bpy.path.abspath(folder)
273
+            file = open(path, 'w')
274
+            try:
275
+                for line in bpy.data.texts[props.start_code].lines:
276
+                    file.write(line.body + '\n')
277
+            except:
278
+                pass
279
+
280
+        #if props.gcode_mode == 'RETR':
281
+
282
+        # sort layers (Z)
283
+        if props.auto_sort_layers:
284
+            sorted_verts = []
285
+            for curve in vertices:
286
+                # mean z
287
+                listz = [v[2] for v in curve]
288
+                meanz = np.mean(listz)
289
+                # store curve and meanz
290
+                sorted_verts.append((curve, meanz))
291
+            vertices = [data[0] for data in sorted(sorted_verts, key=lambda height: height[1])]
292
+
293
+        # sort vertices (XY)
294
+        if props.auto_sort_points:
295
+            # curves median point
296
+            median_points = [np.mean(verts,axis=0) for verts in vertices]
297
+
298
+            # chose starting point for each curve
299
+            for j, curve in enumerate(vertices):
300
+                # for closed curves finds the best starting point
301
+                if cyclic_u[j]:
302
+                    # create kd tree
303
+                    kd = mathutils.kdtree.KDTree(len(curve))
304
+                    for i, v in enumerate(curve):
305
+                        kd.insert(v, i)
306
+                    kd.balance()
307
+
308
+                    if props.gcode_mode == 'RETR':
309
+                        if j==0:
310
+                            # close to next two curves median point
311
+                            co_find = np.mean(median_points[j+1:j+3],axis=0)
312
+                        elif j < len(vertices)-1:
313
+                            co_find = np.mean([median_points[j-1],median_points[j+1]],axis=0)
314
+                        else:
315
+                            co_find = np.mean(median_points[j-2:j],axis=0)
316
+                        #flow_mult[j] = flow_mult[j][index:]+flow_mult[j][:index]
317
+                        #layer[j] = layer[j][index:]+layer[j][:index]
318
+                    else:
319
+                        if j==0:
320
+                            # close to next two curves median point
321
+                            co_find = np.mean(median_points[j+1:j+3],axis=0)
322
+                        else:
323
+                            co_find = vertices[j-1][-1]
324
+                    co, index, dist = kd.find(co_find)
325
+                    vertices[j] = vertices[j][index:]+vertices[j][:index+1]
326
+                else:
327
+                    if j > 0:
328
+                        p0 = curve[0]
329
+                        p1 = curve[-1]
330
+                        last = vertices[j-1][-1]
331
+                        d0 = (last-p0).length
332
+                        d1 = (last-p1).length
333
+                        if d1 < d0: vertices[j].reverse()
334
+
335
+
336
+
337
+            '''
338
+            #  close shapes
339
+            if props.close_all:
340
+                for i in range(len(vertices)):
341
+                    vertices[i].append(vertices[i][0])
342
+                    #flow_mult[i].append(flow_mult[i][0])
343
+                    #layer[i].append(layer[i][0])
344
+            '''
345
+        # calc bounding box
346
+        min_corner = np.min(vertices[0],axis=0)
347
+        max_corner = np.max(vertices[0],axis=0)
348
+        for i in range(1,len(vertices)):
349
+            eval_points = vertices[i] + [min_corner]
350
+            min_corner = np.min(eval_points,axis=0)
351
+            eval_points = vertices[i] + [max_corner]
352
+            max_corner = np.max(eval_points,axis=0)
353
+
354
+        # initialize variables
355
+        e = 0
356
+        last_vert = Vector((0,0,0))
357
+        maxz = 0
358
+        path_length = 0
359
+        travel_length = 0
360
+
361
+        printed_verts = []
362
+        printed_edges = []
363
+        travel_verts = []
364
+        travel_edges = []
365
+
366
+        # write movements
367
+        for i in range(len(vertices)):
368
+            curve = vertices[i]
369
+            first_id = len(printed_verts)
370
+            for j in range(len(curve)):
371
+                v = curve[j]
372
+                v_flow_mult = flow_mult#[i][j]
373
+                v_layer = layer#[i][j]
374
+
375
+                # record max z
376
+                maxz = np.max((maxz,v[2]))
377
+                #maxz = max(maxz,v[2])
378
+
379
+                # first point of the gcode
380
+                if i == j == 0:
381
+                    printed_verts.append(v)
382
+                    if(export):
383
+                        file.write('G92 E0 \n')
384
+                        params = v[:3] + (feed,)
385
+                        to_write = 'G1 X{0:.4f} Y{1:.4f} Z{2:.4f} F{3:.0f}\n'.format(*params)
386
+                        file.write(to_write)
387
+                else:
388
+                    # start after retraction
389
+                    if j == 0 and props.gcode_mode == 'RETR':
390
+                        if(export):
391
+                            params = v[:2] + (maxz+props.dz,) + (feed_h,)
392
+                            to_write = 'G1 X{0:.4f} Y{1:.4f} Z{2:.4f} F{3:.0f}\n'.format(*params)
393
+                            file.write(to_write)
394
+                            params = v[:3] + (feed_v,)
395
+                            to_write = 'G1 X{0:.4f} Y{1:.4f} Z{2:.4f} F{3:.0f}\n'.format(*params)
396
+                            file.write(to_write)
397
+                            to_write = 'G1 F{:.0f}\n'.format(feed)
398
+                            file.write(to_write)
399
+                            if props.retraction_mode == 'GCODE':
400
+                                e += props.push
401
+                                file.write( 'G1 E' + format(e, '.4f') + '\n')
402
+                            else:
403
+                                file.write('G11\n')
404
+                        printed_verts.append((v[0], v[1], maxz+props.dz))
405
+                        travel_edges.append((len(printed_verts)-1, len(printed_verts)-2))
406
+                        travel_length += (Vector(printed_verts[-1])-Vector(printed_verts[-2])).length
407
+                        printed_verts.append(v)
408
+                        travel_edges.append((len(printed_verts)-1, len(printed_verts)-2))
409
+                        travel_length += maxz+props.dz - v[2]
410
+                    # regular extrusion
411
+                    else:
412
+                        printed_verts.append(v)
413
+                        v1 = Vector(v)
414
+                        v0 = Vector(curve[j-1])
415
+                        dist = (v1-v0).length
416
+                        area = v_layer * props.nozzle + pi*(v_layer/2)**2 # rectangle + circle
417
+                        cylinder = pi*(props.filament/2)**2
418
+                        flow = area / cylinder * (0 if j == 0 else 1)
419
+                        e += dist * v_flow_mult * flow
420
+                        params = v[:3] + (e,)
421
+                        if(export):
422
+                            to_write = 'G1 X{0:.4f} Y{1:.4f} Z{2:.4f} E{3:.4f}\n'.format(*params)
423
+                            file.write(to_write)
424
+                        path_length += dist
425
+                        printed_edges.append([len(printed_verts)-1, len(printed_verts)-2])
426
+            if props.gcode_mode == 'RETR':
427
+                v0 = Vector(curve[-1])
428
+                if props.close_all and False:
429
+                    #printed_verts.append(v0)
430
+                    printed_edges.append([len(printed_verts)-1, first_id])
431
+
432
+                    v1 = Vector(curve[0])
433
+                    dist = (v0-v1).length
434
+                    area = v_layer * props.nozzle + pi*(v_layer/2)**2 # rectangle + circle
435
+                    cylinder = pi*(props.filament/2)**2
436
+                    flow = area / cylinder
437
+                    e += dist * v_flow_mult * flow
438
+                    params = v1[:3] + (e,)
439
+                    if(export):
440
+                        to_write = 'G1 X{0:.4f} Y{1:.4f} Z{2:.4f} E{3:.4f}\n'.format(*params)
441
+                        file.write(to_write)
442
+                    path_length += dist
443
+                    v0 = v1
444
+                if i < len(vertices)-1:
445
+                    if(export):
446
+                        if props.retraction_mode == 'GCODE':
447
+                            e -= props.pull
448
+                            file.write('G0 E' + format(e, '.4f') + '\n')
449
+                        else:
450
+                            file.write('G10\n')
451
+                        params = v0[:2] + (maxz+props.dz,) + (feed_v,)
452
+                        to_write = 'G1 X{0:.4f} Y{1:.4f} Z{2:.4f} F{3:.0f}\n'.format(*params)
453
+                        file.write(to_write)
454
+                    printed_verts.append(v0.to_tuple())
455
+                    printed_verts.append((v0.x, v0.y, maxz+props.dz))
456
+                    travel_edges.append((len(printed_verts)-1, len(printed_verts)-2))
457
+                    travel_length += maxz+props.dz - v0.z
458
+        if(export):
459
+            # end code
460
+            try:
461
+                for line in bpy.data.texts[props.end_code].lines:
462
+                    file.write(line.body + '\n')
463
+            except:
464
+                pass
465
+            file.close()
466
+            print("Saved gcode to " + path)
467
+        bb = list(min_corner) + list(max_corner)
468
+        info = 'Bounding Box:\n'
469
+        info += '\tmin\tX: {0:.1f}\tY: {1:.1f}\tZ: {2:.1f}\n'.format(*bb)
470
+        info += '\tmax\tX: {3:.1f}\tY: {4:.1f}\tZ: {5:.1f}\n'.format(*bb)
471
+        info += 'Extruded Filament: ' + format(e, '.2f') + '\n'
472
+        info += 'Extruded Volume: ' + format(e*pi*(props.filament/2)**2, '.2f') + '\n'
473
+        info += 'Printed Path Length: ' + format(path_length, '.2f') + '\n'
474
+        info += 'Travel Length: ' + format(travel_length, '.2f')
475
+        '''
476
+        # animate
477
+        if scene.animate:
478
+            scene = bpy.context.scene
479
+            try:
480
+                param = (scene.frame_current - scene.frame_start)/(scene.frame_end - scene.frame_start)
481
+            except:
482
+                param = 1
483
+            last_vert = max(int(param*len(printed_verts)),1)
484
+            printed_verts = printed_verts[:last_vert]
485
+            printed_edges = [e for e in printed_edges if e[0] < last_vert and e[1] < last_vert]
486
+            travel_edges = [e for e in travel_edges if e[0] < last_vert and e[1] < last_vert]
487
+        '''
488
+        return {'FINISHED'}

+ 477
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/LATTICE.PY ファイルの表示

@@ -0,0 +1,477 @@
1
+# ##### BEGIN GPL LICENSE BLOCK #####
2
+#
3
+#  This program is free software; you can redistribute it and/or
4
+#  modify it under the terms of the GNU General Public License
5
+#  as published by the Free Software Foundation; either version 2
6
+#  of the License, or (at your option) any later version.
7
+#
8
+#  This program is distributed in the hope that it will be useful,
9
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+#  GNU General Public License for more details.
12
+#
13
+#  You should have received a copy of the GNU General Public License
14
+#  along with this program; if not, write to the Free Software Foundation,
15
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
+#
17
+# ##### END GPL LICENSE BLOCK #####
18
+# --------------------------- LATTICE ALONG SURFACE -------------------------- #
19
+# -------------------------------- version 0.3 ------------------------------- #
20
+#                                                                              #
21
+# Automatically generate and assign a lattice that follows the active surface. #
22
+#                                                                              #
23
+#                        (c)   Alessandro Zomparelli                           #
24
+#                                    (2017)                                    #
25
+#                                                                              #
26
+# http://www.co-de-it.com/                                                     #
27
+#                                                                              #
28
+# ############################################################################ #
29
+
30
+import bpy
31
+import bmesh
32
+from bpy.types import Operator
33
+from bpy.props import (BoolProperty, StringProperty, FloatProperty)
34
+from mathutils import Vector
35
+
36
+from .utils import *
37
+
38
+
39
+def not_in(element, grid):
40
+    output = True
41
+    for loop in grid:
42
+        if element in loop:
43
+            output = False
44
+            break
45
+    return output
46
+
47
+
48
+def grid_from_mesh(mesh, swap_uv):
49
+    bm = bmesh.new()
50
+    bm.from_mesh(mesh)
51
+    verts_grid = []
52
+    edges_grid = []
53
+    faces_grid = []
54
+
55
+    running_grid = True
56
+    while running_grid:
57
+        verts_loop = []
58
+        edges_loop = []
59
+        faces_loop = []
60
+
61
+        # storing first point
62
+        verts_candidates = []
63
+        if len(faces_grid) == 0:
64
+            # for first loop check all vertices
65
+            verts_candidates = bm.verts
66
+        else:
67
+            # for other loops start form the vertices of the first face
68
+            # the last loop, skipping already used vertices
69
+            verts_candidates = [v for v in bm.faces[faces_grid[-1][0]].verts if not_in(v.index, verts_grid)]
70
+
71
+        # check for last loop
72
+        is_last = False
73
+        for vert in verts_candidates:
74
+            if len(vert.link_faces) == 1:   # check if corner vertex
75
+                vert.select = True
76
+                verts_loop.append(vert.index)
77
+                is_last = True
78
+                break
79
+
80
+        if not is_last:
81
+            for vert in verts_candidates:
82
+                new_link_faces = [f for f in vert.link_faces if not_in(f.index, faces_grid)]
83
+                if len(new_link_faces) < 2:  # check if corner vertex
84
+                    vert.select = True
85
+                    verts_loop.append(vert.index)
86
+                    break
87
+
88
+        running_loop = len(verts_loop) > 0
89
+
90
+        while running_loop:
91
+            bm.verts.ensure_lookup_table()
92
+            id = verts_loop[-1]
93
+            link_edges = bm.verts[id].link_edges
94
+            # storing second point
95
+            if len(verts_loop) == 1:            # only one vertex stored in the loop
96
+                if len(faces_grid) == 0:        # first loop #
97
+                    edge = link_edges[swap_uv]  # chose direction
98
+                    for vert in edge.verts:
99
+                        if vert.index != id:
100
+                            vert.select = True
101
+                            verts_loop.append(vert.index)                # new vertex
102
+                            edges_loop.append(edge.index)                # chosen edge
103
+                            faces_loop.append(edge.link_faces[0].index)  # only one face
104
+                            # edge.link_faces[0].select = True
105
+                else:  # other loops #
106
+                    # start from the edges of the first face of the last loop
107
+                    for edge in bm.faces[faces_grid[-1][0]].edges:
108
+                        # chose an edge starting from the first vertex that is not returning back
109
+                        if bm.verts[verts_loop[0]] in edge.verts and \
110
+                                bm.verts[verts_grid[-1][0]] not in edge.verts:
111
+                            for vert in edge.verts:
112
+                                if vert.index != id:
113
+                                    vert.select = True
114
+                                    verts_loop.append(vert.index)
115
+                            edges_loop.append(edge.index)
116
+
117
+                            for face in edge.link_faces:
118
+                                if not_in(face.index, faces_grid):
119
+                                    faces_loop.append(face.index)
120
+            # continuing the loop
121
+            else:
122
+                for edge in link_edges:
123
+                    for vert in edge.verts:
124
+                        store_data = False
125
+                        if not_in(vert.index, verts_grid) and vert.index not in verts_loop:
126
+                            if len(faces_loop) > 0:
127
+                                bm.faces.ensure_lookup_table()
128
+                                if vert not in bm.faces[faces_loop[-1]].verts:
129
+                                    store_data = True
130
+                            else:
131
+                                store_data = True
132
+                            if store_data:
133
+                                vert.select = True
134
+                                verts_loop.append(vert.index)
135
+                                edges_loop.append(edge.index)
136
+                                for face in edge.link_faces:
137
+                                    if not_in(face.index, faces_grid):
138
+                                        faces_loop.append(face.index)
139
+                                break
140
+            # ending condition
141
+            if verts_loop[-1] == id or verts_loop[-1] == verts_loop[0]:
142
+                running_loop = False
143
+
144
+        verts_grid.append(verts_loop)
145
+        edges_grid.append(edges_loop)
146
+        faces_grid.append(faces_loop)
147
+
148
+        if len(faces_loop) == 0:
149
+            running_grid = False
150
+
151
+    return verts_grid, edges_grid, faces_grid
152
+
153
+
154
+class lattice_along_surface(Operator):
155
+    bl_idname = "object.lattice_along_surface"
156
+    bl_label = "Lattice along Surface"
157
+    bl_description = ("Automatically add a Lattice modifier to the selected "
158
+                      "object, adapting it to the active one.\nThe active "
159
+                      "object must be a rectangular grid compatible with the "
160
+                      "Lattice's topology")
161
+    bl_options = {'REGISTER', 'UNDO'}
162
+
163
+    set_parent : BoolProperty(
164
+            name="Set Parent",
165
+            default=True,
166
+            description="Automatically set the Lattice as parent"
167
+            )
168
+    flipNormals : BoolProperty(
169
+            name="Flip Normals",
170
+            default=False,
171
+            description="Flip normals direction"
172
+            )
173
+    swapUV : BoolProperty(
174
+            name="Swap UV",
175
+            default=False,
176
+            description="Flip grid's U and V"
177
+            )
178
+    flipU : BoolProperty(
179
+            name="Flip U",
180
+            default=False,
181
+            description="Flip grid's U")
182
+
183
+    flipV : BoolProperty(
184
+            name="Flip V",
185
+            default=False,
186
+            description="Flip grid's V"
187
+            )
188
+    flipW : BoolProperty(
189
+            name="Flip W",
190
+            default=False,
191
+            description="Flip grid's W"
192
+            )
193
+    use_groups : BoolProperty(
194
+            name="Vertex Group",
195
+            default=False,
196
+            description="Use active Vertex Group for lattice's thickness"
197
+            )
198
+    high_quality_lattice : BoolProperty(
199
+            name="High quality",
200
+            default=True,
201
+            description="Increase the the subdivisions in normal direction for a "
202
+                        "more correct result"
203
+            )
204
+    hide_lattice : BoolProperty(
205
+            name="Hide Lattice",
206
+            default=True,
207
+            description="Automatically hide the Lattice object"
208
+            )
209
+    scale_x : FloatProperty(
210
+            name="Scale X",
211
+            default=1,
212
+            min=0.001,
213
+            max=1,
214
+            description="Object scale"
215
+            )
216
+    scale_y : FloatProperty(
217
+            name="Scale Y", default=1,
218
+            min=0.001,
219
+            max=1,
220
+            description="Object scale"
221
+            )
222
+    scale_z : FloatProperty(
223
+            name="Scale Z",
224
+            default=1,
225
+            min=0.001,
226
+            max=1,
227
+            description="Object scale"
228
+            )
229
+    thickness : FloatProperty(
230
+            name="Thickness",
231
+            default=1,
232
+            soft_min=0,
233
+            soft_max=5,
234
+            description="Lattice thickness"
235
+            )
236
+    displace : FloatProperty(
237
+            name="Displace",
238
+            default=0,
239
+            soft_min=-1,
240
+            soft_max=1,
241
+            description="Lattice displace"
242
+            )
243
+    grid_object = ""
244
+    source_object = ""
245
+
246
+    @classmethod
247
+    def poll(cls, context):
248
+        try: return bpy.context.object.mode == 'OBJECT'
249
+        except: return False
250
+
251
+    def draw(self, context):
252
+        layout = self.layout
253
+        col = layout.column(align=True)
254
+        col.label(text="Thickness:")
255
+        col.prop(
256
+            self, "thickness", text="Thickness", icon='NONE', expand=False,
257
+            slider=True, toggle=False, icon_only=False, event=False,
258
+            full_event=False, emboss=True, index=-1
259
+            )
260
+        col.prop(
261
+            self, "displace", text="Offset", icon='NONE', expand=False,
262
+            slider=True, toggle=False, icon_only=False, event=False,
263
+            full_event=False, emboss=True, index=-1
264
+            )
265
+        row = col.row()
266
+        row.prop(self, "use_groups")
267
+        col.separator()
268
+        col.label(text="Scale:")
269
+        col.prop(
270
+            self, "scale_x", text="U", icon='NONE', expand=False,
271
+            slider=True, toggle=False, icon_only=False, event=False,
272
+            full_event=False, emboss=True, index=-1
273
+            )
274
+        col.prop(
275
+            self, "scale_y", text="V", icon='NONE', expand=False,
276
+            slider=True, toggle=False, icon_only=False, event=False,
277
+            full_event=False, emboss=True, index=-1
278
+            )
279
+        col.separator()
280
+        col.label(text="Flip:")
281
+        row = col.row()
282
+        row.prop(self, "flipU", text="U")
283
+        row.prop(self, "flipV", text="V")
284
+        row.prop(self, "flipW", text="W")
285
+        col.prop(self, "swapUV")
286
+        col.prop(self, "flipNormals")
287
+        col.separator()
288
+        col.label(text="Lattice Options:")
289
+        col.prop(self, "high_quality_lattice")
290
+        col.prop(self, "hide_lattice")
291
+        col.prop(self, "set_parent")
292
+
293
+    def execute(self, context):
294
+        if self.source_object == self.grid_object == "" or True:
295
+            if len(bpy.context.selected_objects) != 2:
296
+                self.report({'ERROR'}, "Please, select two objects")
297
+                return {'CANCELLED'}
298
+            grid_obj = bpy.context.object
299
+            if grid_obj.type not in ('MESH', 'CURVE', 'SURFACE'):
300
+                self.report({'ERROR'}, "The surface object is not valid. Only Mesh,"
301
+                            "Curve and Surface objects are allowed.")
302
+                return {'CANCELLED'}
303
+            obj = None
304
+            for o in bpy.context.selected_objects:
305
+                if o.name != grid_obj.name and o.type in \
306
+                        ('MESH', 'CURVE', 'SURFACE', 'FONT'):
307
+                    obj = o
308
+                    o.select_set(False)
309
+                    break
310
+            try:
311
+                obj_dim = obj.dimensions
312
+                obj_me = simple_to_mesh(obj)#obj.to_mesh(bpy.context.depsgraph, apply_modifiers=True)
313
+            except:
314
+                self.report({'ERROR'}, "The object to deform is not valid. Only "
315
+                            "Mesh, Curve, Surface and Font objects are allowed.")
316
+                return {'CANCELLED'}
317
+            self.grid_object = grid_obj.name
318
+            self.source_object = obj.name
319
+        else:
320
+            grid_obj = bpy.data.objects[self.grid_object]
321
+            obj = bpy.data.objects[self.source_object]
322
+            obj_me = simple_to_mesh(obj)# obj.to_mesh(bpy.context.depsgraph, apply_modifiers=True)
323
+            for o in bpy.context.selected_objects: o.select_set(False)
324
+            grid_obj.select_set(True)
325
+            bpy.context.view_layer.objects.active = grid_obj
326
+
327
+        temp_grid_obj = grid_obj.copy()
328
+        temp_grid_obj.data = simple_to_mesh(grid_obj)
329
+        grid_mesh = temp_grid_obj.data
330
+        for v in grid_mesh.vertices:
331
+            v.co = grid_obj.matrix_world @ v.co
332
+        grid_mesh.calc_normals()
333
+
334
+        if len(grid_mesh.polygons) > 64 * 64:
335
+            bpy.data.objects.remove(temp_grid_obj)
336
+            bpy.context.view_layer.objects.active = obj
337
+            obj.select_set(True)
338
+            self.report({'ERROR'}, "Maximum resolution allowed for Lattice is 64")
339
+            return {'CANCELLED'}
340
+
341
+        # CREATING LATTICE
342
+        min = Vector((0, 0, 0))
343
+        max = Vector((0, 0, 0))
344
+        first = True
345
+        for v in obj_me.vertices:
346
+            v0 = v.co.copy()
347
+            vert = obj.matrix_world @ v0
348
+            if vert[0] < min[0] or first:
349
+                min[0] = vert[0]
350
+            if vert[1] < min[1] or first:
351
+                min[1] = vert[1]
352
+            if vert[2] < min[2] or first:
353
+                min[2] = vert[2]
354
+            if vert[0] > max[0] or first:
355
+                max[0] = vert[0]
356
+            if vert[1] > max[1] or first:
357
+                max[1] = vert[1]
358
+            if vert[2] > max[2] or first:
359
+                max[2] = vert[2]
360
+            first = False
361
+
362
+        bb = max - min
363
+        lattice_loc = (max + min) / 2
364
+        bpy.ops.object.add(type='LATTICE')
365
+        lattice = bpy.context.active_object
366
+        lattice.location = lattice_loc
367
+        lattice.scale = Vector((bb.x / self.scale_x, bb.y / self.scale_y,
368
+                                bb.z / self.scale_z))
369
+
370
+        if bb.x == 0:
371
+            lattice.scale.x = 1
372
+        if bb.y == 0:
373
+            lattice.scale.y = 1
374
+        if bb.z == 0:
375
+            lattice.scale.z = 1
376
+
377
+        bpy.context.view_layer.objects.active = obj
378
+        bpy.ops.object.modifier_add(type='LATTICE')
379
+        obj.modifiers[-1].object = lattice
380
+
381
+        # set as parent
382
+        if self.set_parent:
383
+            obj.select_set(True)
384
+            lattice.select_set(True)
385
+            bpy.context.view_layer.objects.active = lattice
386
+            bpy.ops.object.parent_set(type='LATTICE')
387
+
388
+        # reading grid structure
389
+        verts_grid, edges_grid, faces_grid = grid_from_mesh(
390
+                                                grid_mesh,
391
+                                                swap_uv=self.swapUV
392
+                                                )
393
+        nu = len(verts_grid)
394
+        nv = len(verts_grid[0])
395
+        nw = 2
396
+        scale_normal = self.thickness
397
+
398
+        try:
399
+            lattice.data.points_u = nu
400
+            lattice.data.points_v = nv
401
+            lattice.data.points_w = nw
402
+            for i in range(nu):
403
+                for j in range(nv):
404
+                    for w in range(nw):
405
+                        if self.use_groups:
406
+                            try:
407
+                                displace = temp_grid_obj.vertex_groups.active.weight(
408
+                                                    verts_grid[i][j]) * scale_normal * bb.z
409
+                            except:
410
+                                displace = 0#scale_normal * bb.z
411
+                        else:
412
+                            displace = scale_normal * bb.z
413
+                        target_point = (grid_mesh.vertices[verts_grid[i][j]].co +
414
+                                        grid_mesh.vertices[verts_grid[i][j]].normal *
415
+                                        (w + self.displace / 2 - 0.5) * displace) - lattice.location
416
+                        if self.flipW:
417
+                            w = 1 - w
418
+                        if self.flipU:
419
+                            i = nu - i - 1
420
+                        if self.flipV:
421
+                            j = nv - j - 1
422
+
423
+                        lattice.data.points[i + j * nu + w * nu * nv].co_deform.x = \
424
+                                target_point.x / bpy.data.objects[lattice.name].scale.x
425
+                        lattice.data.points[i + j * nu + w * nu * nv].co_deform.y = \
426
+                                target_point.y / bpy.data.objects[lattice.name].scale.y
427
+                        lattice.data.points[i + j * nu + w * nu * nv].co_deform.z = \
428
+                                target_point.z / bpy.data.objects[lattice.name].scale.z
429
+
430
+        except:
431
+            bpy.ops.object.mode_set(mode='OBJECT')
432
+            temp_grid_obj.select_set(True)
433
+            lattice.select_set(True)
434
+            obj.select_set(False)
435
+            bpy.ops.object.delete(use_global=False)
436
+            bpy.context.view_layer.objects.active = obj
437
+            obj.select_set(True)
438
+            bpy.ops.object.modifier_remove(modifier=obj.modifiers[-1].name)
439
+            if nu > 64 or nv > 64:
440
+                self.report({'ERROR'}, "Maximum resolution allowed for Lattice is 64")
441
+                return {'CANCELLED'}
442
+            else:
443
+                self.report({'ERROR'}, "The grid mesh is not correct")
444
+                return {'CANCELLED'}
445
+
446
+        bpy.ops.object.mode_set(mode='OBJECT')
447
+        #grid_obj.select_set(True)
448
+        #lattice.select_set(False)
449
+        obj.select_set(False)
450
+        #bpy.ops.object.delete(use_global=False)
451
+        bpy.context.view_layer.objects.active = lattice
452
+        lattice.select_set(True)
453
+
454
+        if self.high_quality_lattice:
455
+            bpy.context.object.data.points_w = 8
456
+        else:
457
+            bpy.context.object.data.use_outside = True
458
+
459
+        if self.hide_lattice:
460
+            bpy.ops.object.hide_view_set(unselected=False)
461
+
462
+        bpy.context.view_layer.objects.active = obj
463
+        obj.select_set(True)
464
+        lattice.select_set(False)
465
+
466
+        if self.flipNormals:
467
+            try:
468
+                bpy.ops.object.mode_set(mode='EDIT')
469
+                bpy.ops.mesh.select_all(action='SELECT')
470
+                bpy.ops.mesh.flip_normals()
471
+                bpy.ops.object.mode_set(mode='OBJECT')
472
+            except:
473
+                pass
474
+        bpy.data.meshes.remove(grid_mesh)
475
+        bpy.data.meshes.remove(obj_me)
476
+
477
+        return {'FINISHED'}

+ 54
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/NUMBA_FUNCTIONS.PY ファイルの表示

@@ -0,0 +1,54 @@
1
+# ##### BEGIN GPL LICENSE BLOCK #####
2
+#
3
+#  This program is free software; you can redistribute it and/or
4
+#  modify it under the terms of the GNU General Public License
5
+#  as published by the Free Software Foundation; either version 2
6
+#  of the License, or (at your option) any later version.
7
+#
8
+#  This program is distributed in the hope that it will be useful,
9
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+#  GNU General Public License for more details.
12
+#
13
+#  You should have received a copy of the GNU General Public License
14
+#  along with this program; if not, write to the Free Software Foundation,
15
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
+#
17
+# ##### END GPL LICENSE BLOCK #####
18
+
19
+import numpy as np
20
+try:
21
+    from numba import jit
22
+    print("Tissue: Numba module loaded succesfully")
23
+    @jit
24
+    def numba_reaction_diffusion(n_verts, n_edges, edge_verts, a, b, diff_a, diff_b, f, k, dt, time_steps):
25
+        arr = np.arange(n_edges)*2
26
+        id0 = edge_verts[arr]     # first vertex indices for each edge
27
+        id1 = edge_verts[arr+1]   # second vertex indices for each edge
28
+        for i in range(time_steps):
29
+            lap_a = np.zeros(n_verts)
30
+            lap_b = np.zeros(n_verts)
31
+            lap_a0 =  a[id1] -  a[id0]   # laplacian increment for first vertex of each edge
32
+            lap_b0 =  b[id1] -  b[id0]   # laplacian increment for first vertex of each edge
33
+
34
+            for i, j, la0, lb0 in zip(id0,id1,lap_a0,lap_b0):
35
+                lap_a[i] += la0
36
+                lap_b[i] += lb0
37
+                lap_a[j] -= la0
38
+                lap_b[j] -= lb0
39
+            ab2 = a*b**2
40
+            #a += eval("(diff_a*lap_a - ab2 + f*(1-a))*dt")
41
+            #b += eval("(diff_b*lap_b + ab2 - (k+f)*b)*dt")
42
+            a += (diff_a*lap_a - ab2 + f*(1-a))*dt
43
+            b += (diff_b*lap_b + ab2 - (k+f)*b)*dt
44
+        return a, b
45
+
46
+    @jit
47
+    def numba_lerp2(v00, v10, v01, v11, vx, vy):
48
+        co0 = v00 + (v10 - v00) * vx
49
+        co1 = v01 + (v11 - v01) * vx
50
+        co2 = co0 + (co1 - co0) * vy
51
+        return co2
52
+except:
53
+    print("Tissue: Numba not installed")
54
+    pass

+ 40
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/README.MD ファイルの表示

@@ -0,0 +1,40 @@
1
+# Tissue
2
+![cover](http://www.co-de-it.com/wordpress/wp-content/uploads/2015/07/tissue_graphics.jpg)
3
+Tissue - Blender's add-on for computational design by Co-de-iT
4
+http://www.co-de-it.com/wordpress/code/blender-tissue
5
+
6
+Tissue is already shipped with both Blender 2.79b and Blender 2.80. However both versions can be updated manually, for more updated features and more stability.
7
+
8
+### Blender 2.80
9
+
10
+Tissue v0.3.31 for Blender 2.80 (latest stable release): https://github.com/alessandro-zomparelli/tissue/releases/tag/v0-3-31
11
+
12
+Development branch (most updated version): https://github.com/alessandro-zomparelli/tissue/tree/b280-dev
13
+
14
+### Blender 2.79
15
+
16
+Tissue v0.3.4 for Blender 2.79b (latest stable release): https://github.com/alessandro-zomparelli/tissue/releases/tag/v0-3-4
17
+
18
+Development branch (most updated version): https://github.com/alessandro-zomparelli/tissue/tree/dev1
19
+
20
+
21
+### Installation:
22
+
23
+1. Start Blender. Open User Preferences, the addons tab
24
+2. Search for Tissue add-on and remove existing version
25
+3. Click "install from file" and point Blender at the downloaded zip ("Install..." for Blender 2.80)
26
+4. Activate Tissue add-on from user preferences
27
+5. Save user preferences if you want to have it on at startup. (This could be not necessary for Blender 2.80 if "Auto-Save Preferences" id on)
28
+
29
+### Documentation
30
+
31
+Tissue documentation for Blender 2.80: https://github.com/alessandro-zomparelli/tissue/wiki
32
+
33
+
34
+### Contribute
35
+Please help me keeping Tissue stable and updated, report any issue here: https://github.com/alessandro-zomparelli/tissue/issues
36
+
37
+Tissue is free and open-source. I really think that this is the power of Blender and I wanted to give my small contribution to it.
38
+If you like my work and you want to help to continue the development of Tissue, please consider to make a small donation. Any small contribution is really appreciated, thanks! :-D
39
+
40
+Alessandro

+ 4280
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/TESSELLATE_NUMPY.PY
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 462
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/UTILS.PY ファイルの表示

@@ -0,0 +1,462 @@
1
+# ##### BEGIN GPL LICENSE BLOCK #####
2
+#
3
+#  This program is free software; you can redistribute it and/or
4
+#  modify it under the terms of the GNU General Public License
5
+#  as published by the Free Software Foundation; either version 2
6
+#  of the License, or (at your option) any later version.
7
+#
8
+#  This program is distributed in the hope that it will be useful,
9
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+#  GNU General Public License for more details.
12
+#
13
+#  You should have received a copy of the GNU General Public License
14
+#  along with this program; if not, write to the Free Software Foundation,
15
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
+#
17
+# ##### END GPL LICENSE BLOCK #####
18
+
19
+import bpy
20
+import threading
21
+import numpy as np
22
+import multiprocessing
23
+from multiprocessing import Process, Pool
24
+from mathutils import Vector
25
+try: from .numba_functions import numba_lerp2
26
+except: pass
27
+
28
+weight = []
29
+n_threads = multiprocessing.cpu_count()
30
+
31
+class ThreadVertexGroup(threading.Thread):
32
+    def __init__ ( self, id, vertex_group, n_verts):
33
+        self.id = id
34
+        self.vertex_group = vertex_group
35
+        self.n_verts = n_verts
36
+        threading.Thread.__init__ ( self )
37
+
38
+    def run (self):
39
+        global weight
40
+        global n_threads
41
+        verts = np.arange(int(self.n_verts/8))*8 + self.id
42
+        for v in verts:
43
+            try:
44
+                weight[v] = self.vertex_group.weight(v)
45
+            except:
46
+                pass
47
+
48
+def thread_read_weight(_weight, vertex_group):
49
+    global weight
50
+    global n_threads
51
+    print(n_threads)
52
+    weight = _weight
53
+    n_verts = len(weight)
54
+    threads = [ThreadVertexGroup(i, vertex_group, n_verts) for i in range(n_threads)]
55
+    for t in threads: t.start()
56
+    for t in threads: t.join()
57
+    return weight
58
+
59
+def process_read_weight(id, vertex_group, n_verts):
60
+    global weight
61
+    global n_threads
62
+    verts = np.arange(int(self.n_verts/8))*8 + self.id
63
+    for v in verts:
64
+        try:
65
+            weight[v] = self.vertex_group.weight(v)
66
+        except:
67
+            pass
68
+
69
+
70
+def read_weight(_weight, vertex_group):
71
+    global weight
72
+    global n_threads
73
+    print(n_threads)
74
+    weight = _weight
75
+    n_verts = len(weight)
76
+    n_cores = multiprocessing.cpu_count()
77
+    pool = Pool(processes=n_cores)
78
+    multiple_results = [pool.apply_async(process_read_weight, (i, vertex_group, n_verts)) for i in range(n_cores)]
79
+    #processes = [Process(target=process_read_weight, args=(i, vertex_group, n_verts)) for i in range(n_threads)]
80
+    #for t in processes: t.start()
81
+    #for t in processes: t.join()
82
+    return weight
83
+
84
+#Recursivly transverse layer_collection for a particular name
85
+def recurLayerCollection(layerColl, collName):
86
+    found = None
87
+    if (layerColl.name == collName):
88
+        return layerColl
89
+    for layer in layerColl.children:
90
+        found = recurLayerCollection(layer, collName)
91
+        if found:
92
+            return found
93
+
94
+def auto_layer_collection():
95
+    # automatically change active layer collection
96
+    layer = bpy.context.view_layer.active_layer_collection
97
+    layer_collection = bpy.context.view_layer.layer_collection
98
+    if layer.hide_viewport or layer.collection.hide_viewport:
99
+        collections = bpy.context.object.users_collection
100
+        for c in collections:
101
+            lc = recurLayerCollection(layer_collection, c.name)
102
+            if not c.hide_viewport and not lc.hide_viewport:
103
+                bpy.context.view_layer.active_layer_collection = lc
104
+
105
+def lerp(a, b, t):
106
+    return a + (b - a) * t
107
+
108
+def _lerp2(v1, v2, v3, v4, v):
109
+    v12 = v1.lerp(v2,v.x) # + (v2 - v1) * v.x
110
+    v34 = v3.lerp(v4,v.x) # + (v4 - v3) * v.x
111
+    return v12.lerp(v34, v.y)# + (v34 - v12) * v.y
112
+
113
+def lerp2(v1, v2, v3, v4, v):
114
+    v12 = v1 + (v2 - v1) * v.x
115
+    v34 = v3 + (v4 - v3) * v.x
116
+    return v12 + (v34 - v12) * v.y
117
+
118
+def lerp3(v1, v2, v3, v4, v):
119
+    loc = lerp2(v1.co, v2.co, v3.co, v4.co, v)
120
+    nor = lerp2(v1.normal, v2.normal, v3.normal, v4.normal, v)
121
+    nor.normalize()
122
+    return loc + nor * v.z
123
+
124
+def np_lerp2(v00, v10, v01, v11, vx, vy):
125
+    #try:
126
+    #    co2 = numba_lerp2(v00, v10, v01, v11, vx, vy)
127
+    #except:
128
+    co0 = v00 + (v10 - v00) * vx
129
+    co1 = v01 + (v11 - v01) * vx
130
+    co2 = co0 + (co1 - co0) * vy
131
+    return co2
132
+
133
+
134
+# Prevent Blender Crashes with handlers
135
+def set_animatable_fix_handler(self, context):
136
+    old_handlers = []
137
+    blender_handlers = bpy.app.handlers.render_init
138
+    for h in blender_handlers:
139
+        if "turn_off_animatable" in str(h):
140
+            old_handlers.append(h)
141
+    for h in old_handlers: blender_handlers.remove(h)
142
+    ################ blender_handlers.append(turn_off_animatable)
143
+    return
144
+
145
+def turn_off_animatable(scene):
146
+    for o in bpy.data.objects:
147
+        o.tissue_tessellate.bool_run = False
148
+        o.reaction_diffusion_settings.run = False
149
+        #except: pass
150
+    return
151
+
152
+### OBJECTS ###
153
+
154
+def convert_object_to_mesh(ob, apply_modifiers=True, preserve_status=True):
155
+    try: ob.name
156
+    except: return None
157
+    if ob.type != 'MESH':
158
+        if not apply_modifiers:
159
+            mod_visibility = [m.show_viewport for m in ob.modifiers]
160
+            for m in ob.modifiers: m.show_viewport = False
161
+        #ob.modifiers.update()
162
+        #dg = bpy.context.evaluated_depsgraph_get()
163
+        #ob_eval = ob.evaluated_get(dg)
164
+        #me = bpy.data.meshes.new_from_object(ob_eval, preserve_all_data_layers=True, depsgraph=dg)
165
+        me = simple_to_mesh(ob)
166
+        new_ob = bpy.data.objects.new(ob.data.name, me)
167
+        new_ob.location, new_ob.matrix_world = ob.location, ob.matrix_world
168
+        if not apply_modifiers:
169
+            for m,vis in zip(ob.modifiers,mod_visibility): m.show_viewport = vis
170
+    else:
171
+        if apply_modifiers:
172
+            new_ob = ob.copy()
173
+            new_me = simple_to_mesh(ob)
174
+            new_ob.modifiers.clear()
175
+            new_ob.data = new_me
176
+        else:
177
+            new_ob = ob.copy()
178
+            new_ob.data = ob.data.copy()
179
+            new_ob.modifiers.clear()
180
+    bpy.context.collection.objects.link(new_ob)
181
+    if preserve_status:
182
+        new_ob.select_set(False)
183
+    else:
184
+        for o in bpy.context.view_layer.objects: o.select_set(False)
185
+        new_ob.select_set(True)
186
+        bpy.context.view_layer.objects.active = new_ob
187
+    return new_ob
188
+
189
+def simple_to_mesh(ob):
190
+    dg = bpy.context.evaluated_depsgraph_get()
191
+    ob_eval = ob.evaluated_get(dg)
192
+    me = bpy.data.meshes.new_from_object(ob_eval, preserve_all_data_layers=True, depsgraph=dg)
193
+    me.calc_normals()
194
+    return me
195
+
196
+def join_objects(objects, link_to_scene=True, make_active=False):
197
+    C = bpy.context
198
+    bm = bmesh.new()
199
+
200
+    materials = {}
201
+    faces_materials = []
202
+    dg = C.evaluated_depsgraph_get()
203
+    for o in objects:
204
+        bm.from_object(o, dg)
205
+        # add object's material to the dictionary
206
+        for m in o.data.materials:
207
+            if m not in materials: materials[m] = len(materials)
208
+        for f in o.data.polygons:
209
+            index = f.material_index
210
+            mat = o.material_slots[index].material
211
+            new_index = materials[mat]
212
+            faces_materials.append(new_index)
213
+    bm.verts.ensure_lookup_table()
214
+    bm.edges.ensure_lookup_table()
215
+    bm.faces.ensure_lookup_table()
216
+    # assign new indexes
217
+    for index, f in zip(faces_materials, bm.faces): f.material_index = index
218
+    # create object
219
+    me = bpy.data.meshes.new('joined')
220
+    bm.to_mesh(me)
221
+    me.update()
222
+    ob = bpy.data.objects.new('joined', me)
223
+    if link_to_scene: C.collection.objects.link(ob)
224
+    # make active
225
+    if make_active:
226
+        for o in C.view_layer.objects: o.select_set(False)
227
+        ob.select_set(True)
228
+        C.view_layer.objects.active = ob
229
+    # add materials
230
+    for m in materials.keys(): ob.data.materials.append(m)
231
+    return ob
232
+
233
+### MESH FUNCTIONS
234
+
235
+def get_vertices_numpy(mesh):
236
+    n_verts = len(mesh.vertices)
237
+    verts = [0]*n_verts*3
238
+    mesh.vertices.foreach_get('co', verts)
239
+    verts = np.array(verts).reshape((n_verts,3))
240
+    return verts
241
+
242
+def get_vertices_and_normals_numpy(mesh):
243
+    n_verts = len(mesh.vertices)
244
+    verts = [0]*n_verts*3
245
+    normals = [0]*n_verts*3
246
+    mesh.vertices.foreach_get('co', verts)
247
+    mesh.vertices.foreach_get('normal', normals)
248
+    verts = np.array(verts).reshape((n_verts,3))
249
+    normals = np.array(normals).reshape((n_verts,3))
250
+    return verts, normals
251
+
252
+def get_edges_numpy(mesh):
253
+    n_edges = len(mesh.edges)
254
+    edges = [0]*n_edges*2
255
+    mesh.edges.foreach_get('vertices', edges)
256
+    edges = np.array(edges).reshape((n_edges,2)).astype('int')
257
+    return edges
258
+
259
+def get_edges_id_numpy(mesh):
260
+    n_edges = len(mesh.edges)
261
+    edges = [0]*n_edges*2
262
+    mesh.edges.foreach_get('vertices', edges)
263
+    edges = np.array(edges).reshape((n_edges,2))
264
+    indexes = np.arange(n_edges).reshape((n_edges,1))
265
+    edges = np.concatenate((edges,indexes), axis=1)
266
+    return edges
267
+
268
+def get_vertices(mesh):
269
+    n_verts = len(mesh.vertices)
270
+    verts = [0]*n_verts*3
271
+    mesh.vertices.foreach_get('co', verts)
272
+    verts = np.array(verts).reshape((n_verts,3))
273
+    verts = [Vector(v) for v in verts]
274
+    return verts
275
+
276
+def get_faces(mesh):
277
+    faces = [[v for v in f.vertices] for f in mesh.polygons]
278
+    return faces
279
+
280
+def get_faces_numpy(mesh):
281
+    faces = [[v for v in f.vertices] for f in mesh.polygons]
282
+    return np.array(faces)
283
+
284
+def get_faces_edges_numpy(mesh):
285
+    faces = [v.edge_keys for f in mesh.polygons]
286
+    return np.array(faces)
287
+
288
+#try:
289
+#from numba import jit, njit
290
+#from numba.typed import List
291
+'''
292
+@jit
293
+def find_curves(edges, n_verts):
294
+    #verts_dict = {key:[] for key in range(n_verts)}
295
+    verts_dict = {}
296
+    for key in range(n_verts): verts_dict[key] = []
297
+    for e in edges:
298
+        verts_dict[e[0]].append(e[1])
299
+        verts_dict[e[1]].append(e[0])
300
+    curves = []#List()
301
+    loop1 = True
302
+    while loop1:
303
+        if len(verts_dict) == 0:
304
+            loop1 = False
305
+            continue
306
+        # next starting point
307
+        v = list(verts_dict.keys())[0]
308
+        # neighbors
309
+        v01 = verts_dict[v]
310
+        if len(v01) == 0:
311
+            verts_dict.pop(v)
312
+            continue
313
+        curve = []#List()
314
+        curve.append(v)         # add starting point
315
+        curve.append(v01[0])    # add neighbors
316
+        verts_dict.pop(v)
317
+        loop2 = True
318
+        while loop2:
319
+            last_point = curve[-1]
320
+            #if last_point not in verts_dict: break
321
+            v01 = verts_dict[last_point]
322
+            # curve end
323
+            if len(v01) == 1:
324
+                verts_dict.pop(last_point)
325
+                loop2 = False
326
+                continue
327
+            if v01[0] == curve[-2]:
328
+                curve.append(v01[1])
329
+                verts_dict.pop(last_point)
330
+            elif v01[1] == curve[-2]:
331
+                curve.append(v01[0])
332
+                verts_dict.pop(last_point)
333
+            else:
334
+                loop2 = False
335
+                continue
336
+            if curve[0] == curve[-1]:
337
+                loop2 = False
338
+                continue
339
+        curves.append(curve)
340
+    return curves
341
+'''
342
+def find_curves(edges, n_verts):
343
+    verts_dict = {key:[] for key in range(n_verts)}
344
+    for e in edges:
345
+        verts_dict[e[0]].append(e[1])
346
+        verts_dict[e[1]].append(e[0])
347
+    curves = []
348
+    while True:
349
+        if len(verts_dict) == 0: break
350
+        # next starting point
351
+        v = list(verts_dict.keys())[0]
352
+        # neighbors
353
+        v01 = verts_dict[v]
354
+        if len(v01) == 0:
355
+            verts_dict.pop(v)
356
+            continue
357
+        curve = []
358
+        if len(v01) > 1: curve.append(v01[1])    # add neighbors
359
+        curve.append(v)         # add starting point
360
+        curve.append(v01[0])    # add neighbors
361
+        verts_dict.pop(v)
362
+        # start building curve
363
+        while True:
364
+            #last_point = curve[-1]
365
+            #if last_point not in verts_dict: break
366
+
367
+            # try to change direction if needed
368
+            if curve[-1] in verts_dict: pass
369
+            elif curve[0] in verts_dict: curve.reverse()
370
+            else: break
371
+
372
+            # neighbors points
373
+            last_point = curve[-1]
374
+            v01 = verts_dict[last_point]
375
+
376
+            # curve end
377
+            if len(v01) == 1:
378
+                verts_dict.pop(last_point)
379
+                if curve[0] in verts_dict: continue
380
+                else: break
381
+
382
+            # chose next point
383
+            new_point = None
384
+            if v01[0] == curve[-2]: new_point = v01[1]
385
+            elif v01[1] == curve[-2]: new_point = v01[0]
386
+            #else: break
387
+
388
+            #if new_point != curve[1]:
389
+            curve.append(new_point)
390
+            verts_dict.pop(last_point)
391
+            if curve[0] == curve[-1]:
392
+                verts_dict.pop(new_point)
393
+                break
394
+        curves.append(curve)
395
+    return curves
396
+
397
+def curve_from_points(points, name='Curve'):
398
+    curve = bpy.data.curves.new(name,'CURVE')
399
+    for c in points:
400
+        s = curve.splines.new('POLY')
401
+        s.points.add(len(c))
402
+        for i,p in enumerate(c): s.points[i].co = p.xyz + [1]
403
+    ob_curve = bpy.data.objects.new(name,curve)
404
+    return ob_curve
405
+
406
+def curve_from_pydata(points, indexes, name='Curve', skip_open=False, merge_distance=1, set_active=True):
407
+    curve = bpy.data.curves.new(name,'CURVE')
408
+    curve.dimensions = '3D'
409
+    for c in indexes:
410
+        # cleanup
411
+        pts = np.array([points[i] for i in c])
412
+        if merge_distance > 0:
413
+            pts1 = np.roll(pts,1,axis=0)
414
+            dist = np.linalg.norm(pts1-pts, axis=1)
415
+            count = 0
416
+            n = len(dist)
417
+            mask = np.ones(n).astype('bool')
418
+            for i in range(n):
419
+                count += dist[i]
420
+                if count > merge_distance: count = 0
421
+                else: mask[i] = False
422
+            pts = pts[mask]
423
+
424
+        bool_cyclic = c[0] == c[-1]
425
+        if skip_open and not bool_cyclic: continue
426
+        s = curve.splines.new('POLY')
427
+        n_pts = len(pts)
428
+        s.points.add(n_pts-1)
429
+        w = np.ones(n_pts).reshape((n_pts,1))
430
+        co = np.concatenate((pts,w),axis=1).reshape((n_pts*4))
431
+        s.points.foreach_set('co',co)
432
+        s.use_cyclic_u = bool_cyclic
433
+    ob_curve = bpy.data.objects.new(name,curve)
434
+    bpy.context.collection.objects.link(ob_curve)
435
+    if set_active:
436
+        bpy.context.view_layer.objects.active = ob_curve
437
+    return ob_curve
438
+
439
+def curve_from_vertices(indexes, verts, name='Curve'):
440
+    curve = bpy.data.curves.new(name,'CURVE')
441
+    for c in indexes:
442
+        s = curve.splines.new('POLY')
443
+        s.points.add(len(c))
444
+        for i,p in enumerate(c): s.points[i].co = verts[p].co.xyz + [1]
445
+    ob_curve = bpy.data.objects.new(name,curve)
446
+    return ob_curve
447
+
448
+### WEIGHT FUNCTIONS ###
449
+
450
+def get_weight(vertex_group, n_verts):
451
+    weight = [0]*n_verts
452
+    for i in range(n_verts):
453
+        try: weight[i] = vertex_group.weight(i)
454
+        except: pass
455
+    return weight
456
+
457
+def get_weight_numpy(vertex_group, n_verts):
458
+    weight = [0]*n_verts
459
+    for i in range(n_verts):
460
+        try: weight[i] = vertex_group.weight(i)
461
+        except: pass
462
+    return np.array(weight)

+ 178
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/UV_TO_MESH.PY ファイルの表示

@@ -0,0 +1,178 @@
1
+# ##### BEGIN GPL LICENSE BLOCK #####
2
+#
3
+#  This program is free software; you can redistribute it and/or
4
+#  modify it under the terms of the GNU General Public License
5
+#  as published by the Free Software Foundation; either version 2
6
+#  of the License, or (at your option) any later version.
7
+#
8
+#  This program is distributed in the hope that it will be useful,
9
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+#  GNU General Public License for more details.
12
+#
13
+#  You should have received a copy of the GNU General Public License
14
+#  along with this program; if not, write to the Free Software Foundation,
15
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
+#
17
+# ##### END GPL LICENSE BLOCK #####
18
+
19
+# --------------------------------- UV to MESH ------------------------------- #
20
+# -------------------------------- version 0.1.1 ----------------------------- #
21
+#                                                                              #
22
+# Create a new Mesh based on active UV                                         #
23
+#                                                                              #
24
+#                        (c)   Alessandro Zomparelli                           #
25
+#                                    (2017)                                    #
26
+#                                                                              #
27
+# http://www.co-de-it.com/                                                     #
28
+#                                                                              #
29
+# ############################################################################ #
30
+
31
+import bpy
32
+import math
33
+from bpy.types import Operator
34
+from bpy.props import BoolProperty
35
+from mathutils import Vector
36
+from .utils import *
37
+
38
+
39
+class uv_to_mesh(Operator):
40
+    bl_idname = "object.uv_to_mesh"
41
+    bl_label = "UV to Mesh"
42
+    bl_description = ("Create a new Mesh based on active UV")
43
+    bl_options = {'REGISTER', 'UNDO'}
44
+
45
+    apply_modifiers : BoolProperty(
46
+            name="Apply Modifiers",
47
+            default=True,
48
+            description="Apply object's modifiers"
49
+            )
50
+    vertex_groups : BoolProperty(
51
+            name="Keep Vertex Groups",
52
+            default=True,
53
+            description="Transfer all the Vertex Groups"
54
+            )
55
+    materials : BoolProperty(
56
+            name="Keep Materials",
57
+            default=True,
58
+            description="Transfer all the Materials"
59
+            )
60
+    auto_scale : BoolProperty(
61
+            name="Resize",
62
+            default=True,
63
+            description="Scale the new object in order to preserve the average surface area"
64
+            )
65
+
66
+    def execute(self, context):
67
+        bpy.ops.object.mode_set(mode='OBJECT')
68
+        ob0 = bpy.context.object
69
+        for o in bpy.context.view_layer.objects: o.select_set(False)
70
+        ob0.select_set(True)
71
+
72
+        #if self.apply_modifiers:
73
+        #    bpy.ops.object.duplicate_move()
74
+        #    bpy.ops.object.convert(target='MESH')
75
+
76
+#        me0 = ob0.to_mesh(bpy.context.depsgraph, apply_modifiers=self.apply_modifiers)
77
+        #if self.apply_modifiers: me0 = simple_to_mesh(ob0)
78
+        #else: me0 = ob0.data.copy()
79
+        name0 = ob0.name
80
+        ob0 = convert_object_to_mesh(ob0, apply_modifiers=self.apply_modifiers, preserve_status=False)
81
+        me0 = ob0.data
82
+        area = 0
83
+
84
+        verts = []
85
+        faces = []
86
+        face_materials = []
87
+        for face in me0.polygons:
88
+            area += face.area
89
+            uv_face = []
90
+            store = False
91
+            try:
92
+                for loop in face.loop_indices:
93
+                    uv = me0.uv_layers.active.data[loop].uv
94
+                    if uv.x != 0 and uv.y != 0:
95
+                        store = True
96
+                    new_vert = Vector((uv.x, uv.y, 0))
97
+                    verts.append(new_vert)
98
+                    uv_face.append(loop)
99
+                if store:
100
+                    faces.append(uv_face)
101
+                    face_materials.append(face.material_index)
102
+            except:
103
+                self.report({'ERROR'}, "Missing UV Map")
104
+
105
+                return {'CANCELLED'}
106
+
107
+        name = name0 + '_UV'
108
+        # Create mesh and object
109
+        me = bpy.data.meshes.new(name + 'Mesh')
110
+        ob = bpy.data.objects.new(name, me)
111
+
112
+        # Link object to scene and make active
113
+        scn = bpy.context.scene
114
+        bpy.context.collection.objects.link(ob)
115
+        bpy.context.view_layer.objects.active = ob
116
+        ob.select_set(True)
117
+
118
+        # Create mesh from given verts, faces.
119
+        me.from_pydata(verts, [], faces)
120
+        # Update mesh with new data
121
+        me.update()
122
+        if self.auto_scale:
123
+            new_area = 0
124
+            for p in me.polygons:
125
+                new_area += p.area
126
+            if new_area == 0:
127
+                self.report({'ERROR'}, "Impossible to generate mesh from UV")
128
+                bpy.data.objects.remove(ob0)
129
+
130
+                return {'CANCELLED'}
131
+
132
+        # VERTEX GROUPS
133
+        if self.vertex_groups:
134
+            for group in ob0.vertex_groups:
135
+                index = group.index
136
+                ob.vertex_groups.new(name=group.name)
137
+                for p in me0.polygons:
138
+                    for vert, loop in zip(p.vertices, p.loop_indices):
139
+                        try:
140
+                            ob.vertex_groups[index].add([loop], group.weight(vert), 'REPLACE')
141
+                        except:
142
+                            pass
143
+
144
+        ob0.select_set(False)
145
+        if self.auto_scale:
146
+            scaleFactor = math.pow(area / new_area, 1 / 2)
147
+            ob.scale = Vector((scaleFactor, scaleFactor, scaleFactor))
148
+
149
+        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
150
+        bpy.ops.mesh.remove_doubles(threshold=1e-06)
151
+        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
152
+        bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
153
+
154
+        # MATERIALS
155
+        if self.materials:
156
+            try:
157
+                # assign old material
158
+                uv_materials = [slot.material for slot in ob0.material_slots]
159
+                for i in range(len(uv_materials)):
160
+                    bpy.ops.object.material_slot_add()
161
+                    bpy.context.object.material_slots[i].material = uv_materials[i]
162
+                for i in range(len(ob.data.polygons)):
163
+                    ob.data.polygons[i].material_index = face_materials[i]
164
+            except:
165
+                pass
166
+        '''
167
+        if self.apply_modifiers:
168
+            bpy.ops.object.mode_set(mode='OBJECT')
169
+            ob.select_set(False)
170
+            ob0.select_set(True)
171
+            bpy.ops.object.delete(use_global=False)
172
+            ob.select_set(True)
173
+            bpy.context.view_layer.objects.active = ob
174
+        '''
175
+
176
+        bpy.data.objects.remove(ob0)
177
+        bpy.data.meshes.remove(me0)
178
+        return {'FINISHED'}

+ 151
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__INIT__.PY ファイルの表示

@@ -0,0 +1,151 @@
1
+# ##### BEGIN GPL LICENSE BLOCK #####
2
+#
3
+#  This program is free software; you can redistribute it and/or
4
+#  modify it under the terms of the GNU General Public License
5
+#  as published by the Free Software Foundation; either version 2
6
+#  of the License, or (at your option) any later version.
7
+#
8
+#  This program is distributed in the hope that it will be useful,
9
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+#  GNU General Public License for more details.
12
+#
13
+#  You should have received a copy of the GNU General Public License
14
+#  along with this program; if not, write to the Free Software Foundation,
15
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
+#
17
+# ##### END GPL LICENSE BLOCK #####
18
+
19
+# --------------------------------- TISSUE ----------------------------------- #
20
+# ------------------------------- version 0.3 -------------------------------- #
21
+#                                                                              #
22
+# Creates duplicates of selected mesh to active morphing the shape according   #
23
+# to target faces.                                                             #
24
+#                                                                              #
25
+#                            Alessandro Zomparelli                             #
26
+#                                   (2017)                                     #
27
+#                                                                              #
28
+# http://www.co-de-it.com/                                                     #
29
+# http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Mesh/Tissue      #
30
+#                                                                              #
31
+# ############################################################################ #
32
+
33
+bl_info = {
34
+    "name": "Tissue",
35
+    "author": "Alessandro Zomparelli (Co-de-iT)",
36
+    "version": (0, 3, 34),
37
+    "blender": (2, 80, 0),
38
+    "location": "",
39
+    "description": "Tools for Computational Design",
40
+    "warning": "",
41
+    "wiki_url": "https://github.com/alessandro-zomparelli/tissue/wiki",
42
+    "tracker_url": "https://github.com/alessandro-zomparelli/tissue/issues",
43
+    "category": "Mesh"}
44
+
45
+
46
+if "bpy" in locals():
47
+    import importlib
48
+    importlib.reload(tessellate_numpy)
49
+    importlib.reload(colors_groups_exchanger)
50
+    importlib.reload(dual_mesh)
51
+    importlib.reload(lattice)
52
+    importlib.reload(uv_to_mesh)
53
+    importlib.reload(utils)
54
+    importlib.reload(gcode_export)
55
+
56
+else:
57
+    from . import tessellate_numpy
58
+    from . import colors_groups_exchanger
59
+    from . import dual_mesh
60
+    from . import lattice
61
+    from . import uv_to_mesh
62
+    from . import utils
63
+    from . import gcode_export
64
+
65
+import bpy
66
+from bpy.props import PointerProperty, CollectionProperty, BoolProperty
67
+
68
+classes = (
69
+    tessellate_numpy.tissue_tessellate_prop,
70
+    tessellate_numpy.tissue_tessellate,
71
+    tessellate_numpy.tissue_update_tessellate,
72
+    tessellate_numpy.tissue_refresh_tessellate,
73
+    tessellate_numpy.TISSUE_PT_tessellate,
74
+    tessellate_numpy.tissue_rotate_face_left,
75
+    tessellate_numpy.tissue_rotate_face_right,
76
+    tessellate_numpy.TISSUE_PT_tessellate_object,
77
+    tessellate_numpy.TISSUE_PT_tessellate_frame,
78
+    tessellate_numpy.TISSUE_PT_tessellate_thickness,
79
+    tessellate_numpy.TISSUE_PT_tessellate_coordinates,
80
+    tessellate_numpy.TISSUE_PT_tessellate_rotation,
81
+    tessellate_numpy.TISSUE_PT_tessellate_options,
82
+    tessellate_numpy.TISSUE_PT_tessellate_selective,
83
+    tessellate_numpy.TISSUE_PT_tessellate_morphing,
84
+    tessellate_numpy.TISSUE_PT_tessellate_iterations,
85
+
86
+    colors_groups_exchanger.face_area_to_vertex_groups,
87
+    colors_groups_exchanger.vertex_colors_to_vertex_groups,
88
+    colors_groups_exchanger.vertex_group_to_vertex_colors,
89
+    colors_groups_exchanger.TISSUE_PT_weight,
90
+    colors_groups_exchanger.TISSUE_PT_color,
91
+    colors_groups_exchanger.weight_contour_curves,
92
+    colors_groups_exchanger.tissue_weight_contour_curves_pattern,
93
+    colors_groups_exchanger.weight_contour_mask,
94
+    colors_groups_exchanger.weight_contour_displace,
95
+    colors_groups_exchanger.harmonic_weight,
96
+    colors_groups_exchanger.edges_deformation,
97
+    colors_groups_exchanger.edges_bending,
98
+    colors_groups_exchanger.weight_laplacian,
99
+    colors_groups_exchanger.reaction_diffusion,
100
+    colors_groups_exchanger.start_reaction_diffusion,
101
+    colors_groups_exchanger.TISSUE_PT_reaction_diffusion,
102
+    colors_groups_exchanger.reset_reaction_diffusion_weight,
103
+    colors_groups_exchanger.formula_prop,
104
+    colors_groups_exchanger.reaction_diffusion_prop,
105
+    colors_groups_exchanger.weight_formula,
106
+    colors_groups_exchanger.curvature_to_vertex_groups,
107
+    colors_groups_exchanger.weight_formula_wiki,
108
+    colors_groups_exchanger.tissue_weight_distance,
109
+
110
+    dual_mesh.dual_mesh,
111
+    dual_mesh.dual_mesh_tessellated,
112
+
113
+    lattice.lattice_along_surface,
114
+
115
+    uv_to_mesh.uv_to_mesh,
116
+    gcode_export.TISSUE_PT_gcode_exporter,
117
+    gcode_export.tissue_gcode_prop,
118
+    gcode_export.tissue_gcode_export
119
+)
120
+
121
+def register():
122
+    from bpy.utils import register_class
123
+    for cls in classes:
124
+        bpy.utils.register_class(cls)
125
+    #bpy.utils.register_module(__name__)
126
+    bpy.types.Object.tissue_tessellate = PointerProperty(
127
+                                            type=tessellate_numpy.tissue_tessellate_prop
128
+                                            )
129
+    bpy.types.Scene.tissue_gcode = PointerProperty(
130
+                                            type=gcode_export.tissue_gcode_prop
131
+                                            )
132
+    bpy.types.Object.formula_settings = CollectionProperty(
133
+                                            type=colors_groups_exchanger.formula_prop
134
+                                            )
135
+    bpy.types.Object.reaction_diffusion_settings = PointerProperty(
136
+                        type=colors_groups_exchanger.reaction_diffusion_prop
137
+                        )
138
+    # colors_groups_exchanger
139
+    bpy.app.handlers.frame_change_post.append(colors_groups_exchanger.reaction_diffusion_def)
140
+    #bpy.app.handlers.frame_change_post.append(tessellate_numpy.anim_tessellate)
141
+
142
+def unregister():
143
+    from bpy.utils import unregister_class
144
+    for cls in classes:
145
+        bpy.utils.unregister_class(cls)
146
+
147
+    del bpy.types.Object.tissue_tessellate
148
+
149
+
150
+if __name__ == "__main__":
151
+    register()

バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/COLORS_GROUPS_EXCHANGER.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/DUAL_MESH.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/GCODE_EXPORT.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/LATTICE.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/NUMBA_FUNCTIONS.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/TESSELLATE_NUMPY.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/UTILS.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/UV_TO_MESH.CPYTHON-37.PYC ファイルの表示


バイナリ
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/TISSUE-MASTER/__PYCACHE__/__INIT__.CPYTHON-37.PYC ファイルの表示


+ 86
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/ADDONS/__INIT__.PY ファイルの表示

@@ -0,0 +1,86 @@
1
+'''
2
+Created by Marcin Zielinski, Doug Hammond, Thomas Ludwig, Nicholas Chapman, Yves Colle
3
+
4
+    This program is free software: you can redistribute it and/or modify
5
+    it under the terms of the GNU General Public License as published by
6
+    the Free Software Foundation, either version 3 of the License, or
7
+    (at your option) any later version.
8
+
9
+    This program is distributed in the hope that it will be useful,
10
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+    GNU General Public License for more details.
13
+
14
+    You should have received a copy of the GNU General Public License
15
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
+'''
17
+
18
+bl_info = {
19
+    "name": "Blendigo - Indigo Exporter",
20
+    "description": "This Addon will allow you to render your scenes with the Indigo render engine.",
21
+    "author": "Glare Technologies Ltd.",
22
+    "version": (4, 2, 0),
23
+    "blender": (2, 78, 0),
24
+    "location": "View3D",
25
+    "wiki_url": "",
26
+    "category": "Render" }
27
+
28
+
29
+import bpy
30
+
31
+# load and reload submodules
32
+##################################
33
+
34
+import importlib
35
+from . import developer_utils
36
+importlib.reload(developer_utils)
37
+modules = developer_utils.setup_addon_modules(__path__, __name__, "bpy" in locals())
38
+
39
+
40
+
41
+# register
42
+##################################
43
+
44
+import traceback
45
+
46
+def register():
47
+    try: bpy.utils.register_module(__name__)
48
+    except: traceback.print_exc()
49
+    
50
+    from . properties.render_settings import Indigo_Engine_Properties
51
+    bpy.types.Scene.indigo_engine = bpy.props.PointerProperty(name="Indigo Engine Properties", type = Indigo_Engine_Properties)
52
+    
53
+    from . properties.camera import Indigo_Camera_Properties
54
+    bpy.types.Camera.indigo_camera = bpy.props.PointerProperty(name="Indigo Camera Properties", type = Indigo_Camera_Properties)
55
+    
56
+    from . properties.environment import Indigo_Lightlayers_Properties
57
+    bpy.types.Scene.indigo_lightlayers = bpy.props.PointerProperty(name="Indigo Lightlayers Properties", type = Indigo_Lightlayers_Properties)
58
+    
59
+    from . properties.lamp import Indigo_Lamp_Sun_Properties, Indigo_Lamp_Hemi_Properties
60
+    bpy.types.Lamp.indigo_lamp_sun = bpy.props.PointerProperty(name="Indigo Lamp Sun Properties", type = Indigo_Lamp_Sun_Properties)
61
+    bpy.types.Lamp.indigo_lamp_hemi = bpy.props.PointerProperty(name="Indigo Lamp Hemi Properties", type = Indigo_Lamp_Hemi_Properties)
62
+    
63
+    from . properties.material import Indigo_Material_Properties, Indigo_Texture_Properties
64
+    bpy.types.Material.indigo_material = bpy.props.PointerProperty(name="Indigo Material Properties", type = Indigo_Material_Properties)
65
+    bpy.types.Texture.indigo_texture = bpy.props.PointerProperty(name="Indigo Texture Properties", type = Indigo_Texture_Properties)
66
+    
67
+    from . properties.medium import Indigo_Material_Medium_Properties
68
+    bpy.types.Scene.indigo_material_medium = bpy.props.PointerProperty(name="Indigo Material Medium Properties", type = Indigo_Material_Medium_Properties)
69
+    bpy.types.Material.indigo_material_medium = bpy.props.PointerProperty(name="Indigo Material Medium Properties", type = Indigo_Material_Medium_Properties)
70
+    
71
+    from . properties.object import Indigo_Mesh_Properties
72
+    bpy.types.Mesh.indigo_mesh = bpy.props.PointerProperty(name="Indigo Mesh Properties", type = Indigo_Mesh_Properties)
73
+    bpy.types.SurfaceCurve.indigo_mesh = bpy.props.PointerProperty(name="Indigo Mesh Properties", type = Indigo_Mesh_Properties)
74
+    bpy.types.TextCurve.indigo_mesh = bpy.props.PointerProperty(name="Indigo Mesh Properties", type = Indigo_Mesh_Properties)
75
+    bpy.types.Curve.indigo_mesh = bpy.props.PointerProperty(name="Indigo Mesh Properties", type = Indigo_Mesh_Properties)
76
+    
77
+    from . properties.tonemapping import Indigo_Tonemapping_Properties
78
+    bpy.types.Camera.indigo_tonemapping = bpy.props.PointerProperty(name="Indigo Tonemapping Properties", type = Indigo_Tonemapping_Properties)
79
+    
80
+    print("Registered {} with {} modules".format(bl_info["name"], len(modules)))
81
+
82
+def unregister():
83
+    try: bpy.utils.unregister_module(__name__)
84
+    except: traceback.print_exc()
85
+
86
+    print("Unregistered {}".format(bl_info["name"]))

+ 1
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/PRESETS/BKIT.JSON ファイルの表示

@@ -0,0 +1 @@
1
+{"API_key": "", "API_key_refresh": "", "global_dir": "C:\\Users\\Administrator\\blenderkit_data"}

+ 1489
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/PRESETS/INTERFACE_THEME/⠀.XML
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 1607
- 0
◯ᴥᗱᗴᗝИNᗱᗴᙁ⚭ⵙ⚭ᙁᗱᗴИNᗝᗱᗴᴥ◯/2.90/SCRIPTS/PRESETS/KEYCONFIG/YP.O_PAMYEK_REDNELB_O_BLENDER_KEYMAP_O.PY
ファイル差分が大きすぎるため省略します
ファイルの表示