1
1
#!/usr/bin/env python3
2
2
3
+
3
4
import bpy
4
5
import os
5
6
import ctypes
6
7
from mathutils import Vector , Quaternion , Matrix
7
8
9
+ import os
10
+ import sys
11
+ importpath = os .path .dirname (os .path .realpath (__file__ ))
12
+ sys .path .append (importpath )
13
+ import pywickedengine as wi
14
+
8
15
9
16
bl_info = {
10
17
"name" : "Wicked wiscene Extension" ,
20
27
}
21
28
22
29
23
- def WIVector3 (blvector3 : Vector ):
24
- import pywickedengine as wi
30
+ def WIVector3 (blvector3 : Vector ) -> wi .XMFLOAT3 :
25
31
return wi .XMFLOAT3 (blvector3 [0 ], blvector3 [2 ], blvector3 [1 ])
26
32
27
- def WIQuaternion (q : Quaternion ):
28
- import pywickedengine as wi
33
+ def WIQuaternion (q : Quaternion ) -> wi .XMFLOAT4 :
29
34
# [W X Y Z] -> [X Y Z W] -> [X Z Y -W]
30
35
# q2=[q1.x,q1.z,q1.y,−q1.w]
31
36
return wi .XMFLOAT4 (q [1 ], q [3 ], q [2 ], - q [0 ])
32
37
33
- def wicked_add_mesh (item , scene , root ):
34
- print (f"Adding { item .name } mesh ..." )
35
- import pywickedengine as wi
36
- entity = scene .Entity_CreateObject (item .name )
38
+ def wicked_add_mesh (obj , scene , root ):
39
+ print (f"Adding { obj .name } mesh ..." )
40
+ mesh = obj .data
41
+ entity = scene .Entity_CreateObject (obj .name )
42
+ print (f'{ obj .name } ={ entity } ' )
37
43
object = scene .objects ().GetComponent (entity )
38
44
scene .meshes ().Create (entity )
39
- #entity = scene.Entity_CreateMesh(item .name)
45
+ #entity = scene.Entity_CreateMesh(obj .name)
40
46
#scene.Component_Attach(entity, root) #TODO this creates a self referencing entity, getting the loading screen stuck in an infintie while loop
41
- mesh = scene .meshes ().GetComponent (entity )
47
+ wimesh = scene .meshes ().GetComponent (entity )
42
48
transform = scene .transforms ().GetComponent (entity )
43
- transform .translation_local = WIVector3 (item .location )
44
- transform .scale_local = WIVector3 (item .scale )
45
- if item .rotation_mode == 'QUATERNION' :
46
- transform .rotation_local = WIQuaternion (item .rotation_quaternion )
49
+ transform .translation_local = WIVector3 (obj .location )
50
+ transform .scale_local = WIVector3 (obj .scale )
51
+ if obj .rotation_mode == 'QUATERNION' :
52
+ transform .rotation_local = WIQuaternion (obj .rotation_quaternion )
47
53
else :
48
- transform .rotation_local = WIQuaternion (item .rotation_euler .to_matrix ().to_quaternion ())
54
+ transform .rotation_local = WIQuaternion (obj .rotation_euler .to_matrix ().to_quaternion ())
49
55
transform .UpdateTransform ()
50
56
object .meshID = entity
51
57
@@ -55,69 +61,87 @@ def wicked_add_mesh(item, scene, root):
55
61
#vertices[i].co # position data
56
62
#vertices[i].undeformed_co # position data - no deforming modifiers applied
57
63
64
+ for mat in mesh .materials :
65
+ pass
66
+ #TODO create a subset per material
58
67
# create only one submesh for now
59
- #TODO later create a submesh for each material (or similar)
60
68
subset = wi .MeshComponent_MeshSubset ()
61
69
material = scene .materials ().GetComponent (subset .materialID )
62
- vertex_offset = len (mesh .vertex_positions )
70
+ vertex_offset = len (wimesh .vertex_positions )
71
+
72
+ print ("Generating vertex data" )
73
+ mesh .calc_loop_triangles ()
74
+ #After using mesh.calc_normals_split() you access the normals with loop.normal
75
+ mesh .calc_normals_split ()
76
+
77
+ vertices_map = {}
78
+ vertices_array = []
63
79
64
80
#index_remap = [0,1,-1]
65
81
index_remap = [0 ,0 ,0 ]
66
82
67
- # append vertices
68
- print (f"Adding vertex data (len={ len (item .data .vertices )} )" )
69
- for vertex in item .data .vertices :
70
- mesh .vertex_positions .append (WIVector3 (vertex .co ))
71
- mesh .vertex_normals .append (WIVector3 (vertex .normal ))
72
- mesh .vertex_uvset_0 .append (wi .XMFLOAT2 (0 ,0 ))
73
-
74
- print ("Adding index data" )
75
- for face in item .data .loop_triangles :
76
- #print("Polygon index: %d, length: %d" % (face.index, 3))
83
+ for triangle in mesh .loop_triangles :
84
+ face_index = mesh .loop_triangle_polygons [triangle .index ].value
85
+ face = mesh .polygons [face_index ]
86
+ #print(f'triangle[{triangle.index}]{triangle}={face_index} SmoothGroup={smooth_groups[face_index]}')
77
87
offset = 0
78
- for i in face .loops :
79
- ix = item .data .loops [i + index_remap [offset ]].vertex_index
80
- mesh .indices .append (ix )
81
- #print(" Vertex: %d %r" % (item.data.loops[i].vertex_index, item.data.vertices[ix].co))
82
- #print(" UV: %r" % item.data.uv_layers.active.data[i].uv)
88
+ for i in triangle .loops :
89
+ i += index_remap [offset ]
90
+ ix = mesh .loops [i ].vertex_index
91
+ normal = mesh .loops [i ].normal
92
+ uv = mesh .uv_layers .active .data [i ].uv
93
+ assert len (uv ) == 2
94
+ v = (ix , WIVector3 (normal ), wi .XMFLOAT2 (uv [0 ], uv [1 ]))
95
+ if v in vertices_map :
96
+ newix = vertices_map [v ]
97
+ else :
98
+ newix = len (vertices_array )
99
+ vertices_array .append (v )
100
+ vertices_map [v ] = newix
101
+ wimesh .indices .append (newix )
83
102
offset += 1
84
- #verts_in_face = face.vertices[:]
85
- #print("face index ", face.index)
86
- #print("normal ", face.normal)
87
- #for vert in verts_in_face:
88
- # print("vertex coords ", item.data.vertices[vert].co)
89
103
90
- if len (mesh .vertex_normals ) == 0 and len (mesh .vertex_positions ) > 0 :
91
- for _ in range (len (mesh .vertex_positions )):
92
- mesh .vertex_normals .append (wi .XMFLOAT3 (0 ,0 ,0 ))
93
- mesh .ComputeNormals (wi .MeshComponentComputeNormals .SMOOTH_FAST );
104
+ print ("Adding vertex data" )
105
+ for i , normal , uv in vertices_array :
106
+ vertex = mesh .vertices [i ]
107
+ wimesh .vertex_positions .append (WIVector3 (vertex .co ))
108
+ wimesh .vertex_normals .append (normal )
109
+ wimesh .vertex_uvset_0 .append (uv )
110
+
111
+ if len (wimesh .vertex_normals ) == 0 and len (wimesh .vertex_positions ) > 0 :
112
+ print ("Generating missing normal data" )
113
+ for _ in range (len (wimesh .vertex_positions )):
114
+ wimesh .vertex_normals .append (wi .XMFLOAT3 (0 ,0 ,0 ))
115
+ wimesh .ComputeNormals (wi .MeshComponentComputeNormals .SMOOTH_FAST );
94
116
95
117
subset .materialID = scene .materials ().GetEntity (0 )#max(0, face.material))
96
118
subset .indexOffset = 0
97
- subset .indexCount = len (mesh .indices )
98
- mesh .subsets .append (subset )
119
+ subset .indexCount = len (wimesh .indices )
120
+ wimesh .subsets .append (subset )
99
121
100
- print (f"Finished adding { item .name } mesh" )
122
+ print (f"Finished adding { obj .name } mesh" )
101
123
102
124
103
125
def create_wiscene (scene_name ):
104
- import pywickedengine as wi
105
126
### Load Scene
106
127
scene = wi .Scene ()
107
128
rootEntity = wi .CreateEntity ()
129
+ print (f'rootEntity({ scene_name } )={ rootEntity } ' )
108
130
scene .transforms ().Create (rootEntity )
109
131
scene .names ().Create (rootEntity )
110
132
scene .names ().GetComponent (rootEntity ).name = scene_name
111
133
112
134
#TODO materials
135
+ for mat in bpy .data .materials :
136
+ pass
113
137
114
138
# Meshes
115
139
print ("Exporting meshes" )
116
- for item in bpy .data .objects :
117
- print (f"Element in scene { item .name } " )
118
- match item .type :
140
+ for obj in bpy .data .objects :
141
+ print (f"Element in scene { obj .name } " )
142
+ match obj .type :
119
143
case 'MESH' :
120
- wicked_add_mesh (item , scene , rootEntity )
144
+ wicked_add_mesh (obj , scene , rootEntity )
121
145
print ("Finished exporting meshes" )
122
146
123
147
#TODO armatures
@@ -145,7 +169,6 @@ def create_wiscene(scene_name):
145
169
146
170
def write_wiscene (context , filepath , dump_to_header : bool ):
147
171
print ("running write_wiscene..." )
148
- import pywickedengine as wi
149
172
150
173
filename = os .path .splitext (filepath )[0 ]
151
174
scene_name = os .path .basename (filename )
@@ -218,13 +241,15 @@ def menu_func_export(self, context):
218
241
219
242
# Register and add to the "file selector" menu (required to use F3 search "Text Export Operator" for quick access).
220
243
def register ():
244
+ wi .init ()
221
245
bpy .utils .register_class (ExportWiScene )
222
246
bpy .types .TOPBAR_MT_file_export .append (menu_func_export )
223
247
224
248
225
249
def unregister ():
226
250
bpy .utils .unregister_class (ExportWiScene )
227
251
bpy .types .TOPBAR_MT_file_export .remove (menu_func_export )
252
+ wi .deinit ()
228
253
229
254
230
255
if __name__ == "__main__" :
0 commit comments