Macro PartToVRML

Description
This macro converts selected parts to VRML meshes for small size and faster loading (VRML models Kicad and Blender compatible)

Script
The icone

Macro_PartToVRML.FCMacro


 * 1) -*- coding: utf-8 -*-


 * 1) PartToVRML.FCMacro
 * 2) creates VRML model of selected object(s), with colors (for Kicad and Blender compatibility)
 * 3) useful messages on Report view

__title__ = "PartToVRML" __author__ = "easyw-fc, hyOzd" __url__    = "http://www.freecadweb.org/" __version__ = "1.9.2" __date__   = "22/02/2016"

__Comment__ = "This macro creates VRML model of selected object(s), with colors (for Kicad and Blender compatibility)" __Web__ = "http://www.freecadweb.org/" __Wiki__ = "http://www.freecadweb.org/wiki/index.php?title=Macro_PartToVRML" __Icon__ = "/usr/lib/freecad/Mod/plugins/icons/Macro_PartToVRML.png" __IconW__ = "C:/Users/User Name/AppData/Roaming/FreeCAD/Macro_PartToVRML.png" __Help__ = "start the macro and follow the instructions" __Status__ = "stable" __Requires__ = "Freecad"


 * 1) FreeCAD VRML python exporter is free software: you can redistribute it
 * 2) and/or modify it under the terms of the GNU General Public License
 * 3) as published by the Free Software Foundation, either version 3 of
 * 4) the License, or (at your option) any later version.
 * 5) This sw is distributed in the hope that it will be
 * 6) useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * 7) of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * 8) General Public License for more details.
 * 9) You should have received a copy of the GNU General Public License
 * 10) along with expVrmlColor.FCMacro.  If not, see
 * 11) .
 * 1) along with expVrmlColor.FCMacro.  If not, see
 * 2) .


 * 1) export VRML from FreeCAD is a python macro that will export simplified VRML of
 * 2) a (multi)selected Part or fused Part to VRML optimized to Kicad and compatible with Blender
 * 3) the size of VRML is much smaller compared to the one exported from FC Gui
 * 4) and the loading/rendering time is smaller too
 * 5) change mesh deviation to increase quality of VRML


 * 1) to do
 * 2)  export material properties to vrml

import FreeCAD,FreeCADGui,Part,Mesh import PySide from PySide import QtGui, QtCore from collections import namedtuple import sys, os from os.path import expanduser

mw=Gui.getMainWindow c=mw.findChild(QtGui.QPlainTextEdit, "Python console") c.clear r=mw.findChild(QtGui.QTextEdit, "Report view") r.clear
 * 1) clearing previous messages

def say(msg): FreeCAD.Console.PrintMessage(msg) FreeCAD.Console.PrintMessage('\n')

Mesh = namedtuple('Mesh', ['points', 'faces', 'color', 'transp'])
 * 1) points: [Vector, Vector, ...]
 * 2) faces: [(pi, pi, pi), ], pi: point index
 * 3) color: (Red, Green, Blue), values range from 0 to 1.0

def shapeToMesh(shape, color, transp, scale=None): mesh_deviation=0.03 #the smaller the best quality, 1 coarse; 0.03 good compromise :)   mesh_data = shape.tessellate(mesh_deviation)    points = mesh_data[0]    if scale != None:        points = map(lambda p: p*scale, points)    newMesh= Mesh(points = points, faces = mesh_data[1], color = color, transp=transp)   return newMesh def exportVRML(objects, filepath):    """Export given list of Mesh objects to a VRML file.

