Created
March 23, 2012 15:51
-
-
Save 5263/2172054 to your computer and use it in GitHub Desktop.
Mirror of Exporter of OpenSCAD CSG files for FreeCAD by Keith Sloan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | |
<title>Untitled Document</title> | |
</head> | |
<frameset rows="*" cols="147,*" framespacing="0" frameborder="no" border="0"> | |
<frame src="../menu.html" name="leftFrame" scrolling="No" noresize="noresize" id="leftFrame" /> | |
<frame src="Export_main.html" name="mainFrame" id="mainFrame" /> | |
</frameset> | |
<noframes><body> | |
</body> | |
</noframes></html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | |
<title>RepRap</title> | |
<style type="text/css"> | |
<!-- | |
body { | |
background-image: url(../images/Background.gif); | |
} | |
.style1 {color: #660033} | |
--> | |
</style></head> | |
<body> | |
<div align="center"> | |
<p align="center"><img src="../images/Export_NBanner.gif" width="383" height="70" /></p> | |
<h3 align="center" class="style1"> </h3> | |
<h3 align="center" class="style1">Exporter of OpenSCAD CSG files for FreeCAD</h3> | |
<p align="center" class="style1"><strong>Version 0.1c<br /> | |
<br /> | |
</strong>This is an early version and only supports a limited amount of FreeCAD function.<br /> | |
More function will be added over time so please check back for latest version<br /> | |
. <br /> | |
To install the following python scipts must be placed in <br /> | |
Windows : | |
C:\Program Files\FreeCAD0.12\Mod\Draft<br /> | |
Linux : /usr/lib/freecad/Mod/Draft </p> | |
<p align="center" class="style1"><a href="exportCSG.py">exportCSG.py</a></p> | |
<p align="center" class="style1"> : | |
The InitGui script in the above directory must be altered to add the following line</p> | |
<p align="center" class="style1">App.addExportType("CSG Format (*.csg)","exportCSG") </p> | |
<p align="center" class="style1">As CSG files are a subset of OpenSCAD scad file you may also want to add<br /> | |
the following as this well. This then make it easier to load the csg file directly into OpenSCAD <br /> | |
<br /> | |
App.addExportType("SCADFormat (*.scad)","exportCSG")</p> | |
<p align="center" class="style1"><a href="Versions.txt">Version History</a> </p> | |
<p align="center" class="style1"> </p> | |
<h3 align="center"><a href="Alibre-Mendel.zip" onClick="javascript: pageTracker._trackPageview('/downloads/Alibre-Mendal');"></a></h3> | |
<script type="text/javascript"> | |
</script> | |
</a> | |
<script type="text/javascript">var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); | |
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); | |
</script> | |
<script type="text/javascript"> | |
try { | |
var pageTracker = _gat._getTracker("UA-5880034-6"); | |
pageTracker._trackPageview(); | |
} catch(err) {}</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#*************************************************************************** | |
#* * | |
#* Copyright (c) 2012 Keith Sloan <[email protected]> * | |
#* * | |
#* This program is free software; you can redistribute it and/or modify * | |
#* it under the terms of the GNU General Public License (GPL) * | |
#* 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 * | |
#* * | |
#* Acknowledgements : * | |
#* * | |
#* Thanks to shoogen on the FreeCAD forum for programming advice * | |
#* and some code. * | |
#* * | |
#*************************************************************************** | |
__title__="FreeCAD Draft Workbench - CSG exporter Version 0.01c" | |
__author__ = "Keith Sloan <[email protected]>" | |
__url__ = ["http://www.sloan-home.co.uk/Export/Export.html"] | |
import FreeCAD, os, Part, math | |
from FreeCAD import Vector | |
try: import FreeCADGui | |
except ValueError: gui = False | |
else: gui = True | |
#*************************************************************************** | |
# Tailor following to your requirements ( Should all be strings ) * | |
fafs = '$fa = 12, $fs = 2' | |
convexity = 'convexity = 10' | |
#*************************************************************************** | |
pythonopen = open | |
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") | |
def check_center(ob): | |
d = FreeCAD.Vector(0,0,0) | |
# Only say center = false if no rotation and no displacement | |
if ( ob.Placement.Rotation.Angle == 0 and ob.Placement.Base == d): | |
return 'false' | |
return 'true' | |
def center(b): | |
if b == 0 : | |
return 'false' | |
return 'true' | |
def check_multmatrix(csg,ob,x,y,z): | |
v = FreeCAD.Vector(0,0,1) | |
b = FreeCAD.Vector(x,y,z) | |
if ( ob.Placement.Base == FreeCAD.Vector(0,0,0)): | |
return 0 # center = false no mm | |
elif ( ob.Placement.Rotation.Axis != v or ob.Placement.Rotation.Angle != 0 or ob.Placement.Base != b) : | |
print "Output Multmatrix" | |
m = ob.Placement.toMatrix() | |
# adjust position for center displacments | |
csg.write("multmatrix([["+str(m.A11)+", "+str(m.A12)+", "+str(m.A13)+", "+str(m.A14)+"], ["\ | |
+str(m.A21)+", "+str(m.A22)+", "+str(m.A23)+", "+str(m.A24)+"], ["\ | |
+str(m.A31)+", "+str(m.A32)+", "+str(m.A33)+", "+str(m.A34)+"], [ 0, 0, 0, 1]]){\n") | |
return 1 # center = true and mm | |
return 2 # center = true and no mm | |
def mesh2polyhedron(mesh): | |
pointstr=','.join(['[%f,%f,%f]' % tuple(vec) for vec in mesh.Topology[0]]) | |
trianglestr=','.join(['[%d,%d,%d]' % tuple(tri) for tri in mesh.Topology[1]]) | |
return 'polyhedron ( points = [%s], triangles = [%s]);' % (pointstr,trianglestr) | |
def vector2d(v): | |
return [v[0],v[1]] | |
def vertexs2polygon(vertex): | |
pointstr=','.join(['[%f, %f]' % tuple(vector2d(v.Point)) for v in vertex]) | |
return 'polygon ( points = [%s], paths = undef, convexity = 1);}' % pointstr | |
def shape2polyhedron(shape): | |
import MeshPart | |
return mesh2polyhedron(MeshPart.meshFromShape(shape)) | |
def process_object(csg,ob): | |
print "Placement" | |
print "Pos : "+str(ob.Placement.Base) | |
print "axis : "+str(ob.Placement.Rotation.Axis) | |
print "angle : "+str(ob.Placement.Rotation.Angle) | |
if ob.Type == "Part::Sphere" : | |
print "Sphere Radius : "+str(ob.Radius) | |
check_multmatrix(csg,ob,0,0,0) | |
global fafs | |
csg.write("sphere($fn = 0, "+fafs+", r = "+str(ob.Radius)+");\n") | |
elif ob.Type == "Part::Box" : | |
print "cube : ("+ str(ob.Length)+","+str(ob.Width)+","+str(ob.Height)+")" | |
mm = check_multmatrix(csg,ob,-ob.Length/2,-ob.Width/2,-ob.Height/2) | |
csg.write("cube (size = ["+str(ob.Length)+", "+str(ob.Width)+", "+str(ob.Height)+"], center = "+center(mm)+");\n") | |
if mm == 1 : csg.write("}\n") | |
elif ob.Type == "Part::Cylinder" : | |
print "cylinder : Height "+str(ob.Height)+ " Radius "+str(ob.Radius) | |
mm = check_multmatrix(csg,ob,0,0,-ob.Height/2) | |
global fafs | |
csg.write("cylinder($fn = 0, "+fafs+", h = "+str(ob.Height)+ ", r1 = "+str(ob.Radius)+\ | |
", r2 = " + str(ob.Radius) + ", center = "+center(mm)+");\n") | |
if mm == 1 : csg.write("}\n") | |
elif ob.Type == "Part::Cone" : | |
print "cone : Height "+str(ob.Height)+ " Radius1 "+str(ob.Radius1)+" Radius2 "+str(ob.Radius2) | |
mm = check_multmatrix(csg,ob,0,0,-ob.Height/2) | |
global fafs | |
csg.write("cylinder($fn = 0, "+fafs+", h = "+str(ob.Height)+ ", r1 = "+str(ob.Radius1)+\ | |
", r2 = "+str(ob.Radius2)+", center = "+center(mm)+");\n") | |
if mm == 1 : csg.write("}\n") | |
elif ob.Type == "Part::Torus" : | |
print "Torus" | |
print ob.Radius1 | |
print ob.Radius2 | |
if ob.Angle3 == 360.00 : | |
mm = check_multmatrix(csg,ob,0,0,0) | |
global fafs | |
csg.write("rotate_extrude("+convexity+", $fn = 0, "+fafs+")\n") | |
csg.write("multmatrix([[1, 0, 0, "+str(ob.Radius1)+"], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])\n") | |
csg.write("circle($fn = 0, "+fafs+", r = "+str(ob.Radius2)+");\n") | |
if mm == 1 : csg.write("}\n") | |
else : # Cannot convert to rotate extrude so best effort is polyhedron | |
csg.write('%s\n' % shape2polyhedron(ob.Shape)) | |
elif ob.Type == "Part::Extrusion" : | |
print "Extrusion" | |
print ob.Base | |
print ob.Base.Name | |
#if ( ob.Base == "Part::FeaturePython" and ob.Base.Name == "Polygon") : | |
if ob.Base.Name == "Polygon" : | |
f = str(ob.Base.FacesNumber) | |
r = str(ob.Base.Radius) | |
h = str(ob.Dir[2]) | |
print "Faces : " + f | |
print "Radius : " + r | |
print "Height : " + h | |
mm = check_multmatrix(csg,ob,0,0,-float(h)/2) | |
global fafs | |
csg.write("cylinder($fn = "+f+", "+fafs+", h = "+h+", r1 = "+r+\ | |
", r2 = "+r+", center = "+center(mm)+");\n") | |
if mm == 1: csg.write("}\n") | |
elif ob.Base.Name == "circle" : | |
r = str(ob.Base.Radius) | |
h = str(ob.Dir[2]) | |
print "Radius : " + r | |
print "Height : " + h | |
mm = check_multmatrix(csg,ob,0,0,-float(h)/2) | |
global fafs | |
csg.write("cylinder($fn = 0, "+fafs+", h = "+h+", r1 = "+r+\ | |
", r2 = "+r+", center = "+center(mm)+");\n") | |
if mm == 1: csg.write("}\n") | |
elif ob.Base.Name == "Wire" : | |
print "Wire extrusion" | |
print ob.Base | |
mm = check_multmatrix(csg,ob,0,0,0) | |
global fafs | |
csg.write("linear_extrude(height = "+str(ob.Dir[2])+", center = "+center(mm)+", "+convexity+", twist = 0, slices = 2, $fn = 0, "+fafs+")\n{\n") | |
csg.write(vertexs2polygon(ob.Base.Shape.Vertexes)) | |
if mm == 1: csg.write("}\n") | |
elif ob.Base.Name == "square" : | |
mm = check_multmatrix(csg,ob,0,0,0) | |
global fafs | |
csg.write("linear_extrude(height = "+str(ob.Dir[2])+", center = true, "+convexity+", twist = 0, slices = 2, $fn = 0, "+fafs+")\n{\n") | |
csg.write("square (size = ["+str(ob.Base.Length)+", "+str(ob.Base.Width)+"],center = "+center(mm)+";\n}\n") | |
if mm == 1: csg.write("}\n") | |
elif ob.Type == "Part::Cut" : | |
print "Cut" | |
csg.write("difference() {\n") | |
process_object(csg,ob.Base) | |
process_object(csg,ob.Tool) | |
csg.write("}\n") | |
elif ob.Type == "Part::Fuse" : | |
print "union" | |
csg.write("union() {\n") | |
process_object(csg,ob.Base) | |
process_object(csg,ob.Tool) | |
csg.write("}\n") | |
elif ob.Type == "Part::Common" : | |
print "intersection" | |
csg.write("intersection() {\n") | |
process_object(csg,ob.Base) | |
process_object(csg,ob.Tool) | |
csg.write("}\n") | |
elif ob.Type == "Part::MultiFuse" : | |
print "Multi Fuse / union" | |
csg.write("union() {\n") | |
for subobj in ob.Shapes: | |
process_object(csg,subobj) | |
csg.write("}\n") | |
elif ob.Type == "Part::Common" : | |
print "Multi Common / intersection" | |
csg.write("intersection() {\n") | |
for subobj in ob.Shapes: | |
process_object(csg,subobj) | |
csg.write("}\n") | |
elif ob.isDerivedFrom('Part::Feature') : | |
print "Part::Feature" | |
mm = check_multmatrix(csg,ob,0,0,0) | |
csg.write('%s\n' % shape2polyhedron(ob.Shape)) | |
if mm == 1 : csg.write("}\n") | |
def export(exportList,filename): | |
"called when freecad exports a file" | |
# process Objects | |
print "\nStart Export 0.1c\n" | |
print "Open Output File" | |
csg = pythonopen(filename,'w') | |
print "Write Inital Output" | |
# Not sure if comments as per scad are allowed in csg file | |
csg.write("// CSG file generated from FreeCAD Export 0.1c\n") | |
#write initial group statements - not sure if required | |
csg.write("group() {\n group(){\n") | |
for ob in exportList: | |
print ob | |
print "Name : "+ob.Name | |
print "Type : "+ob.Type | |
print "Shape : " | |
print ob.Shape | |
process_object(csg,ob) | |
# write closing group braces | |
csg.write("}\n}\n") | |
# close file | |
csg.close() | |
FreeCAD.Console.PrintMessage("successfully exported "+filename) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Version History | |
=============== | |
0.01a - First Version | |
0.01b - Added support for polyhedron ( Thanks shoogen ) | |
Some support for Torus | |
Some support for extruded regular polygon | |
0.01c - Support for extruded polygon, square, circle | |
bug fix for polyhydron floating point - Thanks shoogen | |
Thanks to shoogen and Peter Li for their advice, code, support and expertise. | |
Keith Sloan | |
[email protected] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment