From dac51d6e9a0800b5922b40e2692ab4c9a422a980 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sat, 14 Jan 2012 16:14:29 -0200 Subject: [PATCH 1/7] fixes to Draft SVG importer (shoogen) --- src/Mod/Draft/importSVG.py | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index 3bf940899..7157e659f 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -231,7 +231,6 @@ def getrgb(color): return "#"+r+g+b def splitpathd(pathdstr): - "returns a list with the elements contained in the d attribute of a path" whitespacechars = [' ','\t','\r','\n'] commandchars = ['m','M','l','L','h','H','v','V','a','A','c','C','q','Q','s','S','t','T','z','Z'] numberchars = ['e','E','+','-','.','0','1','2','3','4','5','6','7','8','9'] @@ -360,7 +359,38 @@ class svgHandler(xml.sax.ContentHandler): else: if name == "g": self.grouptransform.append(FreeCAD.Matrix()) - + + ''' + print "existing grouptransform: ",self.grouptransform + print "existing transform: ",self.transform + if "translate" in tr: + i0 = tr.index("translate") + print "getting translate ",tr + if "translate" in self.transform: + self.transform['translate'] = self.transform['translate'].add(Vector(float(tr[i0+1]),-float(tr[i0+2]),0)) + else: + self.transform['translate'] = Vector(float(tr[i0+1]),-float(tr[i0+2]),0) + if "translate" in self.grouptransform: + print "adding to group ",self.grouptransform['translate'] + self.transform['translate'] = self.grouptransform['translate'].add(self.transform['translate']) + else: + if "translate" in self.grouptransform: + print "adding to group ",self.grouptransform['translate'] + self.transform['translate'] = self.grouptransform['translate'] + if "scale" in tr: + i0 = tr.index("scale") + if "scale" in self.transform: + self.transform['scale'] = self.transform['scale'].add(Vector(float(tr[i0+1]),float(tr[i0+2]),0)) + else: + print tr + self.transform['scale'] = Vector(float(tr[i0+1]),float(tr[i0+2]),0) + if "scale" in self.grouptransform: + self.transform['scale'] = self.transform['scale'].add(self.grouptransform['scale']) + else: + if "scale" in self.grouptransform: + self.transform['scale'] = self.grouptransform['scale'] + ''' + if (self.style == 1): self.color = self.col self.width = self.lw From 6d86e84d2837ee40f6cfac588c11297581d8be61 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sun, 15 Jan 2012 19:09:27 -0200 Subject: [PATCH 2/7] upgraded Arch IFC importer to work with patched ifcOpenShell (imports objects directly as Part shapes) --- src/Mod/Arch/Arch_rc.py | 292 ++++++++++---------- src/Mod/Arch/Resources/ui/archprefs-base.ui | 101 ++----- src/Mod/Arch/importIFC.py | 89 +++--- 3 files changed, 219 insertions(+), 263 deletions(-) diff --git a/src/Mod/Arch/Arch_rc.py b/src/Mod/Arch/Arch_rc.py index a8691486c..62078f065 100644 --- a/src/Mod/Arch/Arch_rc.py +++ b/src/Mod/Arch/Arch_rc.py @@ -2,8 +2,8 @@ # Resource object code # -# Created: Fri Jan 6 18:11:49 2012 -# by: The Resource Compiler for PyQt (Qt v4.7.3) +# Created: Sun Jan 15 17:53:12 2012 +# by: The Resource Compiler for PyQt (Qt v4.7.4) # # WARNING! All changes made in this file will be lost! @@ -5697,132 +5697,122 @@ qt_resource_data = "\ \x00\x00\x00\x12\x00\x57\x00\x65\x00\x72\x00\x6b\x00\x7a\x00\x65\ \x00\x75\x00\x67\x00\x65\x08\x00\x00\x00\x00\x06\x00\x00\x00\x05\ \x54\x6f\x6f\x6c\x73\x07\x00\x00\x00\x04\x61\x72\x63\x68\x01\ -\x00\x00\x07\xb2\ +\x00\x00\x07\x16\ \x00\ -\x00\x28\x75\x78\x9c\xed\x5a\xeb\x73\xd3\x38\x10\xff\xde\xbf\x42\ -\x97\x9b\xe1\x31\xd3\x44\x49\xdb\x94\x36\x75\x7d\x03\x7d\x40\x67\ -\xe0\x28\xb4\xc0\xdc\x27\xc6\xb1\x95\x58\x20\x5b\xc6\x92\x49\xc2\ -\xcd\xfd\xef\xb7\x7a\x38\x7e\xa5\xe9\x23\xa1\x1c\x37\xcc\x14\x6a\ -\x69\xa5\xdd\xd5\x4f\xab\xdf\xae\x5c\x3b\x7f\x4c\x23\x86\xbe\x92\ -\x54\x50\x1e\x1f\xb6\x7a\x9d\x6e\x0b\x91\xd8\xe7\x01\x8d\xc7\x87\ -\xad\x77\x97\xa7\xed\xbd\xd6\x1f\xee\x86\x93\xd1\x62\xd0\x0e\x0c\ -\x72\x37\x90\xe3\x33\x4f\x08\xf7\x79\x46\x07\x83\x63\xea\x31\x3e\ -\x86\xdf\x6c\x7c\x41\xa4\x84\xc9\xe2\x69\xea\x87\x0e\x36\x63\x60\ -\xf0\x84\x06\x63\x22\x91\x6e\x1f\xb6\xde\x7c\xd0\xcd\x16\x8a\xbd\ -\x88\x1c\xb6\x96\xe9\x50\xa6\x90\x93\xa4\x3c\x21\xa9\x9c\xd9\x09\ -\x63\xc2\x23\x22\xd3\x99\x16\x22\x27\x25\xbe\xd4\x4f\xc8\x99\xba\ -\x5d\x07\x4f\x6d\x63\xa6\x1a\x33\xdb\x00\x0f\x64\xe8\xf6\x9f\xf4\ -\x1d\x6c\x1e\x4d\x77\x48\xe8\x38\x94\xee\xee\xd6\xbe\x83\xed\xb3\ -\xd6\x89\x73\xa5\x0e\xce\x8d\x2f\xf2\x64\x42\xe3\x80\x4f\x2e\xa9\ -\x64\xc4\x3a\x23\x64\x0a\xbe\xbb\xcf\x49\x4c\x52\x8f\x21\x61\xd7\ -\xe2\x60\x2b\x68\xaa\x64\xde\x8c\x67\x05\x36\xef\x9f\xf1\xe9\x4b\ -\xdd\x65\x35\xd6\x4c\x8a\xc4\xf3\x41\x51\xcb\x2e\x20\xce\xa2\x21\ -\x49\xdd\x5d\x07\xdb\x27\xe3\x7e\xd9\x42\x43\x45\xe4\xa5\x63\x1a\ -\xd7\x34\xec\x2f\xd5\x40\x25\x89\x0a\x24\xcb\x7b\xf9\x3c\xe5\x59\ -\x02\x3e\xe7\xbb\x39\xce\xdb\x66\x78\xc3\xb8\x2c\xc0\x5a\x80\x97\ -\xda\x73\x74\xb1\x00\xb4\xa6\x4f\x4b\xa1\xb3\xc6\x20\x6a\x25\xf5\ -\x3d\x66\x7a\x3f\x6e\x15\x76\x8b\x05\x2d\x50\xf4\xa2\xa1\x28\xe4\ -\x29\xfd\xc6\x63\xb9\x40\x55\x5d\x59\x13\xa2\x97\xde\x90\xb0\x5c\ -\x13\x53\x8d\xca\xf4\x05\x18\x91\xa9\xac\x0c\x98\xe3\x74\x4c\x46\ -\x5e\xc6\x40\x35\x67\x3c\x45\x23\xf8\x37\xf1\x18\xab\x23\xb5\x18\ -\x2e\xd3\x69\x7c\x2b\x39\x8f\xab\xde\x37\x16\xa3\x02\x8e\xa4\x0d\ -\x1c\x2e\x74\xf7\xd2\x65\xc0\x58\x02\x43\x25\xf0\x46\x6d\x35\x04\ -\x42\xcd\x7d\x23\x07\x83\x17\x73\x7d\x0e\xd6\x9d\xd7\x2d\xa0\x79\ -\x1e\xe8\x37\xf2\x82\xc6\xb0\x53\x42\x06\x70\xdc\x0e\x5b\xdd\x3a\ -\x74\x30\xa2\xd2\x93\xb3\xc1\x4e\xb7\x42\x06\x73\xa9\x25\x82\xad\ -\x6e\x85\x13\x0a\xb7\xea\x0a\xaf\x40\xda\x00\x77\x0b\xa4\xab\x61\ -\xa3\x69\xf1\x3c\x25\xa3\x23\xb5\xd7\xcf\x32\x29\x01\xc6\xfc\x90\ -\x29\x59\x02\x32\x1d\x07\x43\x23\x5b\x1a\x51\x9c\xb3\x4b\x9a\x2c\ -\x0e\xaa\xcb\x90\x0a\x04\x3f\x32\x24\x28\x68\x04\x58\x4c\x26\xe8\ -\x03\x04\x19\xe2\xc3\x4f\x40\x8a\x37\x8f\xb5\x86\x13\x5a\x67\xcd\ -\x05\xdd\x57\xc3\x3f\x25\x81\xbb\xd5\xef\x2b\x12\x0e\x6a\xa2\x71\ -\x4a\x48\xec\xf6\xf6\x61\x6b\xcc\x63\x55\x3c\x64\x19\x71\x7b\x4f\ -\x40\xaa\x9f\xaa\xdb\xd6\x30\x75\x33\xaf\x15\xcc\x27\xb1\x4a\x37\ -\x57\x46\x98\x6f\x11\x51\x30\xe9\xdd\x02\x63\x77\x05\x49\x99\x3b\ -\xf7\x64\x78\xbd\xb5\x57\x3c\xc0\x36\xcf\xae\xeb\xf4\x3b\xd8\x30\ -\xe1\x9c\x26\x2b\xe2\x55\x49\x73\x25\xca\x5c\x1b\x61\x82\x20\xf3\ -\x65\x96\x92\x1f\xc7\x9a\xd7\xd0\xff\x2f\xde\xbc\x4f\xde\xbc\x2e\ -\x17\xaf\xc6\x9c\x17\x79\xb4\xdd\x2f\x7d\xf6\xfa\xdd\x25\xf4\xb9\ -\xbb\xbf\x8c\x3e\xf7\x76\x7f\x10\x7d\xce\xb1\xfa\xff\x72\x68\x55\ -\x58\xd1\x55\x1a\x77\x87\x72\xbb\x88\xe2\x9b\x15\xdc\x67\xa7\x47\ -\x88\x46\x09\x4f\xe5\xba\xab\xec\xf5\xd5\xd8\xdb\xab\xd5\xd8\xdb\ -\x77\x4c\x19\x0f\x98\x3c\xf8\xed\xf8\xf5\xd1\xe5\x5f\xe7\x27\xe8\ -\xc5\xe5\xab\x97\xe8\xfc\xdd\xb3\x97\x67\x47\xe8\xc1\x97\x8c\xcb\ -\x83\x36\xc6\x1f\xb6\x8f\x30\x3e\xbe\x3c\x36\x52\xb8\x11\x63\x7c\ -\xf2\xa7\x91\xda\x41\xa1\x94\xc9\x00\xe3\xc9\x64\xd2\x99\x6c\x77\ -\x78\x3a\xc6\x97\x6f\xf1\xdb\x93\xa3\x76\x28\x23\xb6\xd3\xd5\x90\ -\xfb\xb2\x13\xc8\xc0\x8c\x7f\x30\x96\x07\x1b\xca\xb0\x92\xab\x86\ -\x7e\x26\x5e\x90\x3f\xc3\x85\xd7\x33\x9e\x9b\x09\x5f\x60\x7e\xa8\ -\xd6\x60\xcd\xfa\x00\x1c\x24\x0d\x2b\xed\xd9\x5e\x9c\x4f\x17\x72\ -\xc6\x08\x92\xb3\x24\x9f\xaf\xa6\x42\xcc\x8b\x92\xf9\x64\x13\x31\ -\x8a\xfe\x46\x93\x10\xb0\x6e\x6b\x16\x1e\x20\x38\x4a\xed\x49\xea\ -\x25\x07\xe8\x1f\xed\x1f\xd6\x9a\x72\xb5\xb8\xec\xe2\x90\x07\x33\ -\xa4\xc5\xd6\x06\x90\x60\x2c\xdb\x23\x2f\xa2\x6c\x36\x78\x78\x4c\ -\x3e\x79\xef\x33\x74\xe1\xc5\xe2\xa1\x15\xa9\x84\x30\xd8\x4b\xf2\ -\x91\x13\x9d\x34\x06\x3b\xdd\x6e\x2e\x57\xca\x06\x31\x4f\x23\x8f\ -\x1d\xd4\x80\x4a\xaa\xa6\xcc\x9d\xb6\x2d\x79\x32\xe8\x26\xd3\x79\ -\x7b\xc8\x81\xe2\xa3\x4a\x17\x23\x23\x59\xe9\x48\xb5\x55\xdd\xd3\ -\xfe\x22\xdb\x43\xc6\xfd\xcf\x6d\xb8\xd8\x03\x9c\x03\xf0\x44\x21\ -\x35\x6f\xc2\xa0\xc2\x8f\x53\xe0\x78\xc5\xfc\xea\x2c\xa5\x00\x04\ -\xe4\x7b\xc9\xd1\x28\x8b\x7d\x95\xba\x37\x11\x04\x31\xe4\x00\x12\ -\x20\x2f\xd6\x63\x2e\xfc\x90\x44\x1e\x3a\x99\x02\xa8\x42\xa0\x11\ -\x85\x2d\x79\xd4\x21\xd3\xe4\x31\xf2\xbe\x7a\x14\xa2\x16\x3a\x42\ -\x92\x92\x81\xc6\x36\xf9\x2f\xad\x55\xb9\xe1\xa1\x10\x88\xf5\xb0\ -\x11\xe1\x42\x92\x44\xa5\x49\xd1\xf1\x79\x84\x45\x96\x28\x5a\x81\ -\x40\x09\xc8\xd7\x8f\x01\xf7\x05\x26\x66\xc5\x98\x8e\xfc\xad\xe9\ -\xb6\xfd\xf5\x51\xfa\x3d\xb5\xf8\xaa\x0d\x08\xbb\xb8\xba\x5a\xed\ -\x53\x40\x7c\x9e\xea\x8a\x68\x80\x32\xf0\x2f\x65\x34\x26\x07\x26\ -\xd7\x0e\x7e\xef\x77\xf7\x48\xb0\x57\xf2\x76\x7d\xce\xe9\x90\x07\ -\x9f\xe6\x11\xef\xcd\x9f\x92\xf9\x93\x8a\xfc\xe2\x48\xd8\x13\xbc\ -\xbe\xea\xf2\xfb\x56\xe5\x1f\x77\x56\xa3\xd9\x9d\x3b\xd2\x6c\xe9\ -\x44\xe8\x93\x00\xa1\xa8\x37\xf8\xc7\x55\xe5\xcb\x13\xc6\xaf\xaa\ -\x7c\x2d\x55\xf9\x29\xec\xf5\x51\xc8\xb9\x20\x69\xa3\x2a\x57\x71\ -\xe0\x5b\xd9\x9d\x6b\xf2\xf5\xb1\x72\x07\x29\x5d\x8c\xfa\x24\x16\ -\xa0\x59\x69\x13\x3c\x16\x68\x42\x90\x07\x05\x7d\xcc\x25\x82\x0b\ -\x3f\x9f\x80\x2e\xb0\x20\x42\x9a\x80\x61\x4f\x1a\x15\x13\x2a\x43\ -\x74\x0a\x45\xf6\xd1\xd3\xe3\x4d\x24\xb8\xb6\x1b\x65\x42\xa2\x80\ -\x4f\x62\xc6\xbd\x00\x51\xa9\x3a\x53\x41\xd8\xa8\x83\xce\x19\xe0\ -\x5b\x9a\x4f\x81\x06\x79\x54\x1c\x0b\x04\x3f\x6a\x34\x70\x5e\x94\ -\x64\x92\xa4\x9b\xb0\x80\x00\xc1\x64\xb8\x55\xe8\x05\xeb\x69\x2a\ -\x7d\x74\xee\x7e\xc7\xb8\x45\xb5\x7e\x36\xf2\x0d\x74\xff\xcb\x42\ -\x7d\x75\x5a\xed\xdf\x9c\x56\x8b\x2b\x6b\x48\xfc\xcf\xe5\xea\x7e\ -\x7e\x5f\x55\x82\x61\xf1\x56\xfd\xf6\xc7\xe2\x6c\x04\x41\x62\x6e\ -\xab\x5a\x19\x09\x36\x11\xe4\x3a\x50\x10\x8b\x90\x30\x06\x01\x0b\ -\xff\x0d\x09\xca\x84\x89\x67\x1f\xc2\x5d\x12\x14\x11\x10\xc3\xb4\ -\x18\x12\x29\xc4\x2c\x1f\x99\x77\xf4\x2b\xdf\x66\xaf\x4e\x0c\xef\ -\x04\x1c\xde\x91\xff\x1a\x3c\xbb\x50\x9e\xdd\x4b\x34\xc3\xaa\xab\ -\x36\x7f\xce\x98\xbe\x6d\xca\x5b\x9e\xbc\x7f\xa5\xbc\x55\x52\xde\ -\xa2\x62\xa9\xbf\x14\x6f\x12\xab\x2b\x40\x50\x5b\xfe\x10\x8e\xb5\ -\x3b\xf2\x98\x20\x0e\xd6\xcf\x6b\x3c\x6b\x2a\x50\xd5\x61\xbf\xd3\ -\x79\xbb\x43\x34\xae\x56\x14\x5c\xf3\xaa\xee\xbb\xc1\x77\x0d\xaf\ -\xaa\xcc\x1e\x7a\x5f\x49\x95\x4f\x15\x63\x42\x79\xa0\x78\x56\x24\ -\xc4\xa7\xa3\x99\x4e\xce\x3a\x55\x27\x05\xec\x67\xfa\x25\x4c\x27\ -\x99\xdd\x0b\xcd\x95\x3d\xfc\x59\x39\x6e\xcd\x2f\xd8\x2a\x04\x99\ -\xbf\xca\xaa\xfe\x75\xf3\x26\xbc\x58\x50\xe2\x7b\xab\xa3\x42\x88\ -\xcd\xd7\x6a\xb7\xa0\xc1\x2a\x03\x5a\xf2\xdb\x6a\x90\x5f\xce\x7b\ -\x3b\x0d\xde\xab\x50\x5e\xdd\x95\x0a\xd1\x15\x20\x95\x90\x2c\xc1\ -\x68\x0b\xa1\xfc\x65\xb7\xfd\x1a\xe1\xb0\xb5\xdb\xb2\xaf\x18\x0e\ -\x5b\xbd\x5e\x0b\xab\x91\x09\x9d\x46\x5e\x92\x17\xde\xee\x97\x73\ -\xdd\x3e\x4d\x79\xf4\x8a\x46\xe4\x02\x6a\x59\x1f\x8e\x64\x6d\x94\ -\xfa\xb2\x04\x8a\x64\x1e\x19\x8b\x42\x7b\x52\xee\x31\x5e\x96\xbe\ -\x3e\x29\x71\x47\xf1\xc5\x89\xda\x8f\xa9\x24\x71\x20\x5c\xfb\xb5\ -\x09\xec\x86\xed\xd8\x30\x50\xa9\x9b\x81\xd2\x80\x95\x02\xf3\xf9\ -\x49\x27\x74\xb0\x15\x68\x00\xea\x76\x97\x3b\x52\xfa\x7b\xc3\x62\ -\x47\xce\x33\x11\xe6\xf2\xab\x9c\x31\xce\x8a\xd5\x3c\xa9\x51\xea\ -\x42\x6f\x9a\xd8\x5d\xe5\x92\xd2\xb6\x36\xb7\xae\x03\xa9\x89\xe4\ -\xfd\xb8\x65\x0b\xef\xc5\x1b\x57\x48\x57\x77\xa6\xda\xa1\xbf\x8e\ -\x82\x7b\xa7\x3e\x0c\x42\x1f\x1b\x9f\xc7\x31\xd1\x87\xc1\x06\xff\ -\xbc\x6d\xac\x0a\xa2\xde\x7f\xb9\x8d\xab\x01\x1c\x63\x23\x31\xa3\ -\xe8\x38\xf6\x98\x2b\xf9\x78\x0c\x29\xe8\x91\x4a\x7c\x8f\x15\x0b\ -\xe8\x5e\x3d\x22\x25\x3e\xa1\xc0\x77\xae\xad\x4c\xf4\x37\x4f\xa6\ -\xc7\x68\x60\x5c\xba\x40\x44\x27\x26\xab\xce\x55\xa8\x6e\xb3\x7c\ -\x60\x2b\x61\x29\x44\x3d\x9b\xd7\xcb\x2d\xb3\x96\xca\xdf\x6c\x9d\ -\xa9\xfb\x64\x7f\xfe\x61\x96\xfa\x32\xab\xb7\xdf\x2b\xbe\xcd\xc2\ -\x6a\x76\x53\x51\x40\x84\xa4\xb1\x66\xd9\xba\xb6\xed\x27\xbb\x35\ -\x75\x5b\x8b\xd4\x99\x47\x61\xf7\xa1\x82\xe3\xf7\x87\x75\x71\x01\ -\xf3\x7d\x51\xde\xed\xad\x13\xe5\x9d\xdd\x7e\x45\xdd\x56\x77\xa1\ -\xba\xab\x51\x2e\x37\x41\xee\xe0\x8c\xba\x1b\xff\x02\x13\xcc\x10\ -\x82\ +\x00\x23\xb1\x78\x9c\xed\x5a\x6d\x6f\xdb\x36\x10\xfe\x9e\x5f\xc1\ +\x79\x40\xbb\x01\xb1\xe5\xbc\x36\x71\x64\x17\xad\x93\x34\x01\xd2\ +\xd5\xad\xdd\x16\xfb\x14\xc8\x12\x6d\xb1\xa5\x44\x45\xa4\x2a\xbb\ +\xc3\xfe\xfb\x8e\x2f\xb2\x24\xcb\x76\x5e\xec\xb4\x6b\x51\x20\x41\ +\x44\x1e\x79\x77\x7c\x78\x7c\xee\xa8\xc8\x7e\x3e\x09\x28\xfa\x82\ +\x63\x4e\x58\xd8\xae\xed\x34\x9a\x35\x84\x43\x97\x79\x24\x1c\xb7\ +\x6b\xef\x07\xe7\xf5\xa3\xda\xf3\xce\x96\x9d\x90\x7c\xd0\x3e\x0c\ +\xea\x6c\x21\xdb\xa5\x0e\xe7\x9d\x57\x09\x69\xb5\x4e\x89\x43\xd9\ +\x18\xfe\xd2\x71\x1f\x0b\x01\x93\xf9\x8b\xd8\xf5\x6d\x4b\x8f\x81\ +\xc1\x29\xf1\xc6\x58\x20\xd5\x6e\xd7\xde\x7e\x54\xcd\x1a\x0a\x9d\ +\x00\xb7\x6b\xab\x74\x48\x53\xc8\x8e\x62\x16\xe1\x58\x4c\xcd\x84\ +\x31\x66\x01\x16\xf1\x54\x09\x91\x1d\x63\x57\xa8\x27\x64\x4f\x3a\ +\x4d\xdb\x9a\x98\xc6\x54\x36\xa6\xa6\x01\x1e\x08\xbf\x73\xf0\xec\ +\xc0\xb6\xf4\xa3\xee\xf6\x31\x19\xfb\xa2\x73\xb8\x7b\x6c\x5b\xe6\ +\x59\xe9\xb4\x32\xa5\xb6\x95\x19\x5f\xe4\x49\x4a\x42\x8f\xa5\x03\ +\x22\x28\x36\xce\x70\x11\x83\xef\x9d\x57\x38\xc4\xb1\x43\x11\x37\ +\x6b\xb1\x2d\x23\xa8\xaa\xa4\xce\x94\x25\x39\x36\x1f\x5e\xb2\xc9\ +\x95\xea\x32\x1a\xe7\x4c\xf2\xc8\x71\x41\x51\xcd\x2c\x20\x4c\x82\ +\x21\x8e\x3b\x87\xb6\x65\x9e\xb4\xfb\x45\x0b\x15\x15\x81\x13\x8f\ +\x49\x38\xa7\xe1\x78\xa5\x06\x22\x70\x90\x23\x59\xdc\xcb\x57\x31\ +\x4b\x22\xf0\x39\xdb\xcd\x71\xd6\xd6\xc3\x2b\xc6\x45\x0e\xd6\x02\ +\xbc\xe4\x9e\xa3\xfe\x02\xd0\xaa\x3e\xad\x84\xce\x18\x83\xa8\x15\ +\xc4\x75\xa8\xee\xbd\xde\xcd\xed\xe6\x0b\x5a\xa0\xe8\xa2\xa2\xc8\ +\x67\x31\xf9\xca\x42\xb1\x40\xd5\xbc\xb2\x2a\x44\x57\xce\x10\xd3\ +\x4c\x13\x95\x8d\xd2\xf4\x05\x18\xe1\x89\x28\x0d\x98\xe1\x74\x8a\ +\x47\x4e\x42\x41\x35\xa3\x2c\x46\x23\xf8\x4d\x1d\x4a\xe7\x91\x5a\ +\x0c\x97\xee\xd4\xbe\x15\x9c\xb7\xca\xde\x57\x16\x23\x03\x0e\xc7\ +\x15\x1c\xfa\xaa\x7b\xe5\x32\x60\x2c\x86\xa1\x02\x78\x63\x6e\x35\ +\x18\x42\xad\xf3\x56\xb4\x5a\x17\x33\x7d\xb6\xa5\x3a\x6f\x5b\x40\ +\xf5\x3c\x90\xaf\xf8\x82\x84\xb0\x53\x5c\x78\x70\xdc\xda\xb5\xe6\ +\x3c\x74\x30\xa2\xd4\x93\xb1\xc1\x7e\xb3\x44\x06\x33\xa9\x21\x82\ +\xdd\x66\x89\x13\x72\xb7\xe6\x15\x2e\x41\x5a\x03\x77\x0f\xa4\xcb\ +\x61\xa3\x68\xb1\x17\xe3\x51\x57\xee\xf5\xcb\x44\x08\x80\x31\x3b\ +\x64\x52\x16\x81\x4c\xc5\xc1\x50\xcb\x56\x46\x14\x63\x74\x40\xa2\ +\xc5\x41\x35\xf0\x09\x47\xf0\x23\x7c\x8c\xbc\x4a\x80\x85\x38\x45\ +\x1f\x21\xc8\x10\x1b\x7e\x02\x52\xbc\x7b\xac\x55\x9c\x50\x3a\xe7\ +\x5c\x50\x7d\x73\xf8\xc7\xd8\xeb\xec\x1e\x1c\x48\x12\xf6\xe6\x44\ +\xe3\x18\xe3\xb0\xb3\x73\x0c\x5b\xa3\x1f\xcb\xe2\x21\x4d\x70\x67\ +\xe7\x19\x48\xd5\x53\x79\xdb\x2a\xa6\xee\xe6\xb5\x84\xf9\x2c\x94\ +\xe9\x66\x69\x84\xb9\x06\x11\x09\x93\xda\x2d\x30\xf6\x50\x90\xa4\ +\xb9\x9e\x23\xfc\xdb\xad\xbd\x66\x9e\x65\xf2\xec\xa6\x4e\xbf\x6d\ +\x69\x26\x9c\xd1\x64\x49\xbc\x2e\x69\xae\x45\x99\x1b\x23\x4c\x10\ +\x24\xae\x48\x62\xfc\xfd\x58\xf3\x16\xfa\xff\xc5\x9b\xdf\x92\x37\ +\x6f\xcb\xc5\xeb\x31\x67\x3f\x8b\xb6\x6f\x4b\x9f\x3b\x07\xcd\x15\ +\xf4\x79\x78\xbc\x8a\x3e\x8f\x0e\xbf\x13\x7d\xce\xb0\xfa\x79\x39\ +\xb4\x2c\x2c\xe9\x2a\x8c\x7b\x40\xb9\x9d\x47\xf1\xdd\x0a\xee\xcb\ +\xf3\x2e\x22\x41\xc4\x62\xb1\xe9\x2a\x7b\x73\x35\xf6\xde\x7a\x35\ +\xf6\xde\x03\x53\xc6\x13\x2a\x4e\x7e\x3b\x7d\xd3\x1d\xfc\xdd\x3b\ +\x43\x17\x83\xd7\x57\xa8\xf7\xfe\xe5\xd5\x65\x17\x3d\xb9\x49\x98\ +\x38\xa9\x5b\xd6\xc7\xbd\xae\x65\x9d\x0e\x4e\xb5\x14\x6e\xc4\x96\ +\x75\xf6\x97\x96\x9a\x41\xbe\x10\x51\xcb\xb2\xd2\x34\x6d\xa4\x7b\ +\x0d\x16\x8f\xad\xc1\x3b\xeb\xdd\x59\xb7\xee\x8b\x80\xee\x37\x15\ +\xe4\xae\x68\x78\xc2\xd3\xe3\x9f\x8c\xc5\xc9\x96\x34\x2c\xe5\xb2\ +\xa1\x9e\xb1\xe3\x65\xcf\x70\xe1\x75\xb4\xe7\x7a\xc2\x0d\xcc\xf7\ +\xe5\x1a\x8c\x59\x17\x80\x83\xa4\x61\xa4\x3b\xa6\xd7\xca\xa6\x73\ +\x31\xa5\x18\x89\x69\x94\xcd\x97\x53\x21\xe6\x79\xc1\x7c\xb4\x8d\ +\x28\x41\xff\xa0\xd4\x07\xac\xeb\x8a\x85\x5b\x08\x8e\x52\x3d\x8d\ +\x9d\xe8\x04\xfd\xab\xfc\xb3\x94\xa6\x4c\xad\x55\x74\x71\xc8\xbc\ +\x29\x52\x62\x63\x03\x48\x30\x14\xf5\x91\x13\x10\x3a\x6d\x3d\x3d\ +\xc5\x9f\x9c\x0f\x09\xea\x3b\x21\x7f\x6a\x44\x32\x21\xb4\x8e\xa2\ +\x6c\x64\xaa\x92\x46\x6b\xbf\xd9\xcc\xe4\x52\x59\x2b\x64\x71\xe0\ +\xd0\x93\x39\xa0\xa2\xb2\x29\x7d\xa7\xad\x0b\x16\xb5\x9a\xd1\x64\ +\xd6\x1e\x32\xa0\xf8\xa0\xd4\x45\xf1\x48\x94\x3a\x62\x65\x55\xf5\ +\xd4\x6f\x44\x7d\x48\x99\xfb\xb9\x0e\x17\x7b\x80\xb3\x05\x9e\x48\ +\xa4\x66\x4d\x18\x94\xfb\x71\x0e\x1c\x2f\x99\x5f\x9e\xa5\x18\x80\ +\x80\x7c\x2f\x18\x1a\x25\xa1\x2b\x53\xf7\x36\x82\x20\x86\x1c\x80\ +\x3d\xe4\x84\x6a\x4c\xdf\xf5\x71\xe0\xa0\xb3\x09\x80\xca\x39\x1a\ +\x11\xd8\x92\x3f\x1a\x78\x12\xfd\x89\x9c\x2f\x0e\x81\xa8\x85\x0e\ +\x1f\xc7\xb8\xa5\xb0\x8d\xfe\x4f\x6b\x95\x6e\x38\xc8\x07\x62\x6d\ +\x57\x22\x9c\x0b\x1c\xc9\x34\xc9\x1b\x2e\x0b\x2c\x9e\x44\x92\x56\ +\x20\x50\x3c\xfc\xe5\xda\x63\x2e\xb7\xb0\x5e\xb1\x45\x46\xee\xee\ +\x64\xcf\xfc\xb9\x16\xee\x8e\x5c\x7c\xd9\x06\x84\x5d\x58\x5e\xad\ +\xf2\xc9\xc3\x2e\x8b\x55\x45\xd4\x42\x09\xf8\x17\x53\x12\xe2\x13\ +\x9d\x6b\x5b\xbf\x1f\x34\x8f\xb0\x77\x54\xf0\x76\x73\xce\xa9\x90\ +\x07\x9f\x66\x11\xef\xcc\x9e\xa2\xd9\x93\x8c\xfc\xfc\x48\x98\x13\ +\xbc\xb9\xea\xf2\x71\xab\xf2\xeb\xfd\xbb\xd3\x6c\x5e\x5b\xf9\xd8\ +\xfd\x5c\x4c\x43\xb3\xc2\x4a\x0a\x86\xc5\x7c\xb4\x98\x7d\x57\x55\ +\x55\x64\x04\xc7\x4a\x17\x56\x4a\x1d\xf6\xb6\xd5\x39\x83\x6a\x15\ +\xc7\x61\xf6\x96\x48\x9e\xa8\xc8\x89\x39\x9c\xba\x94\xc0\xf5\x74\ +\x88\x51\xc2\xb1\x3c\x81\xc3\x84\x50\x4f\x0f\x32\x45\x17\x1a\xc5\ +\x2c\x40\x9f\x43\x96\xea\x93\x28\x89\x90\x37\x1e\x5e\x8a\x2d\x4f\ +\x1e\xd2\x85\x99\x9f\xb9\x8b\x6b\x54\x7d\x1a\x81\x39\x6b\x43\xc0\ +\xaf\x03\xe5\x12\x86\x52\x4d\x3e\x3e\x66\x59\x06\x4b\xba\x1c\xb9\ +\x3d\xb3\x8e\x1f\xb3\x28\xbb\xef\x05\x6d\x75\xed\xf0\xeb\x82\xb6\ +\xce\x05\x6d\x51\xad\xb6\xff\xc0\x5a\xad\x90\x56\x55\x3a\x85\x7c\ +\xa6\xb6\xe5\x31\xaf\xf6\x4b\x28\xf1\x1c\xec\x77\x7d\xc6\xe0\x94\ +\x54\x58\x51\xfa\xe6\x1a\xd9\x83\x69\x71\x73\xe5\x46\x03\x49\x5d\ +\x94\xb8\x38\xe4\xa0\x59\x6a\xe3\x2c\xe4\x28\xc5\xc8\x81\x9b\x6a\ +\xc8\x04\x72\x28\x65\x29\xe8\x02\x0b\xdc\x27\x11\x18\x76\x84\x56\ +\x91\x12\xe1\xa3\x73\xb8\x3d\x76\x5f\x9c\x6e\x23\xce\x94\xdd\x20\ +\xe1\x02\x79\x40\xaf\x94\x39\x1e\x22\x42\x76\x02\x5f\xd0\x51\x03\ +\xf5\x28\x44\x4b\x61\x3e\x81\xfc\xce\x82\x7c\xab\x10\xfc\xc8\xd1\ +\x90\xcc\x83\x28\x01\xe6\xdc\x86\x05\x78\x08\x26\x03\x73\xab\x05\ +\xab\x69\xb2\x2e\x5a\x83\xb1\xef\xc1\x77\x40\x76\x1a\xba\x1f\x95\ +\xec\x1e\xb9\x5e\x38\x78\x8c\x7a\xe1\xe1\xc7\xe2\x72\x49\xb5\x00\ +\x47\xe0\x4d\x84\xc3\xbe\x8f\xa1\x38\xd0\x57\xdd\x72\xa9\xe0\xa9\ +\x97\x34\x59\x85\x20\x83\xde\x87\xc0\xa3\xd0\x3f\x9c\x96\xeb\x8d\ +\x75\x73\xf8\x72\xfe\x7a\xcf\xcb\x8e\x7e\x93\x00\xd7\x09\xbd\x60\ +\xf3\x27\x0c\xf3\xfb\xbf\x68\x29\x15\x04\xd9\x2b\x8d\xf2\x7f\xb9\ +\xee\x52\x07\xe4\x25\xc0\x07\xa3\xa3\x54\x00\x54\x5f\xaf\xdc\x23\ +\xed\x97\x33\xbe\x49\xf6\xbb\x95\x64\x9f\xe5\xf9\xfd\x4a\x9e\x2f\ +\xa5\xf8\x79\x57\x4a\x89\x3d\x07\xa9\x80\x64\x01\x46\xc3\x1b\xd9\ +\x4b\x4f\xf3\x5f\xe9\x76\xed\xb0\x66\xae\x9a\xed\xda\xce\x4e\xcd\ +\x92\x23\x23\x32\x09\x9c\x28\xcb\x53\x9d\x9b\x9e\x6a\x9f\x43\x45\ +\xfe\x9a\x04\xb8\x0f\xd4\xef\x42\x19\x3b\x37\x4a\x7e\x61\x00\x39\ +\x85\x05\xda\x22\x57\x9e\x14\x7b\xb4\x97\x85\xaf\x10\x0a\xf9\x37\ +\xff\xf2\x40\xee\xc7\x44\xe0\xd0\xe3\x1d\xf3\xd5\x01\xec\x86\xe9\ +\xd8\xd2\x50\xc9\x44\x2a\x35\x58\x52\x81\xfe\x0c\xa1\xe1\xdb\x96\ +\x11\x28\x00\xe6\xed\xae\x76\xa4\xf0\xde\x79\xb1\x23\xbd\x84\xfb\ +\x99\x7c\x99\x33\xda\x59\xbe\x9e\x27\x73\x65\xc9\x42\x6f\xaa\xd8\ +\x2d\x73\x49\x6a\xdb\x98\x5b\xb7\x81\x54\x45\xf2\xdb\xb8\x65\xf2\ +\xd4\xe2\x8d\xcb\xa5\xeb\x3b\x53\xee\x50\x5f\xc9\x40\x99\xa6\x0e\ +\x03\x57\xc7\xc6\x65\x61\x88\xd5\x61\x90\x6d\xdb\x4a\x48\x67\xeb\ +\x3f\x96\xcd\xb4\x36\ \x00\x00\x07\x4c\ \x00\ \x00\x29\xd1\x78\x9c\xed\x59\x5b\x8f\xe2\x46\x16\x7e\xef\x5f\xe1\ @@ -10099,30 +10089,30 @@ qt_resource_struct = "\ \x00\x00\x00\x86\x00\x00\x00\x00\x00\x01\x00\x00\x3e\x30\ \x00\x00\x01\x70\x00\x00\x00\x00\x00\x01\x00\x01\x08\x08\ \x00\x00\x00\x38\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x05\x12\x00\x01\x00\x00\x00\x01\x00\x02\x30\xce\ -\x00\x00\x04\x1e\x00\x00\x00\x00\x00\x01\x00\x01\xf2\xff\ -\x00\x00\x02\xfc\x00\x00\x00\x00\x00\x01\x00\x01\xa4\x8d\ -\x00\x00\x05\xb2\x00\x01\x00\x00\x00\x01\x00\x02\x5c\x60\ -\x00\x00\x04\xe4\x00\x01\x00\x00\x00\x01\x00\x02\x29\xfc\ -\x00\x00\x03\x36\x00\x01\x00\x00\x00\x01\x00\x01\xb2\xfc\ -\x00\x00\x03\x88\x00\x01\x00\x00\x00\x01\x00\x01\xc6\x83\ -\x00\x00\x02\xa0\x00\x01\x00\x00\x00\x01\x00\x01\x89\xed\ -\x00\x00\x04\x5e\x00\x00\x00\x00\x00\x01\x00\x02\x0c\xd9\ -\x00\x00\x02\x7e\x00\x01\x00\x00\x00\x01\x00\x01\x80\xf4\ -\x00\x00\x03\x64\x00\x01\x00\x00\x00\x01\x00\x01\xbc\x54\ -\x00\x00\x02\x34\x00\x01\x00\x00\x00\x01\x00\x01\x70\x4c\ -\x00\x00\x02\x5e\x00\x01\x00\x00\x00\x01\x00\x01\x79\xf4\ -\x00\x00\x04\x8e\x00\x01\x00\x00\x00\x01\x00\x02\x1c\x47\ -\x00\x00\x03\xf4\x00\x00\x00\x00\x00\x01\x00\x01\xe2\x7e\ -\x00\x00\x04\xbc\x00\x01\x00\x00\x00\x01\x00\x02\x21\x97\ -\x00\x00\x05\x3c\x00\x00\x00\x00\x00\x01\x00\x02\x37\xa9\ -\x00\x00\x03\xac\x00\x01\x00\x00\x00\x01\x00\x01\xcb\x9a\ -\x00\x00\x05\x86\x00\x01\x00\x00\x00\x01\x00\x02\x53\xe6\ -\x00\x00\x05\x66\x00\x01\x00\x00\x00\x01\x00\x02\x49\xac\ -\x00\x00\x04\x3e\x00\x01\x00\x00\x00\x01\x00\x02\x06\xc1\ -\x00\x00\x02\xd2\x00\x00\x00\x00\x00\x01\x00\x01\x92\x2f\ -\x00\x00\x03\xd6\x00\x00\x00\x00\x00\x01\x00\x01\xd3\x82\ -\x00\x00\x02\x00\x00\x01\x00\x00\x00\x01\x00\x01\x68\xfc\ +\x00\x00\x05\x12\x00\x01\x00\x00\x00\x01\x00\x02\x30\x32\ +\x00\x00\x04\x1e\x00\x00\x00\x00\x00\x01\x00\x01\xf2\x63\ +\x00\x00\x02\xfc\x00\x00\x00\x00\x00\x01\x00\x01\xa3\xf1\ +\x00\x00\x05\xb2\x00\x01\x00\x00\x00\x01\x00\x02\x5b\xc4\ +\x00\x00\x04\xe4\x00\x01\x00\x00\x00\x01\x00\x02\x29\x60\ +\x00\x00\x03\x36\x00\x01\x00\x00\x00\x01\x00\x01\xb2\x60\ +\x00\x00\x03\x88\x00\x01\x00\x00\x00\x01\x00\x01\xc5\xe7\ +\x00\x00\x02\xa0\x00\x01\x00\x00\x00\x01\x00\x01\x89\x51\ +\x00\x00\x04\x5e\x00\x00\x00\x00\x00\x01\x00\x02\x0c\x3d\ +\x00\x00\x02\x7e\x00\x01\x00\x00\x00\x01\x00\x01\x80\x58\ +\x00\x00\x03\x64\x00\x01\x00\x00\x00\x01\x00\x01\xbb\xb8\ +\x00\x00\x02\x34\x00\x01\x00\x00\x00\x01\x00\x01\x6f\xb0\ +\x00\x00\x02\x5e\x00\x01\x00\x00\x00\x01\x00\x01\x79\x58\ +\x00\x00\x04\x8e\x00\x01\x00\x00\x00\x01\x00\x02\x1b\xab\ +\x00\x00\x03\xf4\x00\x00\x00\x00\x00\x01\x00\x01\xe1\xe2\ +\x00\x00\x04\xbc\x00\x01\x00\x00\x00\x01\x00\x02\x20\xfb\ +\x00\x00\x05\x3c\x00\x00\x00\x00\x00\x01\x00\x02\x37\x0d\ +\x00\x00\x03\xac\x00\x01\x00\x00\x00\x01\x00\x01\xca\xfe\ +\x00\x00\x05\x86\x00\x01\x00\x00\x00\x01\x00\x02\x53\x4a\ +\x00\x00\x05\x66\x00\x01\x00\x00\x00\x01\x00\x02\x49\x10\ +\x00\x00\x04\x3e\x00\x01\x00\x00\x00\x01\x00\x02\x06\x25\ +\x00\x00\x02\xd2\x00\x00\x00\x00\x00\x01\x00\x01\x91\x93\ +\x00\x00\x03\xd6\x00\x00\x00\x00\x00\x01\x00\x01\xd2\xe6\ +\x00\x00\x02\x00\x00\x01\x00\x00\x00\x01\x00\x01\x68\x60\ \x00\x00\x01\xd8\x00\x01\x00\x00\x00\x01\x00\x01\x61\x46\ " diff --git a/src/Mod/Arch/Resources/ui/archprefs-base.ui b/src/Mod/Arch/Resources/ui/archprefs-base.ui index 4d1ad8bdd..b5aa13d49 100644 --- a/src/Mod/Arch/Resources/ui/archprefs-base.ui +++ b/src/Mod/Arch/Resources/ui/archprefs-base.ui @@ -142,9 +142,21 @@ p, li { white-space: pre-wrap; } - + + + if this is checked, the internal Arch IFC parser will be use to build Arch objects from known IFC types. + - IFC Schema file location + use internal IFC parser + + + true + + + useIfcParser + + + Mod/Arch @@ -161,6 +173,13 @@ p, li { white-space: pre-wrap; } + + + + IFC Schema file location + + + @@ -181,10 +200,10 @@ p, li { white-space: pre-wrap; } - If this is checked, ifcopenshell will be used to create meshes instead of Arch objects + If this is checked, the IFCOpenShell importer will be used for objects not handled by the internal parser - Use IfcOpenShell + Use IFCOpenShell useIfcOpenShell @@ -194,45 +213,6 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - Path to IfcOpenShell - - - - - - - false - - - If you have ifcopenshell installed, specify here the path to IfcImport.py - - - ifcopenshell - - - Mod/Arch - - - @@ -283,38 +263,5 @@ p, li { white-space: pre-wrap; } - - - gui::prefcheckbox - toggled(bool) - label_5 - setEnabled(bool) - - - 79 - 191 - - - 376 - 192 - - - - - gui::prefcheckbox - toggled(bool) - gui::preffilechooser_2 - setEnabled(bool) - - - 61 - 191 - - - 465 - 201 - - - - + diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index 347d25071..95ac69c7b 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -21,7 +21,7 @@ #* * #*************************************************************************** -import ifcReader, FreeCAD, Arch, Draft, os, sys, time +import ifcReader, FreeCAD, Arch, Draft, os, sys, time, tempfile from draftlibs import fcvec __title__="FreeCAD IFC importer" @@ -29,6 +29,7 @@ __author__ = "Yorik van Havre" __url__ = "http://free-cad.sourceforge.net" DEBUG = True +pyopen = open # because we'll redefine open below def open(filename): "called when freecad opens a file" @@ -71,52 +72,70 @@ def getSchema(): def getIfcOpenShell(): "locates and imports ifcopenshell" - p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") - p = p.GetString("ifcopenshell") - if p: - try: - sys.path.append(os.path.dirname(p)) - global IfcOpenShell - IfcOpenShell = None - import IfcImport as IfcOpenShell - except: - print "Couldn't import IfcOpenShell" + try: + global IfcImport + import IfcImport + except: + print "Couldn't import IfcOpenShell" + return False + else: + return True def readOpenShell(filename): - import Mesh - getIfcOpenShell() - if IfcOpenShell: - if IfcOpenShell.Init(filename): + "Parses an IFC file with IfcOpenShell" + + if getIfcOpenShell(): + USESHAPES = False + if hasattr(IfcImport,"USE_BREP_DATA"): + IfcImport.Settings(IfcImport.USE_BREP_DATA,True) + USESHAPES = True + if IfcImport.Init(filename): while True: - obj = IfcOpenShell.Get() - print "parsing ",obj.guid,": ",obj.name," of type ",obj.type + + obj = IfcImport.Get() + if DEBUG: print "parsing ",obj.guid,": ",obj.name," of type ",obj.type meshdata = [] n = obj.name if not n: n = "Unnamed" - f = obj.mesh.faces - v = obj.mesh.verts + + if USESHAPES: + + # treat as Parts + import Part + tf = tempfile.mkstemp(suffix=".brp")[1] + of = pyopen(tf,"wb") + of.write(obj.mesh.brep_data) + of.close() + sh = Part.read(tf) + nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) + nobj.Shape = sh + + else: + + # treat as meshes + import Mesh + f = obj.mesh.faces + v = obj.mesh.verts + for i in range(0, len(f), 3): + face = [] + for j in range(3): + vi = f[i+j]*3 + face.append([v[vi],v[vi+1],v[vi+2]]) + meshdata.append(face) + newmesh = Mesh.Mesh(meshdata) + nobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n) + nobj.Mesh = newmesh + + # apply transformation matrix m = obj.matrix - print "verts: ",len(v)," faces: ",len(f) mat = FreeCAD.Matrix(m[0], m[3], m[6], m[9], m[1], m[4], m[7], m[10], m[2], m[5], m[8], m[11], 0, 0, 0, 1) - for i in range(0, len(f), 3): - print "face ",f[i],f[i+1],f[i+2] - face = [] - print "i:",i - for j in range(3): - vi = f[i+j]*3 - print "vi:",vi - face.append([v[vi],v[vi+1],v[vi+2]]) - meshdata.append(face) - newmesh = Mesh.Mesh(meshdata) - mobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n) - mobj.Mesh = newmesh - mobj.Placement = FreeCAD.Placement(mat) - if not IfcOpenShell.Next(): + nobj.Placement = FreeCAD.Placement(mat) + if not IfcImport.Next(): break - IfcOpenShell.CleanUp() + IfcImport.CleanUp() return None def read(filename): From 48c9e2fbe8d4c31536b2c9103544742a9786a475 Mon Sep 17 00:00:00 2001 From: Sebastian Hoogen Date: Sun, 15 Jan 2012 12:01:07 +0100 Subject: [PATCH 3/7] Draft importSVG reimplentation of path and transformation parsing All basic elements besides elliptic arcs and rounded rects are now supported --- src/Mod/Draft/importSVG.py | 585 ++++++++++++++++++------------------- 1 file changed, 285 insertions(+), 300 deletions(-) diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index 7157e659f..af3e3e235 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -27,9 +27,13 @@ __url__ = ["http://free-cad.sourceforge.net"] ''' This script imports SVG files in FreeCAD. Currently only reads the following entities: -paths, lines, arcs ,rects, circles, ellipses, polygons, polylines. -currently unsupported: image, rounded rect(rx,ry), transform attribute?? +paths, lines, circular arcs ,rects, circles, ellipses, polygons, polylines. +currently unsupported: image, rounded rect(rx,ry), elliptical arcs ''' +#ToDo: +# elliptical arc segments +# rounded rects (elliptical arcs) +# ignoring CDATA import xml.sax, string, FreeCAD, os, math, re, Draft from draftlibs import fcvec @@ -229,43 +233,6 @@ def getrgb(color): g = str(hex(int(color[1]*255)))[2:].zfill(2) b = str(hex(int(color[2]*255)))[2:].zfill(2) return "#"+r+g+b - -def splitpathd(pathdstr): - whitespacechars = [' ','\t','\r','\n'] - commandchars = ['m','M','l','L','h','H','v','V','a','A','c','C','q','Q','s','S','t','T','z','Z'] - numberchars = ['e','E','+','-','.','0','1','2','3','4','5','6','7','8','9'] - dlist=[] - currentnumber='' - state='whitespace' - for dchar in pathdstr: - if dchar in commandchars: - if currentnumber: - dlist.append(float(currentnumber)) - currentnumber = '' - dlist.append(dchar) - state='whitespace' - elif state == 'whitespace': - if dchar in whitespacechars: - pass #continue - elif dchar in numberchars: - state = 'number' - currentnumber = dchar - else: - print 'unexpected char %s %d %s' % (dchar,ord(dchar),state) - elif state == 'number': - if dchar in numberchars: - currentnumber += dchar - elif dchar in whitespacechars: - dlist.append(float(currentnumber)) - currentnumber = '' - else: - print 'unexpected char %s %d %s' % (dchar,ord(dchar),state) - #End of string/list - if currentnumber: - dlist.append(float(currentnumber)) - currentnumber = '' - return dlist - class svgHandler(xml.sax.ContentHandler): "this handler parses the svg files and creates freecad objects" @@ -318,12 +285,15 @@ class svgHandler(xml.sax.ContentHandler): content = content.split() data[keyword]=content - if 'style' in data: - content = data['style'][0].replace(' ','') - content = content.split(';') - for i in content: - pair = i.split(':') - if len(pair)>1: data[pair[0]]=pair[1] + if 'style' in data: + if not data['style']: + pass#empty style attribute stops inhertig from parent + else: + content = data['style'][0].replace(' ','') + content = content.split(';') + for i in content: + pair = i.split(':') + if len(pair)>1: data[pair[0]]=pair[1] for k in ['x','y','x1','y1','x2','y2','r','rx','ry','cx','cy','width','height']: if k in data: @@ -351,7 +321,7 @@ class svgHandler(xml.sax.ContentHandler): if data['stroke-width'] != 'none': self.width = getsize(data['stroke-width']) if 'transform' in data: - m = self.getMatrix(data['transform']) + m = self.getMatrix(attrs.getValue('transform')) if name == "g": self.grouptransform.append(m) else: @@ -359,38 +329,7 @@ class svgHandler(xml.sax.ContentHandler): else: if name == "g": self.grouptransform.append(FreeCAD.Matrix()) - - ''' - print "existing grouptransform: ",self.grouptransform - print "existing transform: ",self.transform - if "translate" in tr: - i0 = tr.index("translate") - print "getting translate ",tr - if "translate" in self.transform: - self.transform['translate'] = self.transform['translate'].add(Vector(float(tr[i0+1]),-float(tr[i0+2]),0)) - else: - self.transform['translate'] = Vector(float(tr[i0+1]),-float(tr[i0+2]),0) - if "translate" in self.grouptransform: - print "adding to group ",self.grouptransform['translate'] - self.transform['translate'] = self.grouptransform['translate'].add(self.transform['translate']) - else: - if "translate" in self.grouptransform: - print "adding to group ",self.grouptransform['translate'] - self.transform['translate'] = self.grouptransform['translate'] - if "scale" in tr: - i0 = tr.index("scale") - if "scale" in self.transform: - self.transform['scale'] = self.transform['scale'].add(Vector(float(tr[i0+1]),float(tr[i0+2]),0)) - else: - print tr - self.transform['scale'] = Vector(float(tr[i0+1]),float(tr[i0+2]),0) - if "scale" in self.grouptransform: - self.transform['scale'] = self.transform['scale'].add(self.grouptransform['scale']) - else: - if "scale" in self.grouptransform: - self.transform['scale'] = self.grouptransform['scale'] - ''' - + if (self.style == 1): self.color = self.col self.width = self.lw @@ -415,9 +354,6 @@ class svgHandler(xml.sax.ContentHandler): relative = False firstvec = None - pathdata = splitpathd(' '.join(data['d'])) - # print "debug: pathdata:",pathdata - if "freecad:basepoint1" in data: p1 = data["freecad:basepoint1"] p1 = Vector(float(p1[0]),-float(p1[1]),0) @@ -430,8 +366,9 @@ class svgHandler(xml.sax.ContentHandler): self.format(obj) pathdata = [] self.lastdim = obj - - for d in pathdata: + pathcommandsre=re.compile('\s*?([mMlLhHvVaAcCqQsStTzZ])\s*?([^mMlLhHvVaAcCqQsStTzZ]*)\s*?',re.DOTALL) + for d,pointsstr in pathcommandsre.findall(' '.join(data['d'])): + #for d in pathdata: if (d == "M"): command = "move" relative = False @@ -515,215 +452,241 @@ class svgHandler(xml.sax.ContentHandler): relative = True smooth = True point = [] - else: - try: - point.append(float(d)) - except ValueError: - pass + pointlist = pointsstr.replace(',',' ').split() + while pointlist: + if pointlist: + point.append(float(pointlist.pop(0))) + print "command: ",command, ' point: ',point - print "command: ",command, ' point: ',point - - if (len(point)==2) and (command=="move"): - if path: - sh = Part.Wire(path) - if self.fill: sh = Part.Face(sh) - sh = self.applyTrans(sh) - obj = self.doc.addObject("Part::Feature",pathname) - obj.Shape = sh - self.format(obj) - path = [] - if relative: - lastvec = lastvec.add(Vector(point[0],-point[1],0)) - command="line" - else: - lastvec = Vector(point[0],-point[1],0) - firstvec = lastvec - print "move ",lastvec - command = "line" - lastpole = None - point = [] - elif (len(point)==2) and (command=="line"): - if relative: - currentvec = lastvec.add(Vector(point[0],-point[1],0)) - else: - currentvec = Vector(point[0],-point[1],0) - if not fcvec.equals(lastvec,currentvec): + if (len(point)==2) and (command=="move"): + if path: + sh = Part.Wire(path) + if self.fill: sh = Part.Face(sh) + sh = self.applyTrans(sh) + obj = self.doc.addObject("Part::Feature",pathname) + obj.Shape = sh + self.format(obj) + path = [] + if firstvec: + lastvec = firstvec #Move relative to last move command not last draw command + if relative: + lastvec = lastvec.add(Vector(point[0],-point[1],0)) + command="line" + else: + lastvec = Vector(point[0],-point[1],0) + firstvec = lastvec + print "move ",lastvec + command = "line" + lastpole = None + point = [] + elif (len(point)==2) and (command=="line"): + if relative: + currentvec = lastvec.add(Vector(point[0],-point[1],0)) + else: + currentvec = Vector(point[0],-point[1],0) + if not fcvec.equals(lastvec,currentvec): + seg = Part.Line(lastvec,currentvec).toShape() + print "line ",lastvec,currentvec + lastvec = currentvec + path.append(seg) + lastpole = None + point = [] + elif (len(point)==1) and (command=="horizontal"): + if relative: + currentvec = lastvec.add(Vector(point[0],0,0)) + else: + lasty = path[-1].y + currentvec = Vector(point[0],lasty,0) seg = Part.Line(lastvec,currentvec).toShape() - print "line ",lastvec,currentvec lastvec = currentvec + lastpole = None path.append(seg) - lastpole = None - point = [] - elif (len(point)==1) and (command=="horizontal"): - if relative: - currentvec = lastvec.add(Vector(point[0],0,0)) - else: - lasty = path[-1].y - currentvec = Vector(point[0],lasty,0) - seg = Part.Line(lastvec,currentvec).toShape() - lastvec = currentvec - lastpole = None - path.append(seg) - point = [] - elif (len(point)==1) and (command=="vertical"): - if relative: - currentvec = lastvec.add(Vector(0,-point[0],0)) - else: - lastx = path[-1].x - currentvec = Vector(lastx,-point[0],0) - seg = Part.Line(lastvec,currentvec).toShape() - lastvec = currentvec - lastpole = None - path.append(seg) - point = [] - elif (len(point)==7) and (command=="arc"): - if relative: - currentvec = lastvec.add(Vector(point[-2],-point[-1],0)) - else: - currentvec = Vector(point[-2],-point[-1],0) - chord = currentvec.sub(lastvec) - # perp = chord.cross(Vector(0,0,-1)) - # here is a better way to find the perpendicular - if point[4] == 1: - # clockwise - perp = fcvec.rotate2D(chord,-math.pi/2) - else: - # anticlockwise - perp = fcvec.rotate2D(chord,math.pi/2) - chord = fcvec.scale(chord,.5) - if chord.Length > point[0]: a = 0 - else: a = math.sqrt(point[0]**2-chord.Length**2) - s = point[0] - a - perp = fcvec.scale(perp,s/perp.Length) - midpoint = lastvec.add(chord.add(perp)) - seg = Part.Arc(lastvec,midpoint,currentvec).toShape() - lastvec = currentvec - lastpole = None - path.append(seg) - point = [] - elif (command == "close"): - if not fcvec.equals(lastvec,firstvec): - seg = Part.Line(lastvec,firstvec).toShape() - path.append(seg) - if path: - sh = Part.Wire(path) - if self.fill: sh = Part.Face(sh) - sh = self.applyTrans(sh) - obj = self.doc.addObject("Part::Feature",pathname) - obj.Shape = sh - self.format(obj) - path = [] - point = [] - command = None - - elif (command=="cubic") and (((smooth==False) and (len(point)==6)) or (smooth==True and (len(point)==4))) : - if smooth: - if relative: - currentvec = lastvec.add(Vector(point[2],-point[3],0)) - pole2 = lastvec.add(Vector(point[0],-point[1],0)) - else: - currentvec = Vector(point[2],-point[3],0) - pole2 = Vector(point[0],-point[1],0) - if lastpole is not None and lastpole[0]=='cubic': - pole1 = lastvec.sub(lastpole[1]).add(lastvec) - else: - pole1 = lastvec - else: #not smooth - if relative: - currentvec = lastvec.add(Vector(point[4],-point[5],0)) - pole1 = lastvec.add(Vector(point[0],-point[1],0)) - pole2 = lastvec.add(Vector(point[2],-point[3],0)) - else: - currentvec = Vector(point[4],-point[5],0) - pole1 = Vector(point[0],-point[1],0) - pole2 = Vector(point[2],-point[3],0) - - if not fcvec.equals(currentvec,lastvec): - mainv = currentvec.sub(lastvec) - pole1v = lastvec.add(pole1) - pole2v = currentvec.add(pole2) - print "cubic curve data:",mainv.normalize(),pole1v.normalize(),pole2v.normalize() - if pole1.distanceToLine(lastvec,currentvec) < 10**(-1*Draft.precision()) and pole2.distanceToLine(lastvec,currentvec) < 10**(-1*Draft.precision()): - print "straight segment" - seg = Part.Line(lastvec,currentvec).toShape() + point = [] + elif (len(point)==1) and (command=="vertical"): + if relative: + currentvec = lastvec.add(Vector(0,-point[0],0)) else: - print "cubic bezier segment" - b = Part.BezierCurve() - b.setPoles([lastvec,pole1,pole2,currentvec]) - seg = b.toShape() - print "connect ",lastvec,currentvec - lastvec = currentvec - lastpole = ('cubic',pole2) - path.append(seg) - point = [] - - elif (command=="quadratic") and (((smooth==False) and (len(point)==4)) or (smooth==True and (len(point)==2))) : - if smooth: - if relative: - currentvec = lastvec.add(Vector(point[0],-point[1],0)) - else: - currentvec = Vector(point[0],-point[1],0) - if lastpole is not None and lastpole[0]=='quadratic': - pole1 = lastvec.sub(lastpole[1]).add(lastvec) - else: - pole1 = lastvec - else: #not smooth - if relative: - currentvec = lastvec.add(Vector(point[2],-point[3],0)) - pole1 = lastvec.add(Vector(point[0],-point[1],0)) - else: - currentvec = Vector(point[2],-point[3],0) - pole1 = Vector(point[0],-point[1],0) - - if not fcvec.equals(currentvec,lastvec): - if pole1.distanceToLine(lastvec,currentvec) < 10**(-1*Draft.precision()): - print "straight segment" - seg = Part.Line(lastvec,currentvec).toShape() + lastx = path[-1].x + currentvec = Vector(lastx,-point[0],0) + seg = Part.Line(lastvec,currentvec).toShape() + lastvec = currentvec + lastpole = None + path.append(seg) + point = [] + elif (len(point)==7) and (command=="arc"): + #support for large-arc and x-rotation are missing + rx,ry,xrotation, largeflag, sweepflag = point[0:5] + if relative: + currentvec = lastvec.add(Vector(point[-2],-point[-1],0)) else: - print "quadratic bezier segment" - b = Part.BezierCurve() - b.setPoles([lastvec,pole1,currentvec]) - seg = b.toShape() - print "connect ",lastvec,currentvec - lastvec = currentvec - lastpole = ('quadratic',pole1) - path.append(seg) - point = [] + currentvec = Vector(point[-2],-point[-1],0) + chord = currentvec.sub(lastvec) + # perp = chord.cross(Vector(0,0,-1)) + # here is a better way to find the perpendicular + if sweepflag == 1: + # clockwise + perp = fcvec.rotate2D(chord,-math.pi/2) + else: + # anticlockwise + perp = fcvec.rotate2D(chord,math.pi/2) + chord = fcvec.scale(chord,.5) + if chord.Length > rx: a = 0 + else: a = math.sqrt(rx**2-chord.Length**2) + s = rx - a + perp = fcvec.scale(perp,s/perp.Length) + midpoint = lastvec.add(chord.add(perp)) + seg = Part.Arc(lastvec,midpoint,currentvec).toShape() + lastvec = currentvec + lastpole = None + path.append(seg) + point = [] + elif (command=="cubic") and (((smooth==False) and (len(point)==6)) or (smooth==True and (len(point)==4))) : + if smooth: + if relative: + currentvec = lastvec.add(Vector(point[2],-point[3],0)) + pole2 = lastvec.add(Vector(point[0],-point[1],0)) + else: + currentvec = Vector(point[2],-point[3],0) + pole2 = Vector(point[0],-point[1],0) + if lastpole is not None and lastpole[0]=='cubic': + pole1 = lastvec.sub(lastpole[1]).add(lastvec) + else: + pole1 = lastvec + else: #not smooth + if relative: + currentvec = lastvec.add(Vector(point[4],-point[5],0)) + pole1 = lastvec.add(Vector(point[0],-point[1],0)) + pole2 = lastvec.add(Vector(point[2],-point[3],0)) + else: + currentvec = Vector(point[4],-point[5],0) + pole1 = Vector(point[0],-point[1],0) + pole2 = Vector(point[2],-point[3],0) - if path: - sh = Part.Wire(path) - if self.fill: sh = Part.Face(sh) + if not fcvec.equals(currentvec,lastvec): + mainv = currentvec.sub(lastvec) + pole1v = lastvec.add(pole1) + pole2v = currentvec.add(pole2) + print "cubic curve data:",mainv.normalize(),pole1v.normalize(),pole2v.normalize() + if True and \ + pole1.distanceToLine(lastvec,currentvec) < 20**(-1*Draft.precision()) and \ + pole2.distanceToLine(lastvec,currentvec) < 20**(-1*Draft.precision()): + print "straight segment" + seg = Part.Line(lastvec,currentvec).toShape() + else: + print "cubic bezier segment" + b = Part.BezierCurve() + b.setPoles([lastvec,pole1,pole2,currentvec]) + seg = b.toShape() + print "connect ",lastvec,currentvec + lastvec = currentvec + lastpole = ('cubic',pole2) + path.append(seg) + point = [] + + elif (command=="quadratic") and (((smooth==False) and (len(point)==4)) or (smooth==True and (len(point)==2))) : + if smooth: + if relative: + currentvec = lastvec.add(Vector(point[0],-point[1],0)) + else: + currentvec = Vector(point[0],-point[1],0) + if lastpole is not None and lastpole[0]=='quadratic': + pole1 = lastvec.sub(lastpole[1]).add(lastvec) + else: + pole1 = lastvec + else: #not smooth + if relative: + currentvec = lastvec.add(Vector(point[2],-point[3],0)) + pole1 = lastvec.add(Vector(point[0],-point[1],0)) + else: + currentvec = Vector(point[2],-point[3],0) + pole1 = Vector(point[0],-point[1],0) + + if not fcvec.equals(currentvec,lastvec): + if True and pole1.distanceToLine(lastvec,currentvec) < 20**(-1*Draft.precision()): + print "straight segment" + seg = Part.Line(lastvec,currentvec).toShape() + else: + print "quadratic bezier segment" + b = Part.BezierCurve() + b.setPoles([lastvec,pole1,currentvec]) + seg = b.toShape() + print "connect ",lastvec,currentvec + lastvec = currentvec + lastpole = ('quadratic',pole1) + path.append(seg) + point = [] + + #while pointlist or command: + else: + + if (command == "close"): + if not fcvec.equals(lastvec,firstvec): + seg = Part.Line(lastvec,firstvec).toShape() + path.append(seg) + if path: #the path should be closed by now + sh = Part.Wire(path) + if not sh.isClosed: + #Code from wmayer forum p15549 to fix the tolerance problem + comp=Part.Compound(path) + sh = comp.connectEdgesToWires(False,10**(-1*Draft.precision())).Wires[0] #original tolerance = 0.00001 + if self.fill: sh = Part.Face(sh) + sh = self.applyTrans(sh) + obj = self.doc.addObject("Part::Feature",pathname) + obj.Shape = sh + self.format(obj) + path = [] + if firstvec: + lastvec = firstvec #Move relative to last move command not last draw command + point = [] + command = None + if path: + sh = Part.Wire(path) + if self.fill: sh = Part.Face(sh) sh = self.applyTrans(sh) - obj = self.doc.addObject("Part::Feature",pathname) - obj.Shape = sh - self.format(obj) + obj = self.doc.addObject("Part::Feature",pathname) + obj.Shape = sh + self.format(obj) + # processing rects if name == "rect": if not pathname: pathname = 'Rectangle' - p1 = Vector(data['x'],-data['y'],0) - p2 = Vector(data['x']+data['width'],-data['y'],0) - p3 = Vector(data['x']+data['width'],-data['y']-data['height'],0) - p4 = Vector(data['x'],-data['y']-data['height'],0) - edges = [] - edges.append(Part.Line(p1,p2).toShape()) - edges.append(Part.Line(p2,p3).toShape()) - edges.append(Part.Line(p3,p4).toShape()) - edges.append(Part.Line(p4,p1).toShape()) - sh = Part.Wire(edges) - if self.fill: sh = Part.Face(sh) + edges = [] +# if ('rx' not in data or data['rx'] < 10**(-1*Draft.precision())) and \ +# ('ry' not in data or data['ry'] < 10**(-1*Draft.precision())): #negative values are invalid + if True: + p1 = Vector(data['x'],-data['y'],0) + p2 = Vector(data['x']+data['width'],-data['y'],0) + p3 = Vector(data['x']+data['width'],-data['y']-data['height'],0) + p4 = Vector(data['x'],-data['y']-data['height'],0) + edges.append(Part.Line(p1,p2).toShape()) + edges.append(Part.Line(p2,p3).toShape()) + edges.append(Part.Line(p3,p4).toShape()) + edges.append(Part.Line(p4,p1).toShape()) + else: #rounded edges + rx = data.get('rx') + ry = data.get('ry') or rx + rx = rx or ry + if rx > 2 * data['width']: + rx = data['width'] / 2.0 + if ry > 2 * data['height']: + ry = data['height'] / 2.0 + #TBD + # Part.Ellipse(c,rx,ry).toShape() #needs a proxy object + sh = Part.Wire(edges) + if self.fill: sh = Part.Face(sh) sh = self.applyTrans(sh) - obj = self.doc.addObject("Part::Feature",pathname) - obj.Shape = sh - self.format(obj) + obj = self.doc.addObject("Part::Feature",pathname) + obj.Shape = sh + self.format(obj) # processing lines if name == "line": if not pathname: pathname = 'Line' - p1 = Vector(float(data['x1'][0]),-float(data['y1'][0]),0) - p2 = Vector(float(data['x2'][0]),-float(data['y2'][0]),0) + p1 = Vector(data['x1'],-data['y1'],0) + p2 = Vector(data['x2'],-data['y2'],0) sh = Part.Line(p1,p2).toShape() sh = self.applyTrans(sh) obj = self.doc.addObject("Part::Feature",pathname) @@ -733,6 +696,8 @@ class svgHandler(xml.sax.ContentHandler): # processing polylines and polygons if name == "polyline" or name == "polygon": + '''a simpler implementation would be sh = Part.makePolygon([Vector(svgx,-svgy,0) for svgx,svgy in zip(points[0::2],points[1::2])]) + but there would be more difficlult to search for duplicate points beforehand.''' if not pathname: pathname = 'Polyline' points=[float(d) for d in data['points']] print points @@ -823,9 +788,9 @@ class svgHandler(xml.sax.ContentHandler): if self.transform: vec = self.translateVec(vec,self.transform) print "own transform: ",self.transform, vec - for i in range(len(self.grouptransform)): - #vec = self.translateVec(vec,self.grouptransform[-i-1]) - vec = self.grouptransform[-i-1].multiply(vec) + for transform in self.grouptransform[::-1]: + #vec = self.translateVec(vec,transform) + vec = transform.multiply(vec) print "applying vector: ",vec obj.Position = vec if gui: @@ -846,9 +811,9 @@ class svgHandler(xml.sax.ContentHandler): if self.transform: print "applying object transform: ",self.transform sh = sh.transformGeometry(self.transform) - for i in range(len(self.grouptransform)): - print "applying group transform: ",self.grouptransform[-i-1] - sh = sh.transformGeometry(self.grouptransform[-i-1]) + for transform in self.grouptransform[::-1]: + print "applying group transform: ", transform + sh = sh.transformGeometry(transform) return sh elif Draft.getType(sh) == "Dimension": pts = [] @@ -857,9 +822,9 @@ class svgHandler(xml.sax.ContentHandler): if self.transform: print "applying object transform: ",self.transform cp = self.transform.multiply(cp) - for i in range(len(self.grouptransform)): - print "applying group transform: ",self.grouptransform[-i-1] - cp = self.grouptransform[-i-1].multiply(cp) + for transform in self.grouptransform[::-1]: + print "applying group transform: ",transform + cp = transform.multiply(cp) pts.append(cp) sh.Start = pts[0] sh.End = pts[1] @@ -871,27 +836,47 @@ class svgHandler(xml.sax.ContentHandler): def getMatrix(self,tr): "returns a FreeCAD matrix from a svg transform attribute" - s = "" - for l in tr: - s += l - s += " " - s=s.replace("("," ") - s=s.replace(")"," ") - s = s.strip() - tr = s.split() + transformre=re.compile('(matrix|translate|scale|rotate|skewX|skewY)\s*?\((.*?)\)',re.DOTALL) m = FreeCAD.Matrix() - for i in range(len(tr)): - if tr[i] == 'translate': - vec = Vector(float(tr[i+1]),-float(tr[i+2]),0) - m.move(vec) - elif tr[i] == 'scale': - vec = Vector(float(tr[i+1]),float(tr[i+2]),0) - m.scale(vec) - #elif tr[i] == 'rotate': - # m.rotateZ(float(tr[i+1])) + for transformation, arguments in transformre.findall(tr): + argsplit=[float(arg) for arg in arguments.replace(',',' ').split()] + #m.multiply(FreeCAD.Matrix (1,0,0,0,0,-1)) + print '%s:%s %s %d' % (transformation, arguments,argsplit,len(argsplit)) + if transformation == 'translate': + tx = argsplit[0] + ty = argsplit[1] if len(argsplit) > 1 else 0.0 + m.move(Vector(tx,-ty,0)) + elif transformation == 'scale': + sx = argsplit[0] + sy = argsplit[1] if len(argsplit) > 1 else sx + m.scale(Vector(sx,sy,1)) + elif transformation == 'rotate': + angle = argsplit[0] + if len(argsplit) >= 3: + cx = argsplit[1] + cy = argsplit[2] + m.move(Vector(cx,-cy,0)) + m.rotateZ(math.radians(-angle)) #mirroring one axis equals changing the direction of rotaion + if len(argsplit) >= 3: + m.move(Vector(-cx,cy,0)) + elif transformation == 'skewX': + m=m.multiply(FreeCAD.Matrix(1,-math.tan(math.radians(argsplit[0])))) + elif transformation == 'skewY': + m=m.multiply(FreeCAD.Matrix(1,0,0,0,-math.tan(math.radians(argsplit[0])))) + elif transformation == 'matrix': +# '''transformation matrix: +# FreeCAD SVG +# (+A -C +0 +E) (A C 0 E) +# (-B +D -0 -F) = (-Y) * (B D 0 F) *(-Y) +# (+0 -0 +1 +0) (0 0 1 0) +# (+0 -0 +0 +1) (0 0 0 1)''' + m=m.multiply(FreeCAD.Matrix(argsplit[0],-argsplit[2],0,argsplit[4],-argsplit[1],argsplit[3],0,-argsplit[5])) + else: + print 'SKIPPED %s' % transformation + print "m= ",m print "generating transformation: ",m return m - + def decodeName(name): "decodes encoded strings" try: From 7ad1e83b3a9126416361561f7ecfedbecc7882d5 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 16 Jan 2012 16:08:17 -0200 Subject: [PATCH 4/7] small fix to Arch IFC importer --- src/Mod/Arch/importIFC.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index 95ac69c7b..f81c8a367 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -109,7 +109,8 @@ def readOpenShell(filename): sh = Part.read(tf) nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) nobj.Shape = sh - + os.remove(tf) + else: # treat as meshes From 7fc7ad36e282b8f732c76a3c8b27f94509597844 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 16 Jan 2012 18:59:14 -0200 Subject: [PATCH 5/7] Draft now able to snap perpendicularly to BSplines --- src/Mod/Draft/DraftSnap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Mod/Draft/DraftSnap.py b/src/Mod/Draft/DraftSnap.py index 14d409009..26e0dd0e4 100644 --- a/src/Mod/Draft/DraftSnap.py +++ b/src/Mod/Draft/DraftSnap.py @@ -366,6 +366,9 @@ class Snapper: dv = last.sub(shape.Curve.Center) dv = fcvec.scaleTo(dv,shape.Curve.Radius) np = (shape.Curve.Center).add(dv) + elif isinstance(shape.Curve,Part.BSplineCurve): + pr = shape.Curve.parameter(last) + np = shape.Curve.value(pr) else: return snaps snaps.append([np,'perpendicular',np]) From 632af9810292e269e944d4facb704504fdf8356d Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 16 Jan 2012 19:00:34 -0200 Subject: [PATCH 6/7] Draft offset now works on BSplines --- src/Mod/Draft/Draft.py | 11 ++++++++++- src/Mod/Draft/DraftTools.py | 31 +++++++++++++++++++++++++------ src/Mod/Draft/draftlibs/fcgeo.py | 15 +++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index b6e22cd6e..fcf427afe 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -873,6 +873,8 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): if getType(obj) == "Circle": pass + elif getType(obj) == "BSpline": + pass else: if sym: d1 = delta.multiply(0.5) @@ -923,7 +925,10 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): newobj.Placement = pl elif getType(obj) == "Part": newobj = makeWire(p) - newobj.Closed = obj.Shape.isClosed() + newobj.Closed = obj.Shape.isClosed() + elif getType(obj) == "BSpline": + newobj = makeBSpline(delta) + newobj.Closed = obj.Closed formatObject(newobj,obj) else: if sym: return None @@ -933,6 +938,10 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): obj.Base = None obj.Tool = None obj.Points = p + elif getType(obj) == "BSpline": + print delta + obj.Points = delta + print "done" elif getType(obj) == "Rectangle": length,height,plac = getRect(p,obj) obj.Placement = plac diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 6e21bb347..a416b7d62 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -1651,14 +1651,14 @@ class Modifier: self.extendedCopy = False self.ui.setTitle(name) self.featureName = name - self.snap = snapTracker() - self.extsnap = lineTracker(dotted=True) + #self.snap = snapTracker() + #self.extsnap = lineTracker(dotted=True) self.planetrack = PlaneTracker() def finish(self): self.node = [] - self.snap.finalize() - self.extsnap.finalize() + #self.snap.finalize() + #self.extsnap.finalize() FreeCAD.activeDraftCommand = None if self.ui: self.ui.offUi() @@ -2066,6 +2066,7 @@ class Offset(Modifier): else: self.step = 0 self.dvec = None + self.npts = None self.constrainSeg = None self.ui.offsetUi() self.linetrack = lineTracker() @@ -2080,6 +2081,9 @@ class Offset(Modifier): self.ghost.setCenter(self.center) self.ghost.setStartAngle(math.radians(self.sel.FirstAngle)) self.ghost.setEndAngle(math.radians(self.sel.LastAngle)) + elif Draft.getType(self.sel) == "BSpline": + self.ghost = bsplineTracker(points=self.sel.Points) + self.mode = "BSpline" else: self.ghost = wireTracker(self.shape) self.mode = "Wire" @@ -2116,6 +2120,17 @@ class Offset(Modifier): self.dvec = fcvec.rotate(d,a,plane.axis) occmode = self.ui.occOffset.isChecked() self.ghost.update(fcgeo.offsetWire(self.shape,self.dvec,occ=occmode),forceclosed=occmode) + elif self.mode == "BSpline": + d = fcvec.neg(dist[0]) + e = self.shape.Edges[0] + basetan = fcgeo.getTangent(e,point) + self.npts = [] + for p in self.sel.Points: + currtan = fcgeo.getTangent(e,p) + a = -fcvec.angle(currtan,basetan) + self.dvec = fcvec.rotate(d,a,plane.axis) + self.npts.append(p.add(self.dvec)) + self.ghost.update(self.npts) elif self.mode == "Circle": self.dvec = point.sub(self.center).Length self.ghost.setRadius(self.dvec) @@ -2140,7 +2155,11 @@ class Offset(Modifier): copymode = False occmode = self.ui.occOffset.isChecked() if hasMod(arg,MODALT) or self.ui.isCopy.isChecked(): copymode = True - if self.dvec: + if self.npts: + self.commit(translate("draft","Offset"), + partial(Draft.offset,self.sel, + self.npts,copymode,occ=False)) + elif self.dvec: self.commit(translate("draft","Offset"), partial(Draft.offset,self.sel, self.dvec,copymode,occ=occmode)) @@ -2150,11 +2169,11 @@ class Offset(Modifier): self.finish() def finish(self,closed=False): - Modifier.finish(self) if self.ui and self.running: self.linetrack.finalize() self.constraintrack.finalize() self.ghost.finalize() + Modifier.finish(self) def numericRadius(self,rad): '''this function gets called by the toolbar when diff --git a/src/Mod/Draft/draftlibs/fcgeo.py b/src/Mod/Draft/draftlibs/fcgeo.py index 0c5c95089..275f9a0de 100755 --- a/src/Mod/Draft/draftlibs/fcgeo.py +++ b/src/Mod/Draft/draftlibs/fcgeo.py @@ -842,6 +842,16 @@ def findDistance(point,edge,strict=False): return None else: return dist + elif isinstance(edge.Curve,Part.BSplineCurve): + try: + pr = edge.Curve.parameter(point) + np = edge.Curve.value(pr) + dist = np.sub(point) + except: + print "fcgeo: Unable to get curve parameter for point ",point + return None + else: + return dist else: print "fcgeo: Couldn't project point" return None @@ -933,6 +943,11 @@ def getTangent(edge,frompoint=None): ''' if isinstance(edge.Curve,Part.Line): return vec(edge) + elif isinstance(edge.Curve,Part.BSplineCurve): + if not frompoint: + return None + cp = edge.Curve.parameter(frompoint) + return edge.Curve.tangent(cp)[0] elif isinstance(edge.Curve,Part.Circle): if not frompoint: v1 = edge.Vertexes[0].Point.sub(edge.Curve.Center) From 78b3113b359f8d52b12556fa948ade1b07be33b9 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 16 Jan 2012 19:19:51 -0200 Subject: [PATCH 7/7] fixed bug #544 - allow to make Draft ortho dimensions with shift --- src/Mod/Draft/DraftTools.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index a416b7d62..312e8e59f 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -1367,6 +1367,7 @@ class Dimension(Creator): self.center = None self.arcmode = False self.point2 = None + self.force = None self.constraintrack = lineTracker(dotted=True) msg(translate("draft", "Pick first point:\n")) FreeCADGui.draftToolBar.show() @@ -1501,15 +1502,21 @@ class Dimension(Creator): self.point2 = self.node[1] else: self.node[1] = self.point2 - a=abs(point.sub(self.node[0]).getAngle(plane.u)) - if (a > math.pi/4) and (a <= 0.75*math.pi): + if not self.force: + a=abs(point.sub(self.node[0]).getAngle(plane.u)) + if (a > math.pi/4) and (a <= 0.75*math.pi): + self.force = 1 + else: + self.force = 2 + if self.force == 1: self.node[1] = Vector(self.node[0].x,self.node[1].y,self.node[0].z) - else: + elif self.force == 2: self.node[1] = Vector(self.node[1].x,self.node[0].y,self.node[0].z) self.constraintrack.p1(point) self.constraintrack.p2(ctrlPoint) self.constraintrack.on() else: + self.force = None if self.point2: self.node[1] = self.point2 self.point2 = None