1+ import bpy
2+ import bmesh
3+ import os
4+ import io
5+ from pathlib import Path
6+ from . import (pdx_data , tree , utils )
7+
8+ class PdxFileImporter :
9+ def __init__ (self , filename ):
10+ self .filename = filename
11+ self .dataTree = tree .Tree (tree .TreeNode ("root" ))
12+
13+ def AddBlenderMesh (self ):
14+ meshNode = self .dataTree .search ("mesh" )
15+
16+ if not meshNode .hasSubNode ("uv_map" ):
17+ meshNode = meshNode .search ("mesh" , False )
18+
19+ if self .filename .find ("/" ) != - 1 :
20+ meshName = self .filename .rsplit ("/" , 1 )[1 ].replace (".mesh" , "" ) #self.dataTree.rootNode.searchForParentNode(meshNode.id).name
21+ elif self .filename .find ("\\ " ) != - 1 :
22+ meshName = self .filename .rsplit ("\\ " , 1 )[1 ].replace (".mesh" , "" ) #self.dataTree.rootNode.searchForParentNode(meshNode.id).name
23+ else :
24+ meshName = "ClausewitzMesh"
25+
26+ mesh = pdx_data .PdxMesh (meshNode .value , meshName )
27+
28+ obName = mesh .blenderName + "_object"
29+
30+ mesh .blenderMesh = bpy .data .meshes .new (mesh .blenderName )
31+ obj = bpy .data .objects .new (obName , mesh .blenderMesh )
32+
33+ scn = bpy .context .scene
34+ scn .objects .link (obj )
35+ scn .objects .active = obj
36+ obj .select = True
37+
38+ mesh .verts = utils .TransposeCoordinateArray (meshNode .search ("vertices" , False ).value )
39+ mesh .faces = utils .TransposeCoordinateArray (meshNode .search ("faces" , False ).value )
40+ mesh .uv_coords = utils .TransposeCoordinateArray2D (meshNode .search ("uv_map" , False ).value )
41+
42+ mesh .blenderMesh .from_pydata (mesh .verts , [], mesh .faces )
43+
44+ bm = bmesh .new ()
45+ bm .from_mesh (mesh .blenderMesh )
46+
47+ bm .verts .ensure_lookup_table ()
48+ bm .verts .index_update ()
49+ bm .faces .index_update ()
50+
51+ uv_layer = bm .loops .layers .uv .new (mesh .blenderName + "_uv" )
52+ for face in bm .faces :
53+ for loop in face .loops :
54+ loop [uv_layer ].uv [0 ] = mesh .uv_coords [loop .vert .index ][0 ]
55+ loop [uv_layer ].uv [1 ] = 1 - mesh .uv_coords [loop .vert .index ][1 ]
56+
57+ mat = bpy .data .materials .new (name = mesh .blenderName + "Material" )
58+
59+ obj .data .materials .append (mat )
60+
61+ tex = bpy .data .textures .new (meshName + "_text" , 'IMAGE' )
62+ tex .type = 'IMAGE'
63+
64+ imageFile = Path (os .path .join (os .path .dirname (self .filename ), meshNode .search ("diff" , False ).value [0 ]))
65+
66+ altImageFile = Path (os .path .join (os .path .dirname (self .filename ), meshName + "_diffuse.dds" ))
67+
68+ if imageFile .is_file ():
69+ imageFile .resolve ()
70+ image = bpy .data .images .load (str (imageFile ))
71+ tex .image = image
72+ elif altImageFile .is_file ():
73+ altImageFile .resolve ()
74+ image = bpy .data .images .load (str (altImageFile ))
75+ tex .image = image
76+ else :
77+ print ("No Texture File was found." )
78+
79+ slot = mat .texture_slots .add ()
80+ slot .texture = tex
81+ slot .bump_method = 'BUMP_ORIGINAL'
82+ slot .mapping = 'FLAT'
83+ slot .mapping_x = 'X'
84+ slot .mapping_y = 'Y'
85+ slot .texture_coords = 'UV'
86+ slot .use = True
87+ slot .uv_layer = uv_layer .name
88+
89+ bm .to_mesh (mesh .blenderMesh )
90+
91+ #Locator Add Block
92+ locatorNode = meshNode .search ("locator" , False )
93+
94+ locators = locatorNode .subNodes [0 ].Flatten ()
95+
96+ for i in range (0 , len (locators )):
97+ o = bpy .data .objects .new (locators [i ].name , None )
98+ bpy .context .scene .objects .link (o )
99+ o .empty_draw_size = 2
100+ o .empty_draw_type = 'PLAIN_AXES'
101+ o .location = (locators [i ].subNodes [0 ].value [0 ], locators [i ].subNodes [0 ].value [1 ], locators [i ].subNodes [0 ].value [2 ])
102+
103+ def ReadFile (self ):
104+ offset = 0
105+ meshFile = io .open (self .filename , "rb" )
106+ rawData = meshFile .read ()
107+
108+ # Remove File Identifier
109+ data = rawData .lstrip (b"@@b@" )
110+
111+ buffer = utils .BufferReader (data )
112+
113+ rootNode = tree .TreeNode ("root" )
114+
115+ self .dataTree = tree .Tree (rootNode )
116+ self .ReadObject (rootNode , buffer , - 1 )
117+
118+ self .dataTree .print ()
119+ meshFile .close ()
120+
121+ def ReadProperty (self , treeNode : tree .TreeNode , buffer : utils .BufferReader ):
122+ name = ""
123+ dataCount = 0
124+ stringType = 1
125+ propertyData = []
126+
127+ nameLength = buffer .NextInt8 ()
128+
129+ for i in range (1 , nameLength + 1 ):
130+ name += buffer .NextChar ()
131+
132+ name = utils .TranslatePropertyName (name )
133+
134+ char = buffer .NextChar ()
135+
136+ if char == "i" :
137+ dataCount = buffer .NextUInt32 ()
138+
139+ for i in range (0 , dataCount ):
140+ propertyData .append (buffer .NextInt32 ())
141+ elif char == "f" :
142+ dataCount = buffer .NextUInt32 ()
143+
144+ for i in range (0 , dataCount ):
145+ propertyData .append (buffer .NextFloat32 ())
146+ elif char == "s" :
147+ stringValue = ""
148+ stringType = buffer .NextUInt32 ()
149+ dataCount = buffer .NextUInt32 ()
150+
151+ stringValue = self .ReadNullByteString (buffer )
152+
153+ propertyData .append (stringValue )
154+
155+ newNode = tree .TreeNode (name )
156+ newNode .value = propertyData
157+
158+ treeNode .append (newNode )
159+
160+ def ReadObject (self , treeNode : tree .TreeNode , buffer : utils .BufferReader , depth ):
161+ objectName = ""
162+ char = buffer .NextChar ()
163+
164+ while not buffer .IsEOF () and char == '[' :
165+ depth += 1
166+ char = buffer .NextChar ()
167+
168+ node = treeNode
169+
170+ if depth >= 0 :
171+ objectName = char + self .ReadNullByteString (buffer )
172+
173+ node = tree .TreeNode (objectName )
174+ treeNode .append (node )
175+
176+ while not buffer .IsEOF ():
177+ if char == "!" :
178+ self .ReadProperty (node , buffer )
179+ elif char == "[" :
180+ self .ReadObject (node , buffer , depth + 1 )
181+
182+ if not buffer .IsEOF ():
183+ char = buffer .NextChar ()
184+
185+ def ReadNullByteString (self , buffer : utils .BufferReader ):
186+ stringValue = ""
187+
188+ char = buffer .NextChar ()
189+
190+ while char != "\x00 " :
191+ stringValue += char
192+ char = buffer .NextChar ()
193+
194+ return stringValue
0 commit comments