importOCA.py

Go to the documentation of this file.
00001 
00002 #***************************************************************************
00003 #*                                                                         *
00004 #*   Copyright (c) 2009 Yorik van Havre <yorik@gmx.fr>                     * 
00005 #*                                                                         *
00006 #*   This program is free software; you can redistribute it and/or modify  *
00007 #*   it under the terms of the GNU General Public License (GPL)            *
00008 #*   as published by the Free Software Foundation; either version 2 of     *
00009 #*   the License, or (at your option) any later version.                   *
00010 #*   for detail see the LICENCE text file.                                 *
00011 #*                                                                         *
00012 #*   This program is distributed in the hope that it will be useful,       *
00013 #*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014 #*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015 #*   GNU Library General Public License for more details.                  *
00016 #*                                                                         *
00017 #*   You should have received a copy of the GNU Library General Public     *
00018 #*   License along with this program; if not, write to the Free Software   *
00019 #*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
00020 #*   USA                                                                   *
00021 #*                                                                         *
00022 #***************************************************************************
00023 
00024 __title__="FreeCAD Draft Workbench - OCA importer/exporter"
00025 __author__ = "Yorik van Havre <yorik@gmx.fr>"
00026 __url__ = ["http://yorik.orgfree.com","http://free-cad.sourceforge.net"]
00027 
00028 '''
00029 This script imports OCA/gcad files into FreeCAD.
00030 '''
00031 
00032 import FreeCAD, os, Part, math
00033 from draftlibs import fcvec, fcgeo
00034 from FreeCAD import Vector
00035 
00036 try: import FreeCADGui
00037 except ValueError: gui = False
00038 else: gui = True
00039 
00040 pythonopen = open
00041 params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
00042 
00043 def getpoint(data):
00044     "turns an OCA point definition into a FreeCAD Vector"
00045     print "found point ",data
00046     if (len(data) == 3):
00047         return Vector(float(data[0]),float(data[1]),float(data[2]))
00048     elif (data[0] == "P") and (len(data) == 4):
00049         return Vector(float(data[1]),float(data[2]),float(data[3]))
00050     elif (data[0][0] == "P") and (len(data[0]) > 1):
00051         if (len(data) == 1):
00052             return objects[data[0]]
00053         else:
00054             if (data[1][0] == "R"):
00055                 return objects[data[0]].add(objects[data[1]])
00056             elif (data[1][0] == "C"):
00057                 return fcgeo.findProjection(objects[data[0]],objects[data[1]])
00058     elif (data[0][0] == "C"):
00059         if objects[data[0]]:
00060             p1 = objects[data[0]].Curve.Position
00061             if (len(data) == 1):
00062                 return p1
00063             else:
00064                 if (data[1][0] == "L"):
00065                     l = objects[data[1]]
00066                     return p1.add(fcgeo.vec(l))
00067               
00068 def getarea(data):
00069     "turns an OCA area definition into a FreeCAD Part Wire"
00070     print "found area ",data
00071     if (data[0] == "S"):
00072         if (data[1] == "POL"):
00073             pts = data[2:]
00074             verts = []
00075             for p in pts:
00076                 if (p[0] == "P"):
00077                     verts.append(getpoint([p]))
00078             w = Part.makePolygon(verts)
00079             return w
00080 
00081 def getarc(data):
00082     "turns an OCA arc definition into a FreeCAD Part Edge"
00083     print "found arc ", data
00084     c = None
00085     if (data[0] == "ARC"):
00086         # 3-points arc
00087         pts = data[1:]
00088         verts = []
00089         for p in range(len(pts)):
00090             if (pts[p] == "P"):
00091                 verts.append(getpoint(pts[p:p+3]))
00092             elif (pts[p][0] == "P"):
00093                 verts.append(getpoint([pts[p]]))
00094         if verts[0] and verts[1] and verts[2]:
00095             c = Part.Arc(verts[0],verts[1],verts[2])
00096     elif (data[0][0] == "P"):
00097         # 2-point circle
00098         verts = []
00099         rad = None
00100         for p in range(len(data)):
00101             if (data[p] == "P"):
00102                 verts.append(getpoint(data[p:p+4]))
00103             elif (data[p][0] == "P"):
00104                 verts.append(getpoint([data[p]]))
00105             elif (data[p] == "VAL"):
00106                 rad = float(data[p+1])
00107             elif (data[p][0] == "L"):
00108                 lines.append(objects[data[p]])
00109         c = Part.Circle()
00110         c.Center = verts[0]
00111         if rad: c.Radius = rad
00112         else: c.Radius = fcvec.new(verts[0],verts[1]).Length
00113     elif (data[0][0] == "L"):
00114         # 2-lines circle
00115         lines = []
00116         rad = None
00117         for p in range(len(data)):
00118             if (data[p] == "VAL"):
00119                 rad = float(data[p+1])
00120             elif (data[p][0] == "L"):
00121                 lines.append(objects[data[p]])
00122         circles = fcgeo.circleFrom2LinesRadius(lines[0],lines[1],rad)
00123         if circles: c = circles[0]
00124     if c: return c.toShape()
00125 
00126 def getline(data):
00127     print "found line ", data
00128     "turns an OCA line definition into a FreeCAD Part Edge"
00129     verts = []
00130     for p in range(len(data)):
00131         if (data[p] == "P"):
00132             verts.append(getpoint(data[p:p+4]))
00133         elif (data[p][0] == "P"):
00134             verts.append(getpoint([data[p]]))
00135     l = Part.Line(verts[0],verts[1])
00136     return l.toShape()
00137 
00138 def gettranslation(data):
00139     "retrieves a transformation vector"
00140     print "found translation ",data
00141     if (data[0] == "Z"):
00142         return Vector(0,0,float(data[1]))
00143     elif (data[0] == "Y"):
00144         return Vector(0,float(data[1]),0)
00145     elif (data[0] == "X"):
00146         return Vector(float(data[1]),0,0)    
00147     return Vector(0,0,0)
00148 
00149 def writepoint(vector):
00150     "writes a FreeCAD vector in OCA format"
00151     return "P("+str(vector.x)+" "+str(vector.y)+" "+str(vector.z)+")"
00152 
00153 def createobject(id,doc):
00154     "creates an object in the current document"
00155     if isinstance(objects[id],Part.Shape):
00156         ob = doc.addObject("Part::Feature",id)
00157         ob.Shape = objects[id]
00158         if gui: ob.ViewObject.ShapeColor = color
00159 
00160 def parse(filename,doc):
00161     "inports an opened OCA file into the given doc"
00162     filebuffer = pythonopen(filename)
00163     global objects
00164     objects = {}
00165     global color
00166     color = (0,0,0)
00167     for l in filebuffer:
00168         readline = l.replace(","," ").upper()
00169         if ("=" in readline):
00170             # entity definitions
00171             pair = readline.split("=")
00172             id = pair[0]
00173             data = pair[1]
00174             data = data.replace(","," ")
00175             data = data.replace("("," ")
00176             data = data.replace(")"," ")
00177             data = data.split()
00178             if id[0] == "P":
00179                 # point
00180                 objects[id] = getpoint(data)
00181             elif ((id[0] == "A") and params.GetBool("ocaareas")):
00182                 # area
00183                 objects[id] = getarea(data)
00184                 createobject(id,doc)
00185 
00186             elif id[0] == "C":
00187                 # arc or circle
00188                 objects[id] = getarc(data)
00189                 createobject(id,doc)
00190 
00191             elif id[0] == "L":
00192                 # line
00193                 objects[id] = getline(data)
00194                 createobject(id,doc)
00195                 
00196             elif id[0] == "R":
00197                 # translation
00198                 objects[id] = gettranslation(data)
00199 
00200         elif (readline[0:6] == "DEFCOL"):
00201             # color
00202             c = readline.split()
00203             color = (float(c[1])/255,float(c[2])/255,float(c[3])/255)
00204 
00205     del color
00206 
00207 def decodeName(name):
00208     "decodes encoded strings"
00209     try:
00210         decodedName = (name.decode("utf8"))
00211     except UnicodeDecodeError:
00212         try:
00213             decodedName = (name.decode("latin1"))
00214         except UnicodeDecodeError:
00215             print "oca: error: couldn't determine character encoding"
00216             decodedName = name
00217     return decodedName
00218     
00219 def open(filename):
00220     docname=os.path.split(filename)[1]
00221     doc=FreeCAD.newDocument(docname)
00222     if (docname[-4:] == "gcad"): doc.Label = decodeName(docname[:-5])
00223     else: doc.Label = decodeName(docname[:-4])
00224     parse(filename,doc)
00225     doc.recompute()
00226 
00227 def insert(filename,docname):
00228     try:
00229         doc=FreeCAD.getDocument(docname)
00230     except:
00231         doc=FreeCAD.newDocument(docname)
00232     parse(filename,doc)
00233     doc.recompute()
00234             
00235 def export(exportList,filename):
00236     "called when freecad exports a file"
00237     faces = []
00238     edges = []
00239     
00240     # getting faces and edges
00241     for ob in exportList:
00242         if ob.Shape.Faces:
00243             for f in ob.Shape.Faces:
00244                 faces.append(f)
00245         else:
00246             for e in ob.Shape.Edges:
00247                 edges.append(e)
00248     if not (edges or faces):
00249         print "oca: found no data to export"
00250         return
00251     
00252     # writing file
00253     oca = pythonopen(filename,'wb')
00254     oca.write("#oca file generated from FreeCAD\r\n")
00255     oca.write("# edges\r\n")
00256     count = 1
00257     for e in edges:
00258         if isinstance(e.Curve,Part.Line):
00259             oca.write("L"+str(count)+"=")
00260             oca.write(writepoint(e.Vertexes[0].Point))
00261             oca.write(" ")
00262             oca.write(writepoint(e.Vertexes[-1].Point))
00263             oca.write("\r\n")
00264         elif isinstance(e.Curve,Part.Circle):
00265             if (len(e.Vertexes) > 1):
00266                 oca.write("C"+str(count)+"=ARC ")
00267                 oca.write(writepoint(e.Vertexes[0].Point))
00268                 oca.write(" ")
00269                 oca.write(writepoint(fcgeo.findMidpoint(e)))
00270                 oca.write(" ")
00271                 oca.write(writepoint(e.Vertexes[-1].Point))
00272             else:
00273                 oca.write("C"+str(count)+"= ")
00274                 oca.write(writepoint(e.Curve.Center))
00275                 oca.write(" ")
00276                 oca.write(str(e.Curve.Radius))
00277             oca.write("\r\n")
00278         count += 1
00279     oca.write("# faces\r\n")
00280     for f in faces:
00281         oca.write("A"+str(count)+"=S(POL")
00282         for v in f.Vertexes:
00283             oca.write(" ")
00284             oca.write(writepoint(v.Point))
00285         oca.write(" ")
00286         oca.write(writepoint(f.Vertexes[0].Point))
00287         oca.write(")\r\n")
00288         count += 1
00289 
00290     # closing
00291     oca.close()
00292     FreeCAD.Console.PrintMessage("successfully exported "+filename)
00293     
00294         
00295             
00296             
00297         
00298     
00299             
00300                 
00301                 
00302             
00303         
00304 
00305         
00306     

Generated on Wed Nov 23 19:00:18 2011 for FreeCAD by  doxygen 1.6.1