I used xml.etree.ElementTree to manage SVG string.
The Result of study is below.
code for Parametric BeamSection prototype.
Code: Select all
# -*- coding: utf-8 -*-
"""
BeamSection.py
Test Parametric SVG(2D) Object concept
15 Sep 2016
"""
from xml.etree import ElementTree as et
class svgBeamSectionView:
def __init__(self, obj):
obj.addProperty("App::PropertyLength","b","Beam Section","width of the beam section").b = 150
obj.addProperty("App::PropertyLength","h","Beam Section", "height of the beam section").h = 300
obj.addProperty("App::PropertyLength","dia","Beam Section","diameter of the rebar in beam section").dia = 12
obj.addProperty("App::PropertyString","Name","Beam Section","Name of the rebar in beam section")
obj.Proxy = self
self.Type = "StructuralDrawing"
def execute(self, obj):
if not hasattr(self,"svg"):
self.onChanged(obj,"b")
result = et.Element('g' ,stroke='black')
result.set('stroke-width' , '0.25')
result.set('id' , obj.Name)
strTransform = 'rotate('+str(obj.Rotation)+','+str(obj.X)+','+str(obj.Y)+') '
strTransform+= 'translate('+str(obj.X)+','+str(obj.Y)+') '
#strTransform += 'scale('+str(obj.Scale)+','+str(obj.Scale)+')'
result.set('transform' , strTransform)
result.append(self.svg)
obj.ViewResult = et.tostring(result)
def onChanged(self, obj, prop):
if prop in ["b","h","dia" , "Scale" , "Name"]:
scale = obj.Scale
b = obj.b.Value*scale ; h = obj.h.Value*scale; dia = obj.dia.Value*scale
covering = 25 *scale
dia_stir = 6 *scale
font_size = 2
beamSection = et.Element('g')
border = et.Element('rect' , x='0' , y='0' , fill='none' ,
width='%g'%(b) ,height='%g'%(h) )
y1 = -5
dimH = et.Element('g' )
dimH.append( et.Element('line' , x1='-2', y1='%g'%(y1), x2='%g'%(b+2) ,y2='%g'%(y1) ) )
dimH.append( et.Element('line' , x1='0', y1='%g'%(y1-2), x2='0' ,y2='%g'%(y1+2) ) )
dimH.append( et.Element('line' , x1='%g'%(b), y1='%g'%(y1-2), x2='%g'%(b) ,y2='%g'%(y1+2) ) )
dimH.append( et.Element('line' , x1='-1', y1='%g'%(y1+1), x2='1' ,y2='%g'%(y1-1) ) )
dimH.append( et.Element('line' , x1='%g'%(b-1), y1='%g'%(y1+1), x2='%g'%(b+1) ,y2='%g'%(y1-1) ) )
x1 = -5
dimV = et.Element('g' )
dimV.append( et.Element('line' , x1='%g'%(x1), y1='%g'%(-2), x2='%g'%(x1) ,y2='%g'%(h+2) ) )
dimV.append( et.Element('line' , x1='%g'%(x1-2), y1='0', x2='%g'%(x1+2) ,y2='0' ) )
dimV.append( et.Element('line' , x1='%g'%(x1-2), y1='%g'%(h), x2='%g'%(x1+2) ,y2='%g'%(h) ) )
dimV.append( et.Element('line' , x1='%g'%(x1-1), y1='1', x2='%g'%(x1+1) ,y2='-1' ) )
dimV.append( et.Element('line' , x1='%g'%(x1-1), y1='%g'%(h+1), x2='%g'%(x1+1) ,y2='%g'%(h-1) ) )
textDimH = et.Element('text' ,x='%g'%(b/2) , y='%g'%(y1-1.5) )
textDimH.text = str(obj.b)
textDimH.set('text-anchor' , "middle")
textDimH.set('font-size' , str(font_size) )
x1-=1 ; y1 = h/2
textDimV = et.Element('text' ,x='%g'%(x1) , y='%g'%(y1) )
textDimV.text = str(obj.h)
textDimV.set('text-anchor' , "middle")
textDimV.set('font-size' , str(font_size) )
textDimV.set('transform' , 'rotate(-90 %g,%g)'%(x1 , y1) )
x1 = covering+dia_stir*1.5+dia/2; y1=x1
x2 = b-x1; y2=h-y1
TopRebarL = et.Element('circle' ,cx='%g'%(x1) , cy='%g'%(y1) , r='%g'%(dia/2) , fill='black' )
TopRebarR = et.Element('circle' ,cx='%g'%(x2) , cy='%g'%(y1) , r='%g'%(dia/2) , fill='black' )
BottomRebarL = et.Element('circle' ,cx='%g'%(x1) , cy='%g'%(y2) , r='%g'%(dia/2) , fill='black' )
BottomRebarR = et.Element('circle' ,cx='%g'%(x2) , cy='%g'%(y2) , r='%g'%(dia/2) , fill='black' )
textTopRebar = et.Element('text' ,x='%g'%(b+2) , y='0' )
textTopRebar.text = u"2RB%dมม"%(obj.dia.Value)
textTopRebar.set('text-anchor' , "start")
textTopRebar.set('font-size' , str(font_size) )
textBottomRebar = et.Element('text' ,x='%g'%(b+2) , y='%g'%(h+1) )
textBottomRebar.text = u"2RB%dมม"%(obj.dia.Value)
textBottomRebar.set('text-anchor' , "start")
textBottomRebar.set('font-size' , str(font_size) )
textStirrupRebar = et.Element('text' ,x='%g'%(b+2) , y='%g'%(h/2) )
textStirrupRebar.text = u"ปRB6มม@0.150ม"
textStirrupRebar.set('text-anchor' , "start")
textStirrupRebar.set('font-size' , str(font_size) )
textName = et.Element('text' ,x='%g'%(b/2) , y='%g'%(h+7) )
textName.text = obj.Name
textName.set('text-anchor' , "middle")
textName.set('font-size' , str(font_size*1.75) )
x1 = (covering+dia_stir/2)
y1 = (covering+dia_stir/2)
w1 = b - (covering+dia_stir/2)*2
h1 = h - (covering+dia_stir/2)*2
D = dia_stir*4
stirrup = et.Element('rect' , x='%g'%(x1) , y='%g'%(y1) , fill='none' ,
width='%g'%(w1) ,height='%g'%(h1) , rx = '%g'%(D/2) , ry = '%g'%(D/2) )
stirrup.set('stroke-width' , '%g'%(dia_stir))
beamSection.append(border)
beamSection.append(dimH)
beamSection.append(dimV)
beamSection.append(TopRebarL)
beamSection.append(TopRebarR)
beamSection.append(BottomRebarL)
beamSection.append(BottomRebarR)
beamSection.append(stirrup)
beamSection.append(textDimH)
beamSection.append(textDimV)
beamSection.append(textTopRebar)
beamSection.append(textBottomRebar)
beamSection.append(textStirrupRebar)
beamSection.append(textName)
self.svg=beamSection
def __getstate__(self):
return self.Type
def __setstate__(self,state):
if state:
self.Type = state
def getDisplayModes(self,vobj):
modes=["Default"]
return modes
def setDisplayMode(self,mode):
return mode
def makeSVGBeamSectionView(name="Beam Section"):
page = None
for o in FreeCAD.ActiveDocument.Objects:
if o.isDerivedFrom("Drawing::FeaturePage"):
page = o
break
if not page:
page = FreeCAD.ActiveDocument.addObject("Drawing::FeaturePage",translate("Arch","Page"))
page.Template = Draft.getParam("template",FreeCAD.getResourceDir()+'Mod/Drawing/Templates/A4_Landscape_plain.svg')
view = FreeCAD.ActiveDocument.addObject("Drawing::FeatureViewPython",name)
page.addObject(view)
svgBeamSectionView(view)
view.Scale = 1/20.0
return view
if __name__=="__main__":
beam1 = makeSVGBeamSectionView("BeamSectionB1")
beam1.X = 30; beam1.Y=50;
beam1.Name = "B1"
beam2 = makeSVGBeamSectionView("BeamSectionB2")
beam2.X = 70; beam2.Y=50;
beam2.b = 200; beam2.h=400
beam2.dia = 15
beam2.Name = "B2"
beam3 = makeSVGBeamSectionView("BeamSectionB3")
beam3.X = 110; beam3.Y=50
beam3.b = 250; beam3.h=500
beam3.dia = 19
beam3.Name = "B3"
FreeCAD.ActiveDocument.Page.addObject(beam1)
FreeCAD.ActiveDocument.Page.addObject(beam2)
FreeCAD.ActiveDocument.Page.addObject(beam3)
FreeCAD.ActiveDocument.recompute()