Tools: added --gui option to fcinfo tool
This commit is contained in:
@@ -30,7 +30,11 @@ __url__ = ["http://www.freecadweb.org"]
|
||||
__doc__ = '''
|
||||
This utility prints information about a given FreeCAD file (*.FCStd)
|
||||
on screen, including document properties, number of included objects,
|
||||
object sizes and properties and values
|
||||
object sizes and properties and values. Its main use is to compare
|
||||
two files and be able to see the differences in a text-based form.
|
||||
|
||||
If no option is used, fcinfo prints the document properties and a list
|
||||
of properties of each object found in the given file.
|
||||
|
||||
Usage:
|
||||
|
||||
@@ -39,30 +43,42 @@ Usage:
|
||||
Options:
|
||||
|
||||
-h, --help: Prints this help text
|
||||
-s, --short: Do not print all the properties contents of objects
|
||||
-vs --veryshort: Only prints the document info, not objects info
|
||||
-s, --short: Do not print object properties. Only one line
|
||||
per object is printed, including its size and SHA1.
|
||||
This is sufficient to see that an object has
|
||||
changed, but not what exactly has changed.
|
||||
-vs --veryshort: Only prints the document info, not objects info.
|
||||
This is sufficient to see if a file has changed, as
|
||||
its SHA1 code and timestamp will show it. But won't
|
||||
show details of what has changed.
|
||||
-g --gui: Adds visual properties too (if not using -s or -vs)
|
||||
|
||||
Git usage:
|
||||
|
||||
This script can be used as a textconv tool for git diff by
|
||||
configuring your git folder as follows:
|
||||
|
||||
1) add to .gitattributes:
|
||||
1) add to .gitattributes (or ~/.gitattributes for user-wide):
|
||||
|
||||
*.fcstd diff=fcinfo
|
||||
|
||||
2) add to .git/config (or ~/.gitconfig for user-wide):
|
||||
|
||||
[diff "fcinfo"]
|
||||
textconv = /path/to/fcinfo
|
||||
|
||||
With this, when committing a .FCStd file with Git,
|
||||
'git diff' will show you the difference between the two
|
||||
texts obtained by fcinfo
|
||||
|
||||
'''
|
||||
|
||||
|
||||
import sys, zipfile, xml.sax, os, hashlib
|
||||
|
||||
import sys
|
||||
import zipfile
|
||||
import xml.sax
|
||||
import os
|
||||
import hashlib
|
||||
import re
|
||||
|
||||
|
||||
|
||||
@@ -70,7 +86,7 @@ class FreeCADFileHandler(xml.sax.ContentHandler):
|
||||
|
||||
|
||||
|
||||
def __init__(self, zfile, short = 0): # short 0=normal, 1=short, 2=veryshort
|
||||
def __init__(self, zfile, short = 0): # short: 0=normal, 1=short, 2=veryshort
|
||||
|
||||
xml.sax.ContentHandler.__init__(self)
|
||||
self.zfile = zfile
|
||||
@@ -95,21 +111,30 @@ class FreeCADFileHandler(xml.sax.ContentHandler):
|
||||
if ("type" in attributes):
|
||||
self.contents[name] = attributes["type"]
|
||||
|
||||
elif tag == "ViewProvider":
|
||||
if ("name" in attributes):
|
||||
self.obj = self.clean(attributes["name"])
|
||||
|
||||
elif tag == "Part":
|
||||
if self.obj:
|
||||
s = self.zfile.read(attributes["file"]).__sizeof__()
|
||||
r = self.zfile.read(attributes["file"])
|
||||
s = r.__sizeof__()
|
||||
if s < 1024:
|
||||
s = str(s)+"B"
|
||||
elif s > 1048576:
|
||||
s = str(s/1048576)+"M"
|
||||
else:
|
||||
s = str(s/1024)+"K"
|
||||
|
||||
s += " " + str(hashlib.sha1(r).hexdigest()[:12])
|
||||
self.contents[self.obj] += " (" + s + ")"
|
||||
|
||||
elif tag == "Property":
|
||||
self.prop = None
|
||||
if attributes["name"] not in ["Symbol"]:
|
||||
# skip "internal" properties, unuseful for a diff
|
||||
if attributes["name"] not in ["Symbol","AttacherType","MapMode","MapPathParameter","MapReversed",
|
||||
"AttachmentOffset","SelectionStyle","TightGrid","GridSize","GridSnap",
|
||||
"GridStyle","Lighting","Deviation","AngularDeflection","BoundingBox",
|
||||
"Selectable","ShowGrid"]:
|
||||
self.prop = attributes["name"]
|
||||
|
||||
elif tag in ["String","Uuid","Float","Integer","Bool","Link"]:
|
||||
@@ -122,10 +147,31 @@ class FreeCADFileHandler(xml.sax.ContentHandler):
|
||||
else:
|
||||
self.contents[self.obj+"00000000::"+self.prop] = attributes["value"]
|
||||
|
||||
elif tag in ["PropertyVector"]:
|
||||
if self.prop and self.obj and (self.short == 0):
|
||||
val = "("+str(float(attributes["valueX"]))+","+str(float(attributes["valueY"]))+","+str(float(attributes["valueZ"]))+")"
|
||||
self.contents[self.obj+"00000000::"+self.prop] = val
|
||||
|
||||
elif tag in ["PropertyPlacement"]:
|
||||
if self.prop and self.obj and (self.short == 0):
|
||||
val = "("+str(float(attributes["Px"]))+","+str(float(attributes["Py"]))+","+str(float(attributes["Pz"]))+")"
|
||||
val += " ("+str(round(float(attributes["Q0"]),4))+","+str(round(float(attributes["Q1"]),4))+","
|
||||
val += str(round(float(attributes["Q2"]),4))+","+str(round(float(attributes["Q3"]),4))+")"
|
||||
self.contents[self.obj+"00000000::"+self.prop] = val
|
||||
|
||||
elif tag in ["PropertyColor"]:
|
||||
if self.prop and self.obj and (self.short == 0):
|
||||
c = int(attributes["value"])
|
||||
r = float((c>>24)&0xFF)/255.0
|
||||
g = float((c>>16)&0xFF)/255.0
|
||||
b = float((c>>8)&0xFF)/255.0
|
||||
val = str((r,g,b))
|
||||
self.contents[self.obj+"00000000::"+self.prop] = val
|
||||
|
||||
elif tag == "Objects":
|
||||
self.count = attributes["Count"]
|
||||
self.obj = None
|
||||
|
||||
|
||||
# Print all the contents of the document properties
|
||||
items = self.contents.items()
|
||||
items.sort()
|
||||
@@ -188,6 +234,14 @@ if __name__ == '__main__':
|
||||
if not "Document.xml" in zfile.namelist():
|
||||
sys.exit(1)
|
||||
doc = zfile.read("Document.xml")
|
||||
if gui and "GuiDocument.xml" in zfile.namelist():
|
||||
guidoc = zfile.read("GuiDocument.xml")
|
||||
guidoc = re.sub(r"<\?xml.*?-->"," ",guidoc,flags=re.MULTILINE|re.DOTALL)
|
||||
# a valid xml doc can have only one root element. So we need to insert
|
||||
# all the contents of the GUiDocument <document> tag into the main one
|
||||
doc = re.sub(r"<\/Document>","",doc,flags=re.MULTILINE|re.DOTALL)
|
||||
guidoc = re.sub(r"<Document.*?>"," ",guidoc,flags=re.MULTILINE|re.DOTALL)
|
||||
doc += guidoc
|
||||
s = os.path.getsize(sys.argv[-1])
|
||||
if s < 1024:
|
||||
s = str(s)+"B"
|
||||
|
||||
Reference in New Issue
Block a user