Add Arch Fence builder

This tool can build a Fence by giving it a single Section, a single Post
and a Path.
It will calculate the number of posts and sections needed and repeat them
along the path so that a full fence is build.
This commit is contained in:
furti
2019-05-03 15:07:10 +02:00
committed by Yorik van Havre
parent 9cfb84d862
commit 41a4ef6674
5 changed files with 756 additions and 1 deletions

View File

@@ -42,6 +42,7 @@ if FreeCAD.GuiUp:
from ArchWall import *
from ArchFloor import *
from ArchFence import *
from ArchSite import *
from ArchBuilding import *
from ArchStructure import *

313
src/Mod/Arch/ArchFence.py Normal file
View File

@@ -0,0 +1,313 @@
import math
import FreeCAD
import ArchComponent
import Draft
if FreeCAD.GuiUp:
import FreeCADGui
from PySide.QtCore import QT_TRANSLATE_NOOP
import PySide.QtGui as QtGui
else:
# \cond
def translate(ctxt, txt):
return txt
def QT_TRANSLATE_NOOP(ctxt, txt):
return txt
# \endcond
EAST = FreeCAD.Vector(1, 0, 0)
class _Fence(ArchComponent.Component):
def __init__(self, obj):
ArchComponent.Component.__init__(self, obj)
self.setProperties(obj)
# Does a IfcType exist?
# obj.IfcType = "Fence"
obj.MoveWithHost = False
def setProperties(self, obj):
ArchComponent.Component.setProperties(self, obj)
pl = obj.PropertiesList
if not "Section" in pl:
obj.addProperty("App::PropertyLink", "Section", "Fence", QT_TRANSLATE_NOOP(
"App::Property", "A single section of the fence"))
if not "Post" in pl:
obj.addProperty("App::PropertyLink", "Post", "Fence", QT_TRANSLATE_NOOP(
"App::Property", "A single fence post"))
if not "Path" in pl:
obj.addProperty("App::PropertyLink", "Path", "Fence", QT_TRANSLATE_NOOP(
"App::Property", "The Path the fence should follow"))
if not "NumberOfSections" in pl:
obj.addProperty("App::PropertyInteger", "NumberOfSections", "Fence", QT_TRANSLATE_NOOP(
"App::Property", "The number of sections the fence is built of"))
obj.setEditorMode("NumberOfSections", 1)
if not "NumberOfPosts" in pl:
obj.addProperty("App::PropertyInteger", "NumberOfPosts", "Fence", QT_TRANSLATE_NOOP(
"App::Property", "The number of posts used to build the fence"))
obj.setEditorMode("NumberOfPosts", 1)
self.Type = "Fence"
def execute(self, obj):
import Part
pathwire = self.calculatePathWire(obj)
if not pathwire:
FreeCAD.Console.PrintLog(
"ArchFence.execute: path " + obj.Path.Name + " has no edges\n")
return
if not obj.Section:
FreeCAD.Console.PrintLog(
"ArchFence.execute: Section not set\n")
return
if not obj.Post:
FreeCAD.Console.PrintLog(
"ArchFence.execute: Post not set\n")
return
pathLength = pathwire.Length
sectionLength = obj.Section.Shape.BoundBox.XMax
postLength = obj.Post.Shape.BoundBox.XMax
obj.NumberOfSections = self.calculateNumberOfSections(
pathLength, sectionLength, postLength)
obj.NumberOfPosts = obj.NumberOfSections + 1
# We assume that the section was drawn in front view
# We have to rotate the shape down so that it is aligned correctly by the algorithm later on
downRotation = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), -90)
postPlacements = self.calculatePostPlacements(
obj, pathwire, downRotation)
postShapes = self.calculatePosts(obj, postPlacements)
sectionShapes = self.calculateSections(obj, postPlacements, postLength)
allShapes = []
allShapes.extend(postShapes)
allShapes.extend(sectionShapes)
compound = Part.makeCompound(allShapes)
self.applyShape(obj, compound, obj.Placement,
allowinvalid=True, allownosolid=True)
def calculateNumberOfSections(self, pathLength, sectionLength, postLength):
withoutLastPost = pathLength - postLength
realSectionLength = sectionLength + postLength
return math.ceil(withoutLastPost / realSectionLength)
def calculatePostPlacements(self, obj, pathwire, rotation):
postWidth = obj.Post.Shape.BoundBox.YMax
# We want to center the posts on the path. So move them the half width in
transformationVector = FreeCAD.Vector(0, - postWidth / 2, 0)
placements = Draft.calculatePlacementsOnPath(
rotation, pathwire, obj.NumberOfSections + 1, transformationVector, True)
# The placement of the last object is always the second entry in the list.
# So we move it to the end
placements.append(placements.pop(1))
return placements
def calculatePosts(self, obj, postPlacements):
posts = []
for placement in postPlacements:
postCopy = obj.Post.Shape.copy()
postCopy.Placement = placement
posts.append(postCopy)
return posts
def calculateSections(self, obj, postPlacements, postLength):
import Part
shapes = []
for i in range(obj.NumberOfSections):
startPlacement = postPlacements[i]
endPlacement = postPlacements[i + 1]
# print("start: %s, end: %s\n" % (startPlacement, endPlacement))
sectionLine = Part.LineSegment(
startPlacement.Base, endPlacement.Base)
sectionBase = sectionLine.value(postLength)
if startPlacement.Rotation.isSame(endPlacement.Rotation):
sectionRotation = endPlacement.Rotation
else:
direction = endPlacement.Base.sub(startPlacement.Base)
sectionRotation = FreeCAD.Rotation(EAST, direction)
placement = FreeCAD.Placement()
placement.Base = sectionBase
placement.Rotation = sectionRotation
sectionCopy = obj.Section.Shape.copy()
sectionCopy.Placement = placement
shapes.append(sectionCopy)
return shapes
def calculatePathWire(self, obj):
if (hasattr(obj.Path.Shape, 'Wires') and obj.Path.Shape.Wires):
return obj.Path.Shape.Wires[0]
elif obj.Path.Shape.Edges:
return Part.Wire(obj.Path.Shape.Edges)
return None
class _ViewProviderFence(ArchComponent.ViewProviderComponent):
"A View Provider for the Fence object"
def __init__(self, vobj):
ArchComponent.ViewProviderComponent.__init__(self, vobj)
def getIcon(self):
import Arch_rc
return ":/icons/Arch_Fence_Tree.svg"
def claimChildren(self):
children = []
if self.Object.Section:
children.append(self.Object.Section)
if self.Object.Post:
children.append(self.Object.Post)
if self.Object.Path:
children.append(self.Object.Path)
return children
class _CommandFence:
"the Arch Fence command definition"
def GetResources(self):
return {'Pixmap': 'Arch_Fence',
'MenuText': QT_TRANSLATE_NOOP("Arch_Fence", "Fence"),
'ToolTip': QT_TRANSLATE_NOOP("Arch_Fence", "Creates a fence object from a selected section, post and path")}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
if len(sel) != 3:
QtGui.QMessageBox.information(QtGui.QApplication.activeWindow(
), 'Arch Fence selection', 'Select a section, post and path in exactly this order to build a fence.')
return
section = sel[0]
post = sel[1]
path = sel[2]
buildFence(section, post, path)
def buildFence(section, post, path):
obj = FreeCAD.ActiveDocument.addObject(
'Part::FeaturePython', 'Fence')
_Fence(obj)
obj.Section = section
obj.Post = post
obj.Path = path
if FreeCAD.GuiUp:
_ViewProviderFence(obj.ViewObject)
hide(section)
hide(post)
hide(path)
FreeCAD.ActiveDocument.recompute()
def hide(obj):
if hasattr(obj, 'ViewObject') and obj.ViewObject:
obj.ViewObject.Visibility = False
if FreeCAD.GuiUp:
FreeCADGui.addCommand('Arch_Fence', _CommandFence())
if __name__ == '__main__':
# For testing purposes. When someone runs the File as a macro a default fence will be generated
import Part
def buildSection():
parts = []
parts.append(Part.makeBox(
2000, 50, 30, FreeCAD.Vector(0, 0, 1000 - 30)))
parts.append(Part.makeBox(2000, 50, 30))
parts.append(Part.makeBox(20, 20, 1000 -
60, FreeCAD.Vector(0, 15, 30)))
parts.append(Part.makeBox(20, 20, 1000 - 60,
FreeCAD.Vector(1980, 15, 30)))
for i in range(8):
parts.append(Part.makeBox(20, 20, 1000 - 60,
FreeCAD.Vector((2000 / 9 * (i + 1)) - 10, 15, 30)))
Part.show(Part.makeCompound(parts), "Section")
return FreeCAD.ActiveDocument.getObject('Section')
def buildPath():
sketch = FreeCAD.ActiveDocument.addObject(
'Sketcher::SketchObject', 'Path')
sketch.Placement = FreeCAD.Placement(
FreeCAD.Vector(0, 0, 0), FreeCAD.Rotation(0, 0, 0, 1))
sketch.addGeometry(Part.LineSegment(FreeCAD.Vector(
0, 0, 0), FreeCAD.Vector(20000, 0, 0)), False)
sketch.addGeometry(Part.LineSegment(FreeCAD.Vector(
20000, 0, 0), FreeCAD.Vector(20000, 20000, 0)), False)
return sketch
def buildPost():
post = Part.makeBox(100, 100, 1000, FreeCAD.Vector(0, 0, 0))
Part.show(post, "Post")
return FreeCAD.ActiveDocument.getObject('Post')
section = buildSection()
path = buildPath()
post = buildPost()
buildFence(section, post, path)

View File

@@ -38,7 +38,7 @@ class ArchWorkbench(Workbench):
"Arch_Window","Arch_Roof","Arch_AxisTools",
"Arch_SectionPlane","Arch_Space","Arch_Stairs",
"Arch_PanelTools","Arch_Equipment",
"Arch_Frame","Arch_MaterialTools","Arch_Schedule","Arch_PipeTools",
"Arch_Frame", "Arch_Fence", "Arch_MaterialTools","Arch_Schedule","Arch_PipeTools",
"Arch_CutPlane","Arch_Add","Arch_Remove","Arch_Survey"]
self.utilities = ["Arch_Component","Arch_CloneComponent","Arch_SplitMesh","Arch_MeshToShape",
"Arch_SelectNonSolidMeshes","Arch_RemoveShape",

View File

@@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2985"
version="1.1"
inkscape:version="0.92.1 r15371"
sodipodi:docname="Arch_Fence.svg">
<defs
id="defs2987">
<linearGradient
id="linearGradient3794">
<stop
style="stop-color:#d3d7cf;stop-opacity:1"
offset="0"
id="stop3796" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="1"
id="stop3798" />
</linearGradient>
<linearGradient
id="linearGradient3794-8">
<stop
style="stop-color:#ffb400;stop-opacity:1;"
offset="0"
id="stop3796-5" />
<stop
style="stop-color:#ffea00;stop-opacity:1;"
offset="1"
id="stop3798-8" />
</linearGradient>
<linearGradient
y2="23.848686"
x2="62.65237"
y1="23.848686"
x1="15.184971"
gradientTransform="matrix(1.0265568,0,0,0.91490626,-3.236706,-1.8027032)"
gradientUnits="userSpaceOnUse"
id="linearGradient3886"
xlink:href="#linearGradient3794-8"
inkscape:collect="always" />
<linearGradient
id="linearGradient3794-1">
<stop
style="stop-color:#ffb400;stop-opacity:1;"
offset="0"
id="stop3796-2" />
<stop
style="stop-color:#ffea00;stop-opacity:1;"
offset="1"
id="stop3798-2" />
</linearGradient>
<linearGradient
y2="23.848686"
x2="62.65237"
y1="23.848686"
x1="15.184971"
gradientTransform="matrix(1.0265568,0,0,0.91490626,-3.236706,-1.8027032)"
gradientUnits="userSpaceOnUse"
id="linearGradient3886-0"
xlink:href="#linearGradient3794-1"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.2080075"
inkscape:cx="27.389555"
inkscape:cy="21.184291"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1366"
inkscape:window-height="705"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:snap-global="true">
<inkscape:grid
type="xygrid"
id="grid2997"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2990">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:creator>
<cc:Agent>
<dc:title>[yorikvanhavre]</dc:title>
</cc:Agent>
</dc:creator>
<dc:title>Arch_Site_Tree</dc:title>
<dc:date>2011-12-06</dc:date>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Arch/Resources/icons/Arch_Site_Tree.svg</dc:identifier>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g4538">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path931-5"
d="M 3,43 H 61 V 35 H 3 Z"
style="fill:#edd400;fill-rule:evenodd;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path933-8"
d="m 5,37 v 4 h 54 v -4 z"
style="fill:none;fill-rule:evenodd;stroke:#fce94f;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g4534">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path931"
d="M 3,57 H 61 V 49 H 3 Z"
style="fill:#edd400;fill-rule:evenodd;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path933"
d="m 5,51 v 4 h 54 v -4 z"
style="fill:none;fill-rule:evenodd;stroke:#fce94f;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g4518">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path881"
d="M 5,61 V 27 l 5,-6 5,6 v 34 z"
style="fill:#edd400;fill-rule:evenodd;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path883"
d="M 7,59 V 28 l 3,-4 3,4 v 31 z"
style="fill:none;fill-rule:evenodd;stroke:#fce94f;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g4526">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path881-4"
d="M 49,61 V 27 l 5,-6 5,6 v 34 z"
style="fill:#edd400;fill-rule:evenodd;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path883-5"
d="M 51,59 V 28 l 3,-4 3,4 v 31 z"
style="fill:none;fill-rule:evenodd;stroke:#fce94f;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g4522">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path881-4-4"
d="M 27,61 V 27 l 5,-6 5,6 v 34 z"
style="fill:#edd400;fill-rule:evenodd;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path883-5-8"
d="M 29,59 V 28 l 3,-4 3,4 v 31 z"
style="fill:none;fill-rule:evenodd;stroke:#fce94f;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2985"
version="1.1"
inkscape:version="0.92.1 r15371"
sodipodi:docname="Arch_Fence_Tree.svg">
<defs
id="defs2987">
<linearGradient
id="linearGradient3794">
<stop
style="stop-color:#d3d7cf;stop-opacity:1"
offset="0"
id="stop3796" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="1"
id="stop3798" />
</linearGradient>
<linearGradient
id="linearGradient3794-8">
<stop
style="stop-color:#ffb400;stop-opacity:1;"
offset="0"
id="stop3796-5" />
<stop
style="stop-color:#ffea00;stop-opacity:1;"
offset="1"
id="stop3798-8" />
</linearGradient>
<linearGradient
y2="23.848686"
x2="62.65237"
y1="23.848686"
x1="15.184971"
gradientTransform="matrix(1.0265568,0,0,0.91490626,-3.236706,-1.8027032)"
gradientUnits="userSpaceOnUse"
id="linearGradient3886"
xlink:href="#linearGradient3794-8"
inkscape:collect="always" />
<linearGradient
id="linearGradient3794-1">
<stop
style="stop-color:#ffb400;stop-opacity:1;"
offset="0"
id="stop3796-2" />
<stop
style="stop-color:#ffea00;stop-opacity:1;"
offset="1"
id="stop3798-2" />
</linearGradient>
<linearGradient
y2="23.848686"
x2="62.65237"
y1="23.848686"
x1="15.184971"
gradientTransform="matrix(1.0265568,0,0,0.91490626,-3.236706,-1.8027032)"
gradientUnits="userSpaceOnUse"
id="linearGradient3886-0"
xlink:href="#linearGradient3794-1"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.2080075"
inkscape:cx="50.905069"
inkscape:cy="22.363535"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1366"
inkscape:window-height="705"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:snap-global="true">
<inkscape:grid
type="xygrid"
id="grid2997"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2990">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:creator>
<cc:Agent>
<dc:title>[yorikvanhavre]</dc:title>
</cc:Agent>
</dc:creator>
<dc:title>Arch_Site_Tree</dc:title>
<dc:date>2011-12-06</dc:date>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Arch/Resources/icons/Arch_Site_Tree.svg</dc:identifier>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
transform="translate(0,-12)"
id="g937-3">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path931-5"
d="M 3,55 H 61 V 47 H 3 Z"
style="fill:#babdb6;fill-rule:evenodd;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path933-8"
d="m 5,49 v 4 h 54 v -4 z"
style="fill:none;fill-rule:evenodd;stroke:#eeeeec;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g937"
transform="translate(0,2)">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path931"
d="M 3,55 H 61 V 47 H 3 Z"
style="fill:#babdb6;fill-rule:evenodd;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path933"
d="m 5,49 v 4 h 54 v -4 z"
style="fill:none;fill-rule:evenodd;stroke:#eeeeec;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g887"
transform="translate(2)">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path881"
d="M 3,61 V 27 l 5,-6 5,6 v 34 z"
style="fill:#babdb6;fill-rule:evenodd;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path883"
d="M 5,59 V 28 l 3,-4 3,4 v 31 z"
style="fill:none;fill-rule:evenodd;stroke:#eeeeec;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
transform="translate(46)"
id="g887-4">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path881-4"
d="M 3,61 V 27 l 5,-6 5,6 v 34 z"
style="fill:#babdb6;fill-rule:evenodd;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path883-5"
d="M 5,59 V 28 l 3,-4 3,4 v 31 z"
style="fill:none;fill-rule:evenodd;stroke:#eeeeec;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
transform="translate(24)"
id="g887-4-7">
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path881-4-4"
d="M 3,61 V 27 l 5,-6 5,6 v 34 z"
style="fill:#babdb6;fill-rule:evenodd;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path883-5-8"
d="M 5,59 V 28 l 3,-4 3,4 v 31 z"
style="fill:none;fill-rule:evenodd;stroke:#eeeeec;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.8 KiB