Blender Slice SVG Export

I am an architecture student and I really enjoy using blender. However, there are a few features that I miss from other modeling programs. One is the ability to export section, or plan cuts in a vector format. To solve this, I am going to write a vector exporting script based on selected points, and edges.

I want to write the script to export Inkscape SVG compatible SVG files. This will give access to more options than a standard SVG file would, like layers. Because this is a learning project for my self, there will be several stages in which I would like to complete this project:

Stage 1: Complete: The script can identify the selected edges within, the selected objects and export the global coordinates of their endpoints to an SVG file. This will create a group for each object that has each line selected segment represented as a line segment in the SVG file. However the closed section are not connected and do not for shapes in the svg file.

Stage 2: Work in Progress: In this section, I would like to take a tuple built from the endpoints of the selected edges in a selected object, and match the connecting ends together. This will allow completed edge loops within an object to be exported as a closed shape with a fill in the SVG file. I have the tuple created but i am still strugling with the best way to 1) search through the tuple for each cooresponding end point, and 2) how to remove or designate that an edge has already been used.

Stage 3: This would be a combination of my export script with the Knife Slice script. The goal would be to allow you to make a slice with a plan, and export the resulting edges as an SVG file. I might even be able to allow you make multiple slices automatically based on offsetting the plane in a choosen direction, then each slice would be exported to the same file as a seperate layer.

If you have any thoughts, words of advice, encouragement, comments, etc. please let me know. I am still pretty new to python so my code will probably be very rough. After I comment my code and ensure it is working a little, I will share my start with the rest of you. Please let me know what you think of the project.

Thanks,
tehquickness

I got some cheering…
Thats a great idea.
And thats the attitude too… :slight_smile:
Not complaining about missing features, just implement them…

A nice feature would be to export the blender materials basecolor used in the architectural visualization for the vector groups exported, or at least inclode an checkbox… maybe someone just want to export it B/W.

Just in case you don’t already know about them, three projects that I know of are directly related to working with SVG in Blender, if you want to have a look at them:

-SVG paths import (models with SVG) (shipped with Blender installs)
-Vectex (textures with SVG)
-Pantograph (renders to SVG)

Yeah, I have seen them, and they impressive but not doing quite the same thing. Pantograph is nice but a little buggy at this point.

I will also consider adding the base color as the fill color, outline color, or maybe both. Who knows at this point. The first thing I need to do now is get the edge matching working. I will be working on my script today, commenting it and making it more legible so there should be some uploaded in a little bit.

Do you know Yorik’s CrossSection script?

Good find. It looks like a newer verson of the old knife script. Well I will use this as the slicing too that I will export the edge from.
Edit: After having played with this script, it will be the ideal to for cutting sections that will be exported to a vector format. Once a system is designed to ensure closed shapes are created, then there will be no problem choosing a specific format, either SVG, dxf etc…

And while after talking in the Python IRC for a while, I think I found a good method to do this. I will post code in a bit

hi tehquickness,

i’m not sure if youve heard this, but there is a project to adapt blender to archiviz, i think you should also post your suggestions there in the
thread: http://blenderartists.org/forum/showthread.php?t=128924 and
wiki: http://wiki.blender.org/index.php/BlenderDev/BlenderArchiProject

Ok, so here is the code I have up to this point.
Usage: Selected the edges you want to export in each object. Then select the objects that you want edges exported from. Cross section is a good way to create sections. Right now, It will only export an orthagonal top view of the selected verticies.

With the objects selected, first use CTRL-A to apply all transforms, scales, and rotations to the objects, then open and run the script in the text editor ( GUI will come later). It will ask you for a place to save the file. Save it some where as a .svg file. Click export and a svg file will be created of the choosen edges.
However, each object will have its own group of edges if opened in inkscape (probably other programs as well.)

Please let me know if you run into a problem or if you manage to break it. Thanks!

 
import Blender
import bpy

def write_obj(filepath):
	out = file(filepath, 'w')

	# Write the SVG Header to the file
	out.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>
