QUELAB

A place to make things!

User Tools

Site Tools


sketchup_dxf_export_plugin

This is an old revision of the document!


Sketchup DXF Export plugin

The current settings on the wiki do not allow the plugin to be uploaded. Alice has it available at a dropbox link.

If that list no longer works, below is the contents of the plugin. Copy 'n paste them to the file skp_to_dxf.rb and save it in your Sketchup plugins folder1)2).

# SketchUp to DXF STL Converter
# Last edited: February 18, 2011
# Authors: Nathan Bromham, Konrad Shroeder
# Download from: http://www.guitar-list.com/download-software/convert-sketchup-skp-files-dxf-or-stl
 
require 'sketchup.rb'
 
def dxf_export_mesh_file
      model = Sketchup.active_model
      model_filename = File.basename(model.path)
      if( model_filename == "" )
        model_filename = "model"
      end
      ss = model.selection
      $stl_conv = 1.0
      $group_count = 0
      $component_count = 0
      $face_count = 0
      $line_count = 0
      entities = model.entities
      if (Sketchup.version_number < 7)
        model.start_operation("export_dxf_mesh")
      else
         model.start_operation("export_dxf_mesh",true)
      end
      if ss.empty?
         answer = UI.messagebox("No objects selected. Export entire model?", MB_YESNOCANCEL)
         if( answer == 6 )
            export_ents = model.entities
         else
            export_ents = ss
         end
      else
         export_ents = Sketchup.active_model.selection
      end
      if (export_ents.length > 0)
         #get units for export
         dxf_dxf_units_dialog
         #get DXF export option
         dxf_option = dxf_dxf_options_dialog
         if (dxf_option =="stl")
          file_type="stl"
         else
          file_type="dxf"
         end
         #exported file name
         out_name = UI.savepanel( file_type+" file location", "." , "#{File.basename(model.path).split(".")[0]}." +file_type )
         $mesh_file = File.new( out_name , "w" )  
         model_name = model_filename.split(".")[0]
         dxf_header(dxf_option,model_name)
         # Recursively export faces and edges, exploding groups as we go.
         #Count "other" objects we can't parse.
         others = dxf_find_faces(0, export_ents, Geom::Transformation.new(), model.active_layer.name,dxf_option)
         dxf_end(dxf_option,model_name)
         UI.messagebox( $face_count.to_s + " faces exported " + $line_count.to_s + " lines exported\n" + others.to_s + " objects ignored" )
      end
      model.commit_operation
end
 
def dxf_find_faces(others, entities, tform, layername,dxf_option)
   entities.each do |entity|
      #Face entity
      if( entity.typename == "Face")
       case dxf_option
       when "polylines"
        dxf_write_polyline(entity,tform,layername)
       when "polyface mesh"
        dxf_write_polyface(entity,tform,layername)
       when "triangular mesh"
         dxf_write_face(entity,tform,layername)
       when "stl"
         dxf_write_stl(entity,tform)     
       end
     #Edge entity
      elsif( entity.typename == "Edge") and((dxf_option=="lines")or(entity.faces.length==0 and dxf_option!="stl"))
       dxf_write_edge(entity, tform, layername)
     #Group entity
      elsif( entity.typename == "Group")
         if entity.name==""
           entity.name="GROUP"+$group_count.to_s
           $group_count+=1
         end
         others = dxf_find_faces(others, entity.entities, tform * entity.transformation, entity.name,dxf_option)
      #Componentinstance entity
      elsif( entity.typename == "ComponentInstance")
         if entity.name==""
           entity.name="COMPONENT"+$component_count.to_s
           $component_count+=1
         end
         others = dxf_find_faces(others, entity.definition.entities, tform * entity.transformation, entity.name,dxf_option)
      else
         others = others + 1
      end
   end
   others
end
 
def dxf_transform_edge(edge, tform)
   points=[]
   points.push(dxf_transform_vertex(edge.start, tform))
   points.push(dxf_transform_vertex(edge.end, tform))
   points
end
 
