Package pyffi :: Package spells :: Package nif
[hide private]
[frames] | no frames]

Source Code for Package pyffi.spells.nif

  1  """ 
  2  :mod:`pyffi.spells.nif` ---  NetImmerse/Gamebryo File/Keyframe (.nif/.kf/.kfa) spells 
  3  ===================================================================================== 
  4   
  5  .. automodule:: pyffi.spells.nif.check 
  6  .. automodule:: pyffi.spells.nif.dump 
  7  .. automodule:: pyffi.spells.nif.fix 
  8  .. automodule:: pyffi.spells.nif.optimize 
  9  .. automodule:: pyffi.spells.nif.modify 
 10  """ 
 11   
 12  # -------------------------------------------------------------------------- 
 13  # ***** BEGIN LICENSE BLOCK ***** 
 14  # 
 15  # Copyright (c) 2007-2011, NIF File Format Library and Tools. 
 16  # All rights reserved. 
 17  # 
 18  # Redistribution and use in source and binary forms, with or without 
 19  # modification, are permitted provided that the following conditions 
 20  # are met: 
 21  # 
 22  #    * Redistributions of source code must retain the above copyright 
 23  #      notice, this list of conditions and the following disclaimer. 
 24  # 
 25  #    * Redistributions in binary form must reproduce the above 
 26  #      copyright notice, this list of conditions and the following 
 27  #      disclaimer in the documentation and/or other materials provided 
 28  #      with the distribution. 
 29  # 
 30  #    * Neither the name of the NIF File Format Library and Tools 
 31  #      project nor the names of its contributors may be used to endorse 
 32  #      or promote products derived from this software without specific 
 33  #      prior written permission. 
 34  # 
 35  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 36  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 37  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 38  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 39  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 40  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 41  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 42  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 43  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 44  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 45  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 46  # POSSIBILITY OF SUCH DAMAGE. 
 47  # 
 48  # ***** END LICENSE BLOCK ***** 
 49  # -------------------------------------------------------------------------- 
 50   
 51  import pyffi.spells 
 52  from pyffi.formats.nif import NifFormat 
 53   
54 -class NifSpell(pyffi.spells.Spell):
55 """Base class for spells for nif files.""" 56
57 - def _datainspect(self):
58 # list of all block types used in the header 59 # (do this first, spells may depend on this being present) 60 self.header_types = [] 61 for block_type in self.data.header.block_types: 62 block_type = block_type.decode("ascii") 63 # handle NiDataStream 64 if block_type.startswith("NiDataStream\x01"): 65 block_type = "NiDataStream" 66 self.header_types.append(getattr(NifFormat, block_type)) 67 68 # call base method 69 if not pyffi.spells.Spell._datainspect(self): 70 return False 71 72 # shortcut for common case (speeds up the check in most cases) 73 if not self.toaster.include_types and not self.toaster.exclude_types: 74 return True 75 76 # old file formats have no list of block types 77 # we cover that here 78 if not self.header_types: 79 return True 80 81 # check that at least one block type of the header is admissible 82 return any(self.toaster.is_admissible_branch_class(header_type) 83 for header_type in self.header_types)
84
85 - def inspectblocktype(self, block_type):
86 """This function heuristically checks whether the given block type 87 is used in the nif file, using header information only. When in doubt, 88 it returns ``True``. 89 90 :param block_type: The block type. 91 :type block_type: :class:`NifFormat.NiObject` 92 :return: ``False`` if the nif has no block of the given type, 93 with certainty. ``True`` if the nif has the block, or if it 94 cannot be determined. 95 :rtype: ``bool`` 96 """ 97 try: 98 # try via header 99 return self.data.header.has_block_type(block_type) 100 except ValueError: 101 # header does not have the information because nif version is 102 # too old 103 return True
104
105 -class SpellVisitSkeletonRoots(NifSpell):
106 """Abstract base class for spells that visit all skeleton roots. 107 Override the skelrootentry method with your implementation. 108 """ 109
110 - def datainspect(self):
111 # only run the spell if there are skinned geometries 112 return self.inspectblocktype(NifFormat.NiSkinInstance)
113
114 - def dataentry(self):
115 # make list of skeleton roots 116 self._skelroots = set() 117 for branch in self.data.get_global_iterator(): 118 if isinstance(branch, NifFormat.NiGeometry): 119 if branch.skin_instance: 120 skelroot = branch.skin_instance.skeleton_root 121 if skelroot and not(id(skelroot) in self._skelroots): 122 self._skelroots.add(id(skelroot)) 123 # only apply spell if there are skeleton roots 124 if self._skelroots: 125 return True 126 else: 127 return False
128
129 - def branchinspect(self, branch):
130 # only inspect the NiNode branch 131 return isinstance(branch, NifFormat.NiNode)
132
133 - def branchentry(self, branch):
134 if id(branch) in self._skelroots: 135 self.skelrootentry(branch) 136 self._skelroots.remove(id(branch)) 137 # keep recursing into children if there are skeleton roots left 138 return bool(self._skelroots)
139
140 - def skelrootentry(self, branch):
141 """Do something with a skeleton root. Return value is ignored.""" 142 raise NotImplementedError
143
144 -class NifToaster(pyffi.spells.Toaster):
145 FILEFORMAT = NifFormat
146