Download src/Mod/Draft/importOCA.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 13.3 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Draft/importOCA.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Draft/importOCA.py
-
curl -L -o importOCA.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Draft/importOCA.py
13.3 kB
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # -*- coding: utf8 -*- | |
| ## @package importOCA | |
| # \ingroup DRAFT | |
| # \brief OCA (Open CAD Format) file importer & exporter | |
| """@package importOCA | |
| OCA (Open CAD Format) file importer & exporter | |
| This module provides support for importing from and exporting to | |
| the OCA format or GCAD format from GCAD3D (http://www.gcad3d.org/). | |
| See: https://groups.google.com/forum/#!forum/open_cad_format | |
| As of 2019 this file format is practically obsolete, and this module is not | |
| maintained. | |
| """ | |
| # Check code with | |
| # flake8 --ignore=E226,E266,E401,W503 | |
| # *************************************************************************** | |
| # * Copyright (c) 2009 Yorik van Havre <yorik@uncreated.net> * | |
| # * * | |
| # * 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 * | |
| # * * | |
| # *************************************************************************** | |
| __title__ = "FreeCAD Draft Workbench - OCA importer/exporter" | |
| __author__ = "Yorik van Havre <yorik@uncreated.net>" | |
| __url__ = "https://www.freecad.org" | |
| import FreeCAD, os, Part, DraftVecUtils, DraftGeomUtils | |
| from FreeCAD import Vector | |
| from FreeCAD import Console as FCC | |
| from draftutils import params | |
| from draftutils.utils import pyopen | |
| if FreeCAD.GuiUp: | |
| from draftutils.translate import translate | |
| else: | |
| def translate(context, txt): | |
| return txt | |
| def getpoint(data): | |
| """Turn an OCA point definition into a FreeCAD.Vector. | |
| Parameters | |
| ---------- | |
| data : list | |
| Different types of data. | |
| Returns | |
| ------- | |
| Base::Vector3 | |
| A vector with the data arranged, depending on the contents of `data`. | |
| """ | |
| FCC.PrintMessage("found point %s \n" % data) | |
| if len(data) == 3: | |
| return Vector(float(data[0]), float(data[1]), float(data[2])) | |
| elif (data[0] == "P") and (len(data) == 4): | |
| return Vector(float(data[1]), float(data[2]), float(data[3])) | |
| elif (data[0][0] == "P") and (len(data[0]) > 1): | |
| if len(data) == 1: | |
| return objects[data[0]] | |
| else: | |
| if data[1][0] == "R": | |
| return objects[data[0]].add(objects[data[1]]) | |
| elif data[1][0] == "C": | |
| # Error: DraftGeomUtils.findProjection() | |
| # doesn't exist | |
| return DraftGeomUtils.findProjection(objects[data[0]], objects[data[1]]) | |
| elif data[0][0] == "C": | |
| if objects[data[0]]: | |
| p1 = objects[data[0]].Curve.Position | |
| if len(data) == 1: | |
| return p1 | |
| else: | |
| if data[1][0] == "L": | |
| L = objects[data[1]] | |
| return p1.add(DraftGeomUtils.vec(L)) | |
| def getarea(data): | |
| """Turn an OCA area definition into a FreeCAD Part.Wire. | |
| Parameters | |
| ---------- | |
| data : list | |
| Different types of data. | |
| Returns | |
| ------- | |
| Part.Wire | |
| A wire object from the points in `data`. | |
| """ | |
| FCC.PrintMessage("found area %s \n" % data) | |
| if data[0] == "S": | |
| if data[1] == "POL": | |
| pts = data[2:] | |
| verts = [] | |
| for p in pts: | |
| if p[0] == "P": | |
| verts.append(getpoint([p])) | |
| w = Part.makePolygon(verts) | |
| return w | |
| def getarc(data): | |
| """Turn an OCA arc definition into a FreeCAD Part.Edge. | |
| Parameters | |
| ---------- | |
| data : list | |
| Different types of data. | |
| Returns | |
| ------- | |
| Part.Edge | |
| An edge object from the points in `data`. | |
| """ | |
| FCC.PrintMessage("found arc %s \n" % data) | |
| c = None | |
| if data[0] == "ARC": | |
| # 3-points arc | |
| pts = data[1:] | |
| verts = [] | |
| for p in range(len(pts)): | |
| if pts[p] == "P": | |
| verts.append(getpoint(pts[p : p + 3])) | |
| elif pts[p][0] == "P": | |
| verts.append(getpoint([pts[p]])) | |
| if verts[0] and verts[1] and verts[2]: | |
| c = Part.Arc(verts[0], verts[1], verts[2]) | |
| elif data[0][0] == "P": | |
| # 2-point circle | |
| verts = [] | |
| rad = None | |
| lines = [] | |
| for p in range(len(data)): | |
| if data[p] == "P": | |
| verts.append(getpoint(data[p : p + 4])) | |
| elif data[p][0] == "P": | |
| verts.append(getpoint([data[p]])) | |
| elif data[p] == "VAL": | |
| rad = float(data[p + 1]) | |
| elif data[p][0] == "L": | |
| lines.append(objects[data[p]]) | |
| c = Part.Circle() | |
| c.Center = verts[0] | |
| if rad: | |
| c.Radius = rad | |
| else: | |
| # Error: DraftVecUtils.new() | |
| # doesn't exist | |
| c.Radius = DraftVecUtils.new(verts[0], verts[1]).Length | |
| elif data[0][0] == "L": | |
| # 2-lines circle | |
| lines = [] | |
| rad = None | |
| for p in range(len(data)): | |
| if data[p] == "VAL": | |
| rad = float(data[p + 1]) | |
| elif data[p][0] == "L": | |
| lines.append(objects[data[p]]) | |
| circles = DraftGeomUtils.circleFrom2LinesRadius(lines[0], lines[1], rad) | |
| if circles: | |
| c = circles[0] | |
| if c: | |
| return c.toShape() | |
| def getline(data): | |
| """Turns an OCA line definition into a FreeCAD Part.Edge. | |
| Parameters | |
| ---------- | |
| data : list | |
| Different types of data. | |
| Returns | |
| ------- | |
| Part.Edge | |
| An edge object from the points in `data`. | |
| """ | |
| FCC.PrintMessage("found line %s \n" % data) | |
| verts = [] | |
| for p in range(len(data)): | |
| if data[p] == "P": | |
| verts.append(getpoint(data[p : p + 4])) | |
| elif data[p][0] == "P": | |
| verts.append(getpoint([data[p]])) | |
| L = Part.LineSegment(verts[0], verts[1]) | |
| return L.toShape() | |
| def gettranslation(data): | |
| """Retrieve a translation (move) vector from `data`. | |
| Parameters | |
| ---------- | |
| data : list | |
| Different types of data. | |
| Returns | |
| ------- | |
| Base::Vector3 | |
| A vector with X, Y, or Z displacement, or (0, 0, 0). | |
| """ | |
| FCC.PrintMessage("found translation %s \n" % data) | |
| if data[0] == "Z": | |
| return Vector(0, 0, float(data[1])) | |
| elif data[0] == "Y": | |
| return Vector(0, float(data[1]), 0) | |
| elif data[0] == "X": | |
| return Vector(float(data[1]), 0, 0) | |
| return Vector(0, 0, 0) | |
| def writepoint(vector): | |
| """Write a FreeCAD.Vector in OCA format. | |
| Parameters | |
| ---------- | |
| vector : Base::Vector3 | |
| A vector with three components. | |
| Returns | |
| ------- | |
| str | |
| A string "P(X Y Z)" with the information from `vector`. | |
| """ | |
| return "P(" + str(vector.x) + " " + str(vector.y) + " " + str(vector.z) + ")" | |
| def createobject(oid, doc): | |
| """Create Part::Feature object in the current document. | |
| Parameters | |
| ---------- | |
| oid : str | |
| ID number of a particular object in the document. | |
| doc : App::Document | |
| A FreeCAD document to which the object is added. | |
| Returns | |
| ------- | |
| None | |
| """ | |
| if isinstance(objects[oid], Part.Shape): | |
| ob = doc.addObject("Part::Feature", oid) | |
| ob.Shape = objects[oid] | |
| if FreeCAD.GuiUp: | |
| ob.ViewObject.ShapeColor = color | |
| def parse(filename, doc): | |
| """Import an opened OCA file into the given document. | |
| Parameters | |
| ---------- | |
| filename : str | |
| The path to the OCA file. | |
| doc : App::Document | |
| A FreeCAD document to which the object is added. | |
| Returns | |
| ------- | |
| None | |
| """ | |
| filebuffer = pyopen(filename) | |
| global objects | |
| objects = {} | |
| global color | |
| color = (0, 0, 0) | |
| for l in filebuffer: | |
| readline = l.replace(",", " ").upper() | |
| if "=" in readline: | |
| # entity definitions | |
| pair = readline.split("=") | |
| _id = pair[0] | |
| data = pair[1] | |
| data = data.replace(",", " ") | |
| data = data.replace("(", " ") | |
| data = data.replace(")", " ") | |
| data = data.split() | |
| if _id[0] == "P": | |
| # point | |
| objects[_id] = getpoint(data) | |
| elif (_id[0] == "A") and params.get_param("ocaareas"): | |
| # area | |
| objects[_id] = getarea(data) | |
| createobject(_id, doc) | |
| elif _id[0] == "C": | |
| # arc or circle | |
| objects[_id] = getarc(data) | |
| createobject(_id, doc) | |
| elif _id[0] == "L": | |
| # line | |
| objects[_id] = getline(data) | |
| createobject(_id, doc) | |
| elif _id[0] == "R": | |
| # translation | |
| objects[_id] = gettranslation(data) | |
| elif readline[0:6] == "DEFCOL": | |
| # color | |
| c = readline.split() | |
| color = (float(c[1]) / 255, float(c[2]) / 255, float(c[3]) / 255) | |
| def open(filename): | |
| """Open filename and parse. | |
| Parameters | |
| ---------- | |
| filename : str | |
| The path to the filename to be opened. | |
| Returns | |
| ------- | |
| None | |
| """ | |
| docname = os.path.split(filename)[1] | |
| doc = FreeCAD.newDocument(docname) | |
| if docname[-4:] == "gcad": | |
| doc.Label = docname[:-5] | |
| else: | |
| doc.Label = docname[:-4] | |
| parse(filename, doc) | |
| doc.recompute() | |
| def insert(filename, docname): | |
| """Get an active document and parse. | |
| If no document exist, it is created. | |
| Parameters | |
| ---------- | |
| filename : str | |
| The path to the filename to be opened. | |
| docname : str | |
| The name of the active App::Document if one exists, or | |
| of the new one created. | |
| Returns | |
| ------- | |
| None | |
| """ | |
| try: | |
| doc = FreeCAD.getDocument(docname) | |
| except NameError: | |
| doc = FreeCAD.newDocument(docname) | |
| FreeCAD.ActiveDocument = doc | |
| parse(filename, doc) | |
| doc.recompute() | |
| def export(exportList, filename): | |
| """Export the OCA file with a given list of objects. | |
| The objects must be edges or faces, in order to be processed | |
| and exported. | |
| Parameters | |
| ---------- | |
| exportList : list | |
| List of document objects to export. | |
| filename : str | |
| Path to the new file. | |
| Returns | |
| ------- | |
| None | |
| If `exportList` doesn't have shapes to export. | |
| """ | |
| faces = [] | |
| edges = [] | |
| # getting faces and edges | |
| for ob in exportList: | |
| if ob.Shape.Faces: | |
| for f in ob.Shape.Faces: | |
| faces.append(f) | |
| else: | |
| for e in ob.Shape.Edges: | |
| edges.append(e) | |
| if not (edges or faces): | |
| FCC.PrintMessage(translate("importOCA", "OCA: found no data to export") + "\n") | |
| return | |
| # writing file | |
| oca = pyopen(filename, "w") | |
| oca.write("#oca file generated from FreeCAD\r\n") | |
| oca.write("# edges\r\n") | |
| count = 1 | |
| for e in edges: | |
| if DraftGeomUtils.geomType(e) == "Line": | |
| oca.write("L" + str(count) + "=") | |
| oca.write(writepoint(e.Vertexes[0].Point)) | |
| oca.write(" ") | |
| oca.write(writepoint(e.Vertexes[-1].Point)) | |
| oca.write("\r\n") | |
| elif DraftGeomUtils.geomType(e) == "Circle": | |
| if len(e.Vertexes) > 1: | |
| oca.write("C" + str(count) + "=ARC ") | |
| oca.write(writepoint(e.Vertexes[0].Point)) | |
| oca.write(" ") | |
| oca.write(writepoint(DraftGeomUtils.findMidpoint(e))) | |
| oca.write(" ") | |
| oca.write(writepoint(e.Vertexes[-1].Point)) | |
| else: | |
| oca.write("C" + str(count) + "= ") | |
| oca.write(writepoint(e.Curve.Center)) | |
| oca.write(" ") | |
| oca.write(str(e.Curve.Radius)) | |
| oca.write("\r\n") | |
| count += 1 | |
| oca.write("# faces\r\n") | |
| for f in faces: | |
| oca.write("A" + str(count) + "=S(POL") | |
| for v in f.Vertexes: | |
| oca.write(" ") | |
| oca.write(writepoint(v.Point)) | |
| oca.write(" ") | |
| oca.write(writepoint(f.Vertexes[0].Point)) | |
| oca.write(")\r\n") | |
| count += 1 | |
| # closing | |
| oca.close() | |
| FCC.PrintMessage(translate("importOCA", "successfully exported") + " " + filename + "\n") | |