소스 검색

Maya Exporter: Export Selected, Nicer JSON, default extension (#9431)

I’ve added a handful of improvements that I think will really help
people trying to use Maya with 3JS:

1. The current plugin will only perform an “EXPORT ALL” regardless of
what you select from the menu in Maya. I have fixed that so you can now
“Export All” or “Export Selected”. Export all sill merges geometry
rather than exporting a 3JS scene, may fix that in the future.
2. Updated the default extension to be “.json” rather than “.js”. This
is more in-line with 3JS and the other exporters.
3. I pulled the JSON encoder from the Blender exporter and integrated
it into the Maya one so that each item in the ups, faces, vertices, etc
arrays are no longer on a separate line. Makes the file MUCH easier to
read and debug.
4. Turned off sorting of the JSON output. This is more of an opinion,
but I didn’t feel like it helped the output at all.
Aaron Cloutier 9 년 전
부모
커밋
489146999d
1개의 변경된 파일205개의 추가작업 그리고 4개의 파일을 삭제
  1. 205 4
      utils/exporters/maya/plug-ins/threeJsFileTranslator.py

+ 205 - 4
utils/exporters/maya/plug-ins/threeJsFileTranslator.py

@@ -26,6 +26,7 @@ class ThreeJsWriter(object):
 
     def write(self, path, optionString, accessMode):
         self.path = path
+        self.accessMode = accessMode
         self._parseOptions(optionString)
 
         self.verticeOffset = 0
@@ -90,13 +91,17 @@ class ThreeJsWriter(object):
 
         with file(path, 'w') as f:
             if self.options['prettyOutput']:
-                f.write(json.dumps(output, sort_keys=True, indent=4, separators=(',', ': ')))
+                f.write(json.dumps(output, indent=4, separators=(", ", ": ")))
             else:
                 f.write(json.dumps(output, separators=(",",":")))
 
     def _allMeshes(self):
-        if not hasattr(self, '__allMeshes'):
+        if not self.accessMode == MPxFileTranslator.kExportActiveAccessMode :
+            print("*** Exporting ALL (NEW) ***")
             self.__allMeshes = filter(lambda m: len(m.listConnections()) > 0, ls(type='mesh'))
+        else :
+            print("### Exporting SELECTED ###")
+            self.__allMeshes = ls(sl=1)
         return self.__allMeshes
 
     def _parseOptions(self, optionsString):
@@ -394,10 +399,10 @@ class ThreeJsTranslator(MPxFileTranslator):
         return True
 
     def filter(self):
-        return '*.js'
+        return '*.json'
 
     def defaultExtension(self):
-        return 'js'
+        return 'json'
 
     def writer(self, fileObject, optionString, accessMode):
         path = fileObject.fullName()
@@ -443,3 +448,199 @@ class FramesPerSecond(object):
             return FramesPerSecond.MAYA_VALUES[self.fpsString]
         else:
             return int(filter(lambda c: c.isdigit(), self.fpsString))
+
+ROUND = 6
+
+## THREE override function
+def _json_floatstr(o):
+    if ROUND is not None:
+        o = round(o, ROUND)
+        
+    return '%g' % o
+
+
+def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
+        _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
+        ## HACK: hand-optimized bytecode; turn globals into locals
+        ValueError=ValueError,
+        basestring=basestring,
+        dict=dict,
+        float=float,
+        id=id,
+        int=int,
+        isinstance=isinstance,
+        list=list,
+        long=long,
+        str=str,
+        tuple=tuple,
+    ):
+
+    def _iterencode_list(lst, _current_indent_level):
+        if not lst:
+            yield '[]'
+            return
+        if markers is not None:
+            markerid = id(lst)
+            if markerid in markers:
+                raise ValueError("Circular reference detected")
+            markers[markerid] = lst
+        buf = '['
+    	#if _indent is not None:
+        #    _current_indent_level += 1
+        #    newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
+        #    separator = _item_separator + newline_indent
+        #    buf += newline_indent
+        #else:
+        newline_indent = None
+        separator = _item_separator
+        first = True
+        for value in lst:
+            if first:
+                first = False
+            else:
+                buf = separator
+            if isinstance(value, basestring):
+                yield buf + _encoder(value)
+            elif value is None:
+                yield buf + 'null'
+            elif value is True:
+                yield buf + 'true'
+            elif value is False:
+                yield buf + 'false'
+            elif isinstance(value, (int, long)):
+                yield buf + str(value)
+            elif isinstance(value, float):
+                yield buf + _floatstr(value)
+            else:
+                yield buf
+                if isinstance(value, (list, tuple)):
+                    chunks = _iterencode_list(value, _current_indent_level)
+                elif isinstance(value, dict):
+                    chunks = _iterencode_dict(value, _current_indent_level)
+                else:
+                    chunks = _iterencode(value, _current_indent_level)
+                for chunk in chunks:
+                    yield chunk
+        if newline_indent is not None:
+            _current_indent_level -= 1
+            yield '\n' + (' ' * (_indent * _current_indent_level))
+        yield ']'
+        if markers is not None:
+            del markers[markerid]
+
+    def _iterencode_dict(dct, _current_indent_level):
+        if not dct:
+            yield '{}'
+            return
+        if markers is not None:
+            markerid = id(dct)
+            if markerid in markers:
+                raise ValueError("Circular reference detected")
+            markers[markerid] = dct
+        yield '{'
+        if _indent is not None:
+            _current_indent_level += 1
+            newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
+            item_separator = _item_separator + newline_indent
+            yield newline_indent
+        else:
+            newline_indent = None
+            item_separator = _item_separator
+        first = True
+        if _sort_keys:
+            items = sorted(dct.items(), key=lambda kv: kv[0])
+        else:
+            items = dct.iteritems()
+        for key, value in items:
+            if isinstance(key, basestring):
+                pass
+            # JavaScript is weakly typed for these, so it makes sense to
+            # also allow them.  Many encoders seem to do something like this.
+            elif isinstance(key, float):
+                key = _floatstr(key)
+            elif key is True:
+                key = 'true'
+            elif key is False:
+                key = 'false'
+            elif key is None:
+                key = 'null'
+            elif isinstance(key, (int, long)):
+                key = str(key)
+            elif _skipkeys:
+                continue
+            else:
+                raise TypeError("key " + repr(key) + " is not a string")
+            if first:
+                first = False
+            else:
+                yield item_separator
+            yield _encoder(key)
+            yield _key_separator
+            if isinstance(value, basestring):
+                yield _encoder(value)
+            elif value is None:
+                yield 'null'
+            elif value is True:
+                yield 'true'
+            elif value is False:
+                yield 'false'
+            elif isinstance(value, (int, long)):
+                yield str(value)
+            elif isinstance(value, float):
+                yield _floatstr(value)
+            else:
+                if isinstance(value, (list, tuple)):
+                    chunks = _iterencode_list(value, _current_indent_level)
+                elif isinstance(value, dict):
+                    chunks = _iterencode_dict(value, _current_indent_level)
+                else:
+                    chunks = _iterencode(value, _current_indent_level)
+                for chunk in chunks:
+                    yield chunk
+        if newline_indent is not None:
+            _current_indent_level -= 1
+            yield '\n' + (' ' * (_indent * _current_indent_level))
+        yield '}'
+        if markers is not None:
+            del markers[markerid]
+
+    def _iterencode(o, _current_indent_level):
+        if isinstance(o, basestring):
+            yield _encoder(o)
+        elif o is None:
+            yield 'null'
+        elif o is True:
+            yield 'true'
+        elif o is False:
+            yield 'false'
+        elif isinstance(o, (int, long)):
+            yield str(o)
+        elif isinstance(o, float):
+            yield _floatstr(o)
+        elif isinstance(o, (list, tuple)):
+            for chunk in _iterencode_list(o, _current_indent_level):
+                yield chunk
+        elif isinstance(o, dict):
+            for chunk in _iterencode_dict(o, _current_indent_level):
+                yield chunk
+        else:
+            if markers is not None:
+                markerid = id(o)
+                if markerid in markers:
+                    raise ValueError("Circular reference detected")
+                markers[markerid] = o
+            o = _default(o)
+            for chunk in _iterencode(o, _current_indent_level):
+                yield chunk
+            if markers is not None:
+                del markers[markerid]
+
+    return _iterencode
+
+
+
+# override the encoder
+json.encoder._make_iterencode = _make_iterencode 
+
+
+