From d930184b57c97cb60e0988e18bb82ac8df37758a Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Mon, 7 Aug 2017 17:47:14 -0700 Subject: [PATCH] Add support for exporting part mesh to JSON --- src/Mod/Arch/CMakeLists.txt | 1 + src/Mod/Arch/Init.py | 1 + src/Mod/Arch/importJSON.py | 104 ++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 src/Mod/Arch/importJSON.py diff --git a/src/Mod/Arch/CMakeLists.txt b/src/Mod/Arch/CMakeLists.txt index f0ecc73ef1..1f40145ba3 100644 --- a/src/Mod/Arch/CMakeLists.txt +++ b/src/Mod/Arch/CMakeLists.txt @@ -24,6 +24,7 @@ SET(Arch_SRCS ArchRoof.py ArchStairs.py importWebGL.py + importJSON.py ArchSpace.py ArchRebar.py TestArch.py diff --git a/src/Mod/Arch/Init.py b/src/Mod/Arch/Init.py index cd145d1a8e..10fc0bd968 100644 --- a/src/Mod/Arch/Init.py +++ b/src/Mod/Arch/Init.py @@ -27,6 +27,7 @@ FreeCAD.addExportType("Industry Foundation Classes (*.ifc)","importIFC") FreeCAD.addImportType("Wavefront OBJ - Arch module (*.obj)","importOBJ") FreeCAD.addExportType("Wavefront OBJ - Arch module (*.obj)","importOBJ") FreeCAD.addExportType("WebGL file (*.html)","importWebGL") +FreeCAD.addExportType("JavaScript Object Notation (*.json)","importJSON") FreeCAD.addImportType("Collada (*.dae)","importDAE") FreeCAD.addExportType("Collada (*.dae)","importDAE") FreeCAD.addImportType("3D Studio mesh (*.3ds)","import3DS") diff --git a/src/Mod/Arch/importJSON.py b/src/Mod/Arch/importJSON.py new file mode 100644 index 0000000000..79eae80a48 --- /dev/null +++ b/src/Mod/Arch/importJSON.py @@ -0,0 +1,104 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2017 * +#* Joseph Coffland * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* This program is distributed in the hope that it will be useful, * +#* but WITHOUT ANY WARRANTY; without even the implied warranty of * +#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +#* GNU Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +"""FreeCAD JSON exporter""" + +import FreeCAD, Mesh, Draft, Part +import json + +if FreeCAD.GuiUp: + import FreeCADGui + from DraftTools import translate + +else: + FreeCADGui = None + def translate(ctxt, txt): return txt + + +if open.__module__ == '__builtin__': pythonopen = open + + +def export(exportList, filename): + "exports the given objects to a .json file" + + # Convert objects + data = { + 'version': '0.0.1', + 'description': 'Mesh data exported from FreeCAD', + 'objects': [getObjectData(obj) for obj in exportList] + } + + # Write file + outfile = pythonopen(filename, "wb") + json.dump(data, outfile, separators = (',', ':')) + outfile.close() + + # Success + FreeCAD.Console.PrintMessage( + translate("Arch", "successfully written ") + filename + "\n") + + +def getObjectData(obj): + result = {'name': str(obj.Label.encode("utf8"))} + if hasattr(obj, "Description"): result['description'] = str(obj.Description) + + if FreeCADGui: + result['color'] = \ + Draft.getrgb(obj.ViewObject.ShapeColor, testbw = False) + + if obj.isDerivedFrom("Part::Feature"): + mesh = Mesh.Mesh(obj.Shape.tessellate(0.1)) + + # Add wires + wires = [] + for f in obj.Shape.Faces: + for w in f.Wires: + wo = Part.Wire(Part.__sortEdges__(w.Edges)) + wires.append([[v.x, v.y, v.z] + for v in wo.discretize(QuasiDeflection = 0.1)]) + + result['wires'] = wires + + elif obj.isDerivedFrom("Mesh::Feature"): mesh = obj.Mesh + + # Add vertices + count = 0 + vertices = [] + vIndex = {} + + for p in mesh.Points: + v = p.Vector + vIndex[p.Index] = count + count += 1 + vertices.append([v.x, v.y, v.z]) + + result['vertices'] = vertices + + # Add facets & normals + facets = [[vIndex[i] for i in f.PointIndices] for f in mesh.Facets] + normals = [[f.Normal.x, f.Normal.y, f.Normal.z] for f in mesh.Facets] + + result['normals'] = normals + result['facets'] = facets + + return result