')
	out.write('<!-- Created with Inkscape (http://www.inkscape.org/) -->
')
	out.write('<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="100" height="100" id="svg2">
')
	
	#Gather the selected objects in the scene and store as variable
	selected_Objs = Blender.Object.GetSelected()
	
	#For each obkect, we want to store the vertex coordinants into an arraay structure
	#	for each edge individually
	for obj in selected_Objs:
		
		#Creates a group for each object in the scene to hold its edges
		out.write('
<g id="%s">
' % (obj.name))
		
		#Retrieve the mesh data for the object, and store as variable
		mesh = obj.getData(mesh=1)
		
		#Create empty sets to store edge verticies in
		pOneX = []
		pOneY = []
		pTwoX = []
		pTwoY = []



		#For each selected edge, use the objects location, local location, and scale to create coordinate sets, objects are scaled 10 times when exporting (temporary feature)
		for e in mesh.edges.selected():
			pOneX.append(round((obj.LocX+mesh.edges[e].v1.co.x*obj.SizeX)*10,4))
			pOneY.append(round((obj.LocY+mesh.edges[e].v1.co.y*obj.SizeY)*10,4))
			pTwoX.append(round((obj.LocX+mesh.edges[e].v2.co.x*obj.SizeX)*10,4))
			pTwoY.append(round((obj.LocY+mesh.edges[e].v2.co.y*obj.SizeY)*10,4))
			
			print "pOneX", pOneX
			print "pOneY", pOneY
			print "pTwoX", pTwoX
			print "pTwoY", pTwoY, "
"
			
			#print each edge seperately
			for pOx, pOy, pTx, pTy in zip(pOneX, pOneY, pTwoX, pTwoY):
			
				out.write('<path d="')
				out.write('M %i %i ' % (pOx+50, -pOy+50) )
				out.write('L %i %i z"' % (pTx+50, -pTy+50) )
				out.write(' fill = "none" stroke = "black" stroke-width=".5" />
')
				
		

			
			
			
		out.write('</g>

') #Closes the group
		
	out.write('</svg>')
	out.close
		
Blender.Window.FileSelector(write_obj, "Export")

It works smoothly for a first version!
I didn’t break it, but thought I did, when i tried with a mesh over 300 verts… The console output, just Matrix like screen filled with numbers looked like an infinite loop…
I tried to abort, my computer crashed, this was the first time since I had switched it to Linux a few weeks ago. In fact I just had to wait… But one might want to abort if it’s too long.
DrawProgressBar would be nice.

I will have to think about a progress bar, also, I am sure once I write this, there will be ways in which I will be able to optimise the code. At this point, it is very rough, and very raw coding. I have not really stress tested the code yet. So thanks for the input!

Did you make a slice through a model? Or what did you use it on?

I am still working on the detecting closed shapes from edges that are connected. The script works OK so far but can be broken pretty easily… So with out further introduction, here is my next attempt at this script. If anyone wants to make a suggestion or help me figure out the best way to test if the edges are connected you are more than welcome… I will keep posting my updates…


import Blender
import bpy

def write_obj(filepath):
    out = file(filepath, 'w')

    # Write the SVG Header to the file
    out.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>
')
    out.write('<!-- Created with Inkscape (http://www.inkscape.org/) -->
')
    out.write('<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="100" height="100" id="svg2">
')
    
    #Gather the selected objects in the scene and store as variable
    selected_Objs = Blender.Object.GetSelected()
    
    #For each obkect, we want to store the vertex coordinants into an arraay structure
    #    for each edge individually
    for obj in selected_Objs:
        
        #Creates a group for each object in the scene to hold its edges
        out.write('
<g id="%s">
' % (obj.name))
        
        #Retrieve the mesh data for the object, and store as variable
        mesh = obj.getData(mesh=1)
        
        #Create empty sets to store edge verticies in
        pOneX = []
        pOneY = []
        pTwoX = []
        pTwoY = []

        #For each selected edge, use the objects location, local location, and scale to create coordinate sets
        for e in mesh.edges.selected():
            pOneX.append(round((obj.LocX+mesh.edges[e].v1.co.x*obj.SizeX)*10,4))
            pOneY.append(round((obj.LocY+mesh.edges[e].v1.co.y*obj.SizeY)*10,4))
            pTwoX.append(round((obj.LocX+mesh.edges[e].v2.co.x*obj.SizeX)*10,4))
            pTwoY.append(round((obj.LocY+mesh.edges[e].v2.co.y*obj.SizeY)*10,4))
            
            print "pOneX", pOneX
            print "pOneY", pOneY
            print "pTwoX", pTwoX
            print "pTwoY", pTwoY, "
"
            
            for pOx, pOy, pTx, pTy in zip(pOneX, pOneY, pTwoX, pTwoY):
            
                out.write('<path d="')
                out.write('M %i %i ' % (pOx+50, -pOy+50) )
                out.write('L %i %i z"' % (pTx+50, -pTy+50) )
                out.write(' fill = "none" stroke = "black" stroke-width=".5" />
')
            
            
        out.write('</g>

') #Closes the group
        
    out.write('</svg>')
    out.close
        
Blender.Window.FileSelector(write_obj, "Export")

Any updates on this script? Would be awesome if Blender could export svg

this is a very useful script, hope it get integrated to blender

any news / alternatives on this script?