genblenddna.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #!/usr/bin/env python3
  2. # -*- Coding: UTF-8 -*-
  3. # ---------------------------------------------------------------------------
  4. # Open Asset Import Library (ASSIMP)
  5. # ---------------------------------------------------------------------------
  6. #
  7. # Copyright (c) 2006-2010, ASSIMP Development Team
  8. #
  9. # All rights reserved.
  10. #
  11. # Redistribution and use of this software in source and binary forms,
  12. # with or without modification, are permitted provided that the following
  13. # conditions are met:
  14. #
  15. # * Redistributions of source code must retain the above
  16. # copyright notice, this list of conditions and the
  17. # following disclaimer.
  18. #
  19. # * Redistributions in binary form must reproduce the above
  20. # copyright notice, this list of conditions and the
  21. # following disclaimer in the documentation and/or other
  22. # materials provided with the distribution.
  23. #
  24. # * Neither the name of the ASSIMP team, nor the names of its
  25. # contributors may be used to endorse or promote products
  26. # derived from this software without specific prior
  27. # written permission of the ASSIMP Development Team.
  28. #
  29. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  31. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  32. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  33. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  34. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  35. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  36. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  37. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  39. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. # ---------------------------------------------------------------------------
  41. """Generate BlenderSceneGen.h and BlenderScene.cpp from the
  42. data structures in BlenderScene.h to map from *any* DNA to
  43. *our* DNA"""
  44. import sys
  45. import os
  46. import re
  47. inputfile = os.path.join("..","..","code","BlenderScene.h")
  48. outputfile_gen = os.path.join("..","..","code","BlenderSceneGen.h")
  49. outputfile_src = os.path.join("..","..","code","BlenderScene.cpp")
  50. template_gen = "BlenderSceneGen.h.template"
  51. template_src = "BlenderScene.cpp.template"
  52. Structure_Convert_decl = """
  53. template <> void Structure :: Convert<{a}> (
  54. {a}& dest,
  55. const FileDatabase& db
  56. ) const
  57. """
  58. Structure_Convert_ptrdecl = """
  59. ReadFieldPtr<{policy}>({destcast}dest.{name_canonical},"{name_dna}",db);"""
  60. Structure_Convert_arraydecl = """
  61. ReadFieldArray<{policy}>({destcast}dest.{name_canonical},"{name_dna}",db);"""
  62. Structure_Convert_arraydecl2d = """
  63. ReadFieldArray2<{policy}>({destcast}dest.{name_canonical},"{name_dna}",db);"""
  64. Structure_Convert_normal = """
  65. ReadField<{policy}>({destcast}dest.{name_canonical},"{name_dna}",db);"""
  66. DNA_RegisterConverters_decl = """
  67. void DNA::RegisterConverters() """
  68. DNA_RegisterConverters_add = """
  69. converters["{a}"] = DNA::FactoryPair( &Structure::Allocate<{a}>, &Structure::Convert<{a}> );"""
  70. map_policy = {
  71. "" : "ErrorPolicy_Igno"
  72. ,"IGNO" : "ErrorPolicy_Igno"
  73. ,"WARN" : "ErrorPolicy_Warn"
  74. ,"FAIL" : "ErrorPolicy_Fail"
  75. }
  76. #
  77. def main():
  78. # -----------------------------------------------------------------------
  79. # Parse structure definitions from BlenderScene.h
  80. input = open(inputfile,"rt").read()
  81. flags = re.ASCII|re.DOTALL|re.MULTILINE
  82. #stripcoms = re.compile(r"/\*(.*?)*\/",flags)
  83. getstruct = re.compile(r"struct\s+(\w+?)\s*(:\s*ElemBase)?\s*\{(.*?)^\}\s*;",flags)
  84. getsmartx = re.compile(r"(std\s*::\s*)?(vector)\s*<\s*(boost\s*::\s*)?shared_(ptr)\s*<\s*(\w+)\s*>\s*>\s*",flags)
  85. getsmartp = re.compile(r"(boost\s*::\s*)?shared_(ptr)\s*<\s*(\w+)\s*>\s*",flags)
  86. getsmarta = re.compile(r"(std\s*::\s*)?(vector)\s*<\s*(\w+)\s*>\s*",flags)
  87. getpolicy = re.compile(r"\s*(WARN|FAIL|IGNO)",flags)
  88. stripenum = re.compile(r"enum\s+(\w+)\s*{.*?\}\s*;",flags)
  89. assert getsmartx and getsmartp and getsmarta and getpolicy and stripenum
  90. enums = set()
  91. #re.sub(stripcoms," ",input)
  92. #print(input)
  93. hits = {}
  94. while 1:
  95. match = re.search(getstruct,input)
  96. if match is None:
  97. break
  98. tmp = match.groups()[2]
  99. while 1:
  100. match2 = re.search(stripenum,tmp)
  101. if match2 is None:
  102. break
  103. tmp = tmp[match2.end():]
  104. enums.add(match2.groups()[0])
  105. hits[match.groups()[0]] = list(
  106. filter(lambda x:x[:2] != "//" and len(x),
  107. map(str.strip,
  108. re.sub(stripenum," ",match.groups()[2]).split(";")
  109. )))
  110. input = input[match.end():]
  111. [print ("Enum: "+e) for e in enums]
  112. for k,v in hits.items():
  113. out = []
  114. for line in v:
  115. policy = "IGNO"
  116. py = re.search(getpolicy,line)
  117. if not py is None:
  118. policy = py.groups()[0]
  119. line = re.sub(getpolicy,"",line)
  120. ty = re.match(getsmartx,line) or re.match(getsmartp,line) or re.match(getsmarta,line)
  121. if ty is None:
  122. ty = line.split(None,1)[0]
  123. else:
  124. if ty.groups()[1] == "ptr":
  125. ty = ty.groups()[2] + "*"
  126. elif ty.groups()[1] == "vector":
  127. ty = ty.groups()[-1] + ("*" if len(ty.groups()) == 3 else "**")
  128. #print(line)
  129. sp = line.split(',')
  130. out.append((ty,sp[0].split(None)[-1].strip(),policy))
  131. for m in sp[1:]:
  132. out.append((ty,m.strip(),policy))
  133. v[:] = out
  134. print("Structure {0}".format(k))
  135. [print("\t"+"\t".join(elem)) for elem in out]
  136. print("")
  137. output = open(outputfile_gen,"wt")
  138. templt = open(template_gen,"rt").read()
  139. s = ""
  140. # -----------------------------------------------------------------------
  141. # Structure::Convert<T> declarations for all supported structures
  142. for k,v in hits.items():
  143. s += Structure_Convert_decl.format(a=k)+";\n";
  144. output.write(templt.replace("<HERE>",s))
  145. output = open(outputfile_src,"wt")
  146. templt = open(template_src,"rt").read()
  147. s = ""
  148. # -----------------------------------------------------------------------
  149. # Structure::Convert<T> definitions for all supported structures
  150. for k,v in hits.items():
  151. s += "//" + "-"*80 + Structure_Convert_decl.format(a=k)+ "{ \n";
  152. for type, name, policy in v:
  153. splits = name.split("[",1)
  154. name_canonical = splits[0]
  155. #array_part = "" if len(splits)==1 else "["+splits[1]
  156. ptr_decl = "*"*type.count("*")
  157. name_dna = ptr_decl+name_canonical #+array_part
  158. #required = "false"
  159. policy = map_policy[policy]
  160. destcast = "(int&)" if type in enums else ""
  161. # POINTER
  162. if ptr_decl:
  163. s += Structure_Convert_ptrdecl.format(**locals())
  164. # ARRAY MEMBER
  165. elif name.count('[')==1:
  166. s += Structure_Convert_arraydecl.format(**locals())
  167. elif name.count('[')==2:
  168. s += Structure_Convert_arraydecl2d.format(**locals())
  169. # NORMAL MEMBER
  170. else:
  171. s += Structure_Convert_normal.format(**locals())
  172. s += "\n\n\tdb.reader->IncPtr(size);\n}\n\n"
  173. # -----------------------------------------------------------------------
  174. # DNA::RegisterConverters - collect all available converter functions
  175. # in a std::map<name,converter_proc>
  176. #s += "#if 0\n"
  177. s += "//" + "-"*80 + DNA_RegisterConverters_decl + "{\n"
  178. for k,v in hits.items():
  179. s += DNA_RegisterConverters_add.format(a=k)
  180. s += "\n}\n"
  181. #s += "#endif\n"
  182. output.write(templt.replace("<HERE>",s))
  183. if __name__ == "__main__":
  184. sys.exit(main())