`Mesh` structure is defined at root."""

with open(filepath, 'w') as f:       # write the standard VRML header f.write("#VRML V2.0 utf8\n\n") for obj in objects: f.write("Shape { geometry IndexedFaceSet \n{ coordIndex [") # write coordinate indexes for each face f.write(','.join("%d,%d,%d,-1" % f for f in obj.faces)) f.write("]\n") # closes coordIndex f.write("coord Coordinate { point [") # write coordinate points for each vertex #f.write(','.join('%.3f %.3f %.3f' % (p.x, p.y, p.z) for p in obj.points)) f.write(','.join('%.3f %.3f %.3f' % (p.x, p.y, p.z) for p in obj.points)) f.write("]\n}") # closes Coordinate #shape_col=(1.0, 0.0, 0.0)#, 0.0)           f.write("}\n") # closes points            #say(obj.color)            shape_col=obj.color[:-1] #remove last item            #say(shape_col)            shape_transparency=obj.transp            f.write("appearance Appearance{material Material{diffuseColor %f %f %f\n" % shape_col)            f.write("transparency %f}}" % shape_transparency)            f.write("}\n") # closes Shape        say(filepath+' written')

def export(componentObjs, fullfilePathName, scale=None): """ Exports given ComponentModel object using FreeCAD.

`componentObjs` : a ComponentObjs list `fullfilePathName` : name of the FC file, extension is important """   exp_name=componentObjs[0].Label    path, fname = os.path.split(fullfilePathName)    fname=os.path.splitext(fname)[0]    if scale != None:        filename=path+os.sep+exp_name+'.wrl'    else:        filename=path+os.sep+exp_name+'_1_1.wrl'    say(filename)        color=[]    Diffuse_color=[]    transparency=[]    for obj in componentObjs:        say(obj.Label)        color.append(Gui.ActiveDocument.getObject(obj.Name).ShapeColor)        transparency.append(Gui.ActiveDocument.getObject(obj.Name).Transparency/100.0)        #say("color")        #say(Gui.ActiveDocument.getObject(obj.Name).DiffuseColor)        Diffuse_color.append(Gui.ActiveDocument.getObject(obj.Name).DiffuseColor)    i=0    meshes=[]    #say("diffuse color")    #say(Diffuse_color)    indexColor=0;    color_vector=[]    applyDiffuse=0    for obj in componentObjs:        shape1=obj.Shape        single_color=Diffuse_color[i]; #check lenght color #say("len color") #say(len(single_color)) #colors less then faces if(len(single_color)!=len(shape1.Faces)): applyDiffuse=0; #copy color to all faces #else copy singolar colors for faces else: applyDiffuse=1; for color in single_color: color_vector.append(color) #say("color_vector") #say(color_vector) for index in range(len(shape1.Faces)): #say("color x") #say(color_vector[indexColor]) singleFace=shape1.Faces[index] if(applyDiffuse): #say(color_vector[indexColor]) meshes.append(shapeToMesh(singleFace, color_vector[indexColor], transparency[i], scale)) else: #say(single_color[0]) meshes.append(shapeToMesh(singleFace, single_color[0], transparency[i], scale)) indexColor=indexColor+1 #meshes.append(shapeToMesh(face, Diffuse_color[i], transparency[i], scale)) color_vector=[] indexColor=0; i=i+1 exportVRML(meshes, filename) return

def go_export: sel = FreeCADGui.Selection.getSelection if not sel: FreeCAD.Console.PrintWarning("Select something first!\n\n") msg="export VRML from FreeCAD is a python macro that will export simplified VRML of " msg+="a (multi)selected Part or fused Part to VRML optimized to Kicad and compatible with Blender " msg+="the size of VRML is much smaller compared to the one exported from FC Gui " msg+="and the loading/rendering time is also smaller\n" msg+="change mesh deviation to increase quality of VRML" say(msg) else: objs = [] for obj in sel: objs.append(obj) #say(obj.Label) #say(obj.Name) say(fullFilePathName) #say(objs) export(objs, fullFilePathName, scale=None) export(objs, fullFilePathName, 0.3937) doc = FreeCAD.ActiveDocument if doc!=None: fullFilePathName=doc.FileName if fullFilePathName=="": home = expanduser("~") fullFilePathName=home+os.sep+doc.Label+'.FCStd' say('path not found, saving to '+fullFilePathName) #say(fullFilePathName) else: fullFilePathName = os.path.dirname(os.path.abspath(fullFilePathName)) fullFilePathName=fullFilePathName+os.sep+doc.Label+'.FCStd' say(fullFilePathName) go_export

Links
The forum discussion export VRML from FreeCAD with python for smaller size, kicad and Blender compatible

The macro reverse, Macro_MeshToPart