From 41b85bb8cd9d62760487e9177d153f9b69ef484d Mon Sep 17 00:00:00 2001 From: furti Date: Wed, 20 Feb 2019 18:31:22 +0100 Subject: [PATCH] Add option to fill cut shapes with material colors Previously when setting the "Show Fill" property of the TechDraw Arch Section View to true, the areas where always filled with a default grey color. This commit adds a property called "UseMaterialColorForFill" to the ArchSectionPlane. When set to true, it will use the objects material color to fill the cut shapes and fall back to the default color when no Material is found. --- src/Mod/Arch/ArchSectionPlane.py | 109 ++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 37 deletions(-) diff --git a/src/Mod/Arch/ArchSectionPlane.py b/src/Mod/Arch/ArchSectionPlane.py index 1549cc0676..076b123380 100644 --- a/src/Mod/Arch/ArchSectionPlane.py +++ b/src/Mod/Arch/ArchSectionPlane.py @@ -108,50 +108,77 @@ def looksLikeDraft(o): # If we have a shape, but no volume, it looks like a flat 2D object return o.Shape.Volume == 0 -def getCutShapes(objs,section,showHidden): +def getCutShapes(objs,section,showHidden,groupSshapesByObject=False): import Part,DraftGeomUtils shapes = [] hshapes = [] sshapes = [] + objectShapes = [] + objectSshapes = [] for o in objs: if o.isDerivedFrom("Part::Feature"): if o.Shape.isNull(): pass elif section.OnlySolids: if o.Shape.isValid(): - shapes.extend(o.Shape.Solids) + solids = [] + solids.extend(o.Shape.Solids) + + shapes.extend(solids) + + objectShapes.append((o, solids)) else: print(section.Label,": Skipping invalid object:",o.Label) else: shapes.append(o.Shape) + objectShapes.append((o, [o.Shape])) cutface,cutvolume,invcutvolume = ArchCommands.getCutVolume(section.Shape.copy(),shapes) if cutvolume: - nsh = [] - for sh in shapes: - for sol in sh.Solids: - if sol.Volume < 0: - sol.reverse() - c = sol.cut(cutvolume) - s = sol.section(cutface) - try: - wires = DraftGeomUtils.findWires(s.Edges) - for w in wires: - f = Part.Face(w) - sshapes.append(f) - #s = Part.Wire(s.Edges) - #s = Part.Face(s) - except Part.OCCError: - #print "ArchDrawingView: unable to get a face" - sshapes.append(s) - nsh.extend(c.Solids) - #sshapes.append(s) - if showHidden: - c = sol.cut(invcutvolume) - hshapes.append(c) - shapes = nsh - return shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume + for o, shapeList in objectShapes: + tmpSshapes = [] + for sh in shapeList: + for sol in sh.Solids: + if sol.Volume < 0: + sol.reverse() + c = sol.cut(cutvolume) + s = sol.section(cutface) + try: + wires = DraftGeomUtils.findWires(s.Edges) + for w in wires: + f = Part.Face(w) + tmpSshapes.append(f) + #s = Part.Wire(s.Edges) + #s = Part.Face(s) + except Part.OCCError: + #print "ArchDrawingView: unable to get a face" + tmpSshapes.append(s) + shapes.extend(c.Solids) + #sshapes.append(s) + if showHidden: + c = sol.cut(invcutvolume) + hshapes.append(c) + if len(tmpSshapes) > 0: + sshapes.extend(tmpSshapes) + + if groupSshapesByObject: + objectSshapes.append((o, tmpSshapes)) + + if groupSshapesByObject: + return shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume,objectSshapes + else: + return shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume + +def getFillForObject(o, defaultFill, section): + if hasattr(section, 'UseMaterialColorForFill') and section.UseMaterialColorForFill: + if hasattr(o, 'Material') and o.Material: + material = o.Material + + if hasattr(material, 'Color') and material.Color: + return o.Material.Color + + return defaultFill def getSVG(section, renderMode="Wireframe", allOn=False, showHidden=False, scale=1, rotation=0, linewidth=1, lineColor=(0.0,0.0,0.0), fontsize=1, showFill=False, fillColor=(0.8,0.8,0.8), techdraw=False): @@ -252,8 +279,11 @@ def getSVG(section, renderMode="Wireframe", allOn=False, showHidden=False, scale # print(render.info()) section.Proxy.svgcache = [svgcache,renderMode,showHidden,showFill] else: - shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden) - + if showFill: + shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume,objectSshapes = getCutShapes(objs,section,showHidden, True) + else: + shapes,hshapes,sshapes,cutface,cutvolume,invcutvolume = getCutShapes(objs,section,showHidden) + if not svgcache: svgcache = "" # render using the Drawing module @@ -279,14 +309,16 @@ def getSVG(section, renderMode="Wireframe", allOn=False, showHidden=False, scale 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) + for o, shapes in objectSshapes: + for s in shapes: + if s.Edges: + objectFill = getFillForObject(o, fillColor, section) + #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(objectFill), + color=lineColor) svgcache += "\n" sshapes = Part.makeCompound(sshapes) style = {'stroke': "SVGLINECOLOR", @@ -453,6 +485,9 @@ class _SectionPlane: if not "OnlySolids" in pl: obj.addProperty("App::PropertyBool","OnlySolids","SectionPlane",QT_TRANSLATE_NOOP("App::Property","If false, non-solids will be cut too, with possible wrong results.")) obj.OnlySolids = True + if not "UseMaterialColorForFill" in pl: + obj.addProperty("App::PropertyBool","UseMaterialColorForFill","SectionPlane",QT_TRANSLATE_NOOP("App::Property","If true, the color of the objects material will be used to fill cut areas.")) + obj.UseMaterialColorForFill = False self.Type = "SectionPlane" def onDocumentRestored(self,obj): @@ -482,7 +517,7 @@ class _SectionPlane: def onChanged(self,obj,prop): # clean svg cache if needed - if prop in ["Placement","Objects","OnlySolids"]: + if prop in ["Placement","Objects","OnlySolids","UseMaterialColorForFill"]: self.svgcache = None def getNormal(self,obj):