def dxf_transform_vertex(vertex, tform)
   point = Geom::Point3d.new(vertex.position.x, vertex.position.y, vertex.position.z)
   point.transform! tform
   point
end
 
def dxf_write_edge(edge, tform, layername)
  points = dxf_transform_edge(edge, tform)
  $mesh_file.puts( "  0\nLINE\n 8\n"+layername+"\n")
  for j in 0..1 do
    $mesh_file.puts((10+j).to_s+"\n"+(points[j].x.to_f * $stl_conv).to_s)#x
    $mesh_file.puts((20+j).to_s+"\n"+(points[j].y.to_f * $stl_conv).to_s)#y
    $mesh_file.puts((30+j).to_s+"\n"+(points[j].z.to_f * $stl_conv).to_s)#z
  end
  $line_count+=1
end
 
def dxf_write_polyline(face, tform,layername)
 face.loops.each do |aloop|
  $mesh_file.puts("  0\nPOLYLINE\n 8\n"+layername+"\n 66\n     1")
  $mesh_file.puts("70\n    8\n 10\n0.0\n 20\n 0.0\n 30\n0.0")
  for j in 0..aloop.vertices.length do
    if (j==aloop.vertices.length)
      count = 0
    else
      count = j
    end
    point = dxf_transform_vertex(aloop.vertices[count],tform)
    $mesh_file.puts( "  0\nVERTEX\n  8\nMY3DLAYER")
    $mesh_file.puts("10\n"+(point.x.to_f * $stl_conv).to_s)
    $mesh_file.puts("20\n"+(point.y.to_f * $stl_conv).to_s)
    $mesh_file.puts("30\n"+(point.z.to_f * $stl_conv).to_s)
    $mesh_file.puts( " 70\n     32")
  end
  if (aloop.vertices.length > 0)
    $mesh_file.puts( "  0\nSEQEND")
  end
 end
 $face_count+=1
end
 
 
def dxf_write_face(face,tform, layername)
  mesh = face.mesh 0
  mesh.transform! tform
  polygons = mesh.polygons
  polygons.each do |polygon|
  if (polygon.length > 2)
    flags = 0
    $mesh_file.puts( "  0\n3DFACE\n 8\n"+layername)
    for j in 0..polygon.length do
      if (j==polygon.length)
        count = polygon.length-1
      else
        count = j
      end
      #check edge visibility
      if ((polygon[count]<0))
       flags+=2**j
      end
      $mesh_file.puts((10+j).to_s+"\n"+(mesh.point_at(polygon[count].abs).x.to_f * $stl_conv).to_s)
      $mesh_file.puts((20+j).to_s+"\n"+(mesh.point_at(polygon[count].abs).y.to_f * $stl_conv).to_s)
      $mesh_file.puts((30+j).to_s+"\n"+(mesh.point_at(polygon[count].abs).z.to_f * $stl_conv).to_s)
    end
    #edge visibiliy flags
    $mesh_file.puts("70\n"+flags.to_s)  
    end
  end
  $face_count+=1
end
 
def dxf_write_stl(face,tform)
  mesh = face.mesh 7
  mesh.transform! tform
  polygons = mesh.polygons
  polygons.each do |polygon|
  if (polygon.length == 3)
      $mesh_file.puts( "facet normal " + mesh.normal_at(polygon[0].abs).x.to_s + " " + mesh.normal_at(polygon[0].abs).y.to_s + " " + mesh.normal_at(polygon[0].abs).z.to_s)
      $mesh_file.puts( "outer loop")
      for j in 0..2 do
         $mesh_file.puts("vertex " + (mesh.point_at(polygon[j].abs).x.to_f * $stl_conv).to_s + " " + (mesh.point_at(polygon[j].abs).y.to_f * $stl_conv).to_s + " " + (mesh.point_at(polygon[j].abs).z.to_f * $stl_conv).to_s)
      end
      $mesh_file.puts( "endloop\nendfacet")
    end
  end
  $face_count+=1
end
 
def dxf_write_polyface(face,tform,layername)
  mesh = face.mesh 0
  mesh.transform! tform
  polygons = mesh.polygons
  points = mesh.points
  $mesh_file.puts("  0\nPOLYLINE\n 8\n"+layername+"\n 66\n     1")
  $mesh_file.puts("10\n0.0\n 20\n 0.0\n 30\n0.0\n")
  $mesh_file.puts("70\n    64\n") #flag for 3D polyface
  $mesh_file.puts("71\n"+mesh.count_points.to_s)
  $mesh_file.puts("72\n   1")
  #points
  points.each do |point| 
      $mesh_file.puts( "  0\nVERTEX\n  8\n"+layername)
      $mesh_file.puts("10\n"+(point.x.to_f * $stl_conv).to_s)
      $mesh_file.puts("20\n"+(point.y.to_f * $stl_conv).to_s)
      $mesh_file.puts("30\n"+(point.z.to_f * $stl_conv).to_s)
      $mesh_file.puts( " 70\n     192")
  end
  #polygons
  polygons.each do |polygon| 
      $mesh_file.puts( "  0\nVERTEX\n  8\n"+layername)
      $mesh_file.puts("10\n0.0\n 20\n 0.0\n 30\n0.0\n")
      $mesh_file.puts( " 70\n     128")
      $mesh_file.puts( " 71\n"+polygon[0].to_s)
      $mesh_file.puts( " 72\n"+polygon[1].to_s)
      $mesh_file.puts( " 73\n"+polygon[2].to_s)
      if (polygon.length==4)
        $mesh_file.puts( " 74\n"+polygon[3]..abs.to_s)
      end
  end
  $mesh_file.puts( "  0\nSEQEND")
  $face_count+=1
end
 
def dxf_dxf_options_dialog
   options_list=["polyface mesh","polylines","triangular mesh","lines","stl"].join("|")
   prompts=["Export to DXF options"]
   enums=[options_list]
   values=["polyface mesh"]
   results = inputbox prompts, values, enums, "Choose which entities to export"
   return if not results
   results[0]
end
 
def dxf_dxf_units_dialog
   cu=Sketchup.active_model.options[0]["LengthUnit"]
   case cu
   when 4
      current_unit= "Meters"
   when 3
      current_unit= "Centimeters"
   when 2
      current_unit= "Millimeters"
   when 1
      current_unit= "Feet"
   when 0
      current_unit= "Inches"
   end
   units_list=["Meters","Centimeters","Millimeters","Inches","Feet"].join("|")
   prompts=["Export unit: "]
   enums=[units_list]
   values=[current_unit]
   results = inputbox prompts, values, enums, "Export units"
   return if not results
   case results[0]
   when "Meters"
      $stl_conv=0.0254
   when "Centimeters"
      $stl_conv=2.54
   when "Millimeters"
      $stl_conv=25.4
   when "Feet"
      $stl_conv=0.0833333333333333
   when "Inches"
      $stl_conv=1
   end
end
 
def dxf_header(dxf_option,model_name)
  if (dxf_option=="stl")
   $mesh_file.puts( "solid " + model_name)
  else
   $mesh_file.puts( " 0\nSECTION\n 2\nENTITIES")
  end
end
 
def dxf_end(dxf_option,model_name)
  if (dxf_option=="stl")
    $mesh_file.puts( "endsolid " + model_name)
  else
    $mesh_file.puts( " 0\nENDSEC\n 0\nEOF")
  end
  $mesh_file.close
end
 
if( not file_loaded?("skp_to_dxf.rb") )
   add_separator_to_menu("Tools")
   UI.menu("Tools").add_item("Export to DXF or STL") { dxf_export_mesh_file }
end
 
file_loaded("skp_to_dxf.rb")
1)
On my 64 bit Windows machine, that folder was C:\Program Files (x86)\Google\Google SketchUp 8\Plugins
2)
Can someone test this? I was unable to make this work with Sketchup 8 installed on my Win10 machine/JT/12-18-15
sketchup_dxf_export_plugin.1450443472.txt.gz · Last modified: 2015/12/18 12:57 by John Benedetto