From b469c237b54e2d4e52b61c9d12fe99ae4c75f931 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Tue, 28 Aug 2018 21:03:25 -0300 Subject: [PATCH] Arch: cache svg calculations in section planes/techdraw views for better performance --- src/Mod/Arch/ArchSectionPlane.py | 151 ++++++++++++++++++------------- src/Mod/Draft/WorkingPlane.py | 7 +- 2 files changed, 92 insertions(+), 66 deletions(-) diff --git a/src/Mod/Arch/ArchSectionPlane.py b/src/Mod/Arch/ArchSectionPlane.py index d1c7da2ce5..4f85564009 100644 --- a/src/Mod/Arch/ArchSectionPlane.py +++ b/src/Mod/Arch/ArchSectionPlane.py @@ -164,6 +164,7 @@ def getSVG(section, renderMode="Wireframe", allOn=False, showHidden=False, scale objs = Draft.getGroupContents(section.Objects,walls=True,addgroups=True) if not allOn: objs = Draft.removeHidden(objs) + # separate spaces and Draft objects spaces = [] nonspaces = [] @@ -196,73 +197,95 @@ def getSVG(section, renderMode="Wireframe", allOn=False, showHidden=False, scale fillpattern += ' x="0" y="0" width="10" height="10">' fillpattern += '' fillpattern += '' + svgLineColor = Draft.getrgb(lineColor) svg = '' + # reading cached version + svgcache = None + if hasattr(section.Proxy,"svgcache") and section.Proxy.svgcache: + svgcache = section.Proxy.svgcache[0] + if section.Proxy.svgcache[1] != renderMode: + svgcache = None + if section.Proxy.svgcache[2] != showHidden: + svgcache = None + if section.Proxy.svgcache[3] != showFill: + svgcache = None + # generating SVG if renderMode in ["Solid",1]: - # render using the Arch Vector Renderer - import ArchVRM, WorkingPlane - wp = WorkingPlane.plane() - wp.setFromPlacement(section.Placement) - #wp.inverse() - render = ArchVRM.Renderer() - render.setWorkingPlane(wp) - render.addObjects(objs) - if showHidden: - render.cut(section.Shape,showHidden) - else: - render.cut(section.Shape) - svg += '\n' - svg += render.getViewSVG(linewidth=svgLineWidth) - svg += fillpattern - svg += render.getSectionSVG(linewidth=svgCutLineWidth, - fillpattern="sectionfill") - if showHidden: - svg += render.getHiddenSVG(linewidth=svgLineWidth) - svg += '\n' - # print(render.info()) - + if not svgcache: + svgcache = '' + # render using the Arch Vector Renderer + import ArchVRM, WorkingPlane + wp = WorkingPlane.plane() + wp.setFromPlacement(section.Placement) + #wp.inverse() + render = ArchVRM.Renderer() + render.setWorkingPlane(wp) + render.addObjects(objs) + if showHidden: + render.cut(section.Shape,showHidden) + else: + render.cut(section.Shape) + svgcache += '\n' + svgcache += render.getViewSVG(linewidth="SVGLINEWIDTH") + svgcache += fillpattern + svgcache += render.getSectionSVG(linewidth="SVGCUTLINEWIDTH", + fillpattern="sectionfill") + if showHidden: + svgcache += render.getHiddenSVG(linewidth="SVGLINEWIDTH") + svgcache += '\n' + # print(render.info()) + section.Proxy.svgcache = [svgcache,renderMode,showHidden,showFill] else: - # render using the Drawing module - import Drawing, Part - shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden) - if shapes: - baseshape = Part.makeCompound(shapes) - style = {'stroke': Draft.getrgb(lineColor), - 'stroke-width': svgLineWidth} - svg += Drawing.projectToSVG( - baseshape, direction, - hStyle=style, h0Style=style, h1Style=style, - vStyle=style, v0Style=style, v1Style=style) - if hshapes: - hshapes = Part.makeCompound(hshapes) - style = {'stroke': Draft.getrgb(lineColor), - 'stroke-width': svgLineWidth, - 'stroke-dasharray': svgHiddenPattern} - svg += Drawing.projectToSVG( - hshapes, direction, - hStyle=style, h0Style=style, h1Style=style, - vStyle=style, v0Style=style, v1Style=style) - if sshapes: - if showFill: - #svg += fillpattern - svg += '\n' - for s in sshapes: - if s.Edges: - #svg += Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0)) - # temporarily disabling fill patterns - svg += Draft.getSVG(s, direction=direction.negative(), - linewidth=0, - fillstyle=Draft.getrgb(fillColor), - color=lineColor) - svg += "\n" - sshapes = Part.makeCompound(sshapes) - style = {'stroke': Draft.getrgb(lineColor), - 'stroke-width': svgCutLineWidth} - svg += Drawing.projectToSVG( - sshapes, direction, - hStyle=style, h0Style=style, h1Style=style, - vStyle=style, v0Style=style, v1Style=style) + if not svgcache: + svgcache = "" + # render using the Drawing module + import Drawing, Part + shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden) + if shapes: + baseshape = Part.makeCompound(shapes) + style = {'stroke': "SVGLINECOLOR", + 'stroke-width': "SVGLINEWIDTH"} + svgcache += Drawing.projectToSVG( + baseshape, direction, + hStyle=style, h0Style=style, h1Style=style, + vStyle=style, v0Style=style, v1Style=style) + if hshapes: + hshapes = Part.makeCompound(hshapes) + style = {'stroke': "SVGLINECOLOR", + 'stroke-width': "SVGLINEWIDTH", + 'stroke-dasharray': "SVGHIDDENPATTERN"} + svgcache += Drawing.projectToSVG( + hshapes, direction, + hStyle=style, h0Style=style, h1Style=style, + vStyle=style, v0Style=style, v1Style=style) + if sshapes: + if showFill: + #svgcache += fillpattern + svgcache += '\n' + for s in sshapes: + if s.Edges: + #svg += Draft.getSVG(s,direction=direction.negative(),linewidth=0,fillstyle="sectionfill",color=(0,0,0)) + # temporarily disabling fill patterns + svgcache += Draft.getSVG(s, direction=direction.negative(), + linewidth=0, + fillstyle=Draft.getrgb(fillColor), + color=lineColor) + svgcache += "\n" + sshapes = Part.makeCompound(sshapes) + style = {'stroke': "SVGLINECOLOR", + 'stroke-width': "SVGCUTLINEWIDTH"} + svgcache += Drawing.projectToSVG( + sshapes, direction, + hStyle=style, h0Style=style, h1Style=style, + vStyle=style, v0Style=style, v1Style=style) + section.Proxy.svgcache = [svgcache,renderMode,showHidden,showFill] + svgcache = svgcache.replace("SVGLINECOLOR",svgLineColor) + svgcache = svgcache.replace("SVGLINEWIDTH",svgLineWidth) + svgcache = svgcache.replace("SVGHIDDENPATTERN",svgHiddenPattern) + svgcache = svgcache.replace("SVGCUTLINEWIDTH",svgCutLineWidth) + svg += svgcache if drafts: if not techdraw: @@ -443,7 +466,9 @@ class _SectionPlane: def onChanged(self,obj,prop): - pass + # clean svg cache if needed + if prop in ["Placement","Objects","OnlySolids"]: + self.svgcache = None def getNormal(self,obj): diff --git a/src/Mod/Draft/WorkingPlane.py b/src/Mod/Draft/WorkingPlane.py index 0e9e68c76d..ea708ca1d3 100644 --- a/src/Mod/Draft/WorkingPlane.py +++ b/src/Mod/Draft/WorkingPlane.py @@ -306,9 +306,10 @@ class plane: # Arch active container if FreeCAD.GuiUp: import FreeCADGui - a = FreeCADGui.ActiveDocument.ActiveView.getActiveObject("Arch") - if a: - p = a.Placement.inverse().multiply(p) + if FreeCADGui.ActiveDocument.ActiveView: + a = FreeCADGui.ActiveDocument.ActiveView.getActiveObject("Arch") + if a: + p = a.Placement.inverse().multiply(p) return p def getPlacement(self,rotated=False):