From 35709cc7e41664fb711713b17a020834f1dfdac9 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Thu, 14 Feb 2013 18:37:14 -0200 Subject: [PATCH] Arch: General optimization --- src/Mod/Arch/ArchCell.py | 2 + src/Mod/Arch/ArchComponent.py | 109 +++++++++++++++++++++++++++++++++- src/Mod/Arch/ArchRoof.py | 18 ++++-- src/Mod/Arch/ArchStructure.py | 17 ++---- src/Mod/Arch/ArchWall.py | 63 ++------------------ src/Mod/Arch/ArchWindow.py | 39 +++--------- 6 files changed, 139 insertions(+), 109 deletions(-) diff --git a/src/Mod/Arch/ArchCell.py b/src/Mod/Arch/ArchCell.py index 6c4527ce5c..73fa2d21f3 100644 --- a/src/Mod/Arch/ArchCell.py +++ b/src/Mod/Arch/ArchCell.py @@ -21,6 +21,8 @@ #* * #*************************************************************************** +#### WARNING: CELL OBJECT IS OBSOLETED + import FreeCAD,FreeCADGui,Draft,ArchComponent,ArchCommands from FreeCAD import Vector from PyQt4 import QtCore diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index e455aba28f..14262a44bd 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -266,13 +266,120 @@ class Component: self.Type = "Component" self.Subvolume = None + def __getstate__(self): return self.Type + def __setstate__(self,state): if state: self.Type = state - + + + def getSubVolume(self,base,width,plac=None): + "returns a subvolume from a base object" + import Part,DraftVecUtils + + # finding biggest wire in the base shape + max_length = 0 + f = None + for w in base.Shape.Wires: + if w.BoundBox.DiagonalLength > max_length: + max_length = w.BoundBox.DiagonalLength + f = w + if f: + f = Part.Face(f) + n = f.normalAt(0,0) + v1 = DraftVecUtils.scaleTo(n,width*1.1) # we extrude a little more to avoid face-on-face + f.translate(v1) + v2 = DraftVecUtils.neg(v1) + v2 = DraftVecUtils.scale(v1,-2) + f = f.extrude(v2) + if plac: + f.Placement = plac + return f + return None + + + def hideSubobjects(self,obj,prop): + "Hides subobjects when a subobject lists change" + if prop in ["Additions","Subtractions"]: + if hasattr(obj,prop): + for o in getattr(obj,prop): + o.ViewObject.hide() + + def processSubShapes(self,obj,base): + "Adds additions and subtractions to a base shape" + import Draft + + # treat additions + for o in obj.Additions: + + if base: + if base.isNull(): + base = None + + if (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window")): + if base: + # windows can be additions or subtractions, treated the same way + if hasattr(self,"Width"): + width = self.Width + else: + b = base.BoundBox + width = max(b.XLength,b.YLength,b.ZLength) + if Draft.isClone(o,"Window"): + window = o.Objects[0] + else: + window = o + if window.Base and width: + f = self.getSubVolume(window.Base,width) + if f: + if base.Solids and f.Solids: + base = base.cut(f) + + elif o.isDerivedFrom("Part::Feature"): + if o.Shape: + if not o.Shape.isNull(): + if o.Shape.Solids: + if base: + if base.Solids: + base = base.fuse(o.Shape) + else: + base = o.Shape + + # treat subtractions + for o in obj.Subtractions: + + if base: + if base.isNull(): + base = None + + if base: + if (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window")): + # windows can be additions or subtractions, treated the same way + if hasattr(self,"Width"): + width = self.Width + else: + b = base.BoundBox + width = max(b.XLength,b.YLength,b.ZLength) + if Draft.isClone(o,"Window"): + window = o.Objects[0] + else: + window = o + if window.Base and width: + f = self.getSubVolume(window.Base,width) + if f: + if base.Solids and f.Solids: + base = base.cut(f) + + elif o.isDerivedFrom("Part::Feature"): + if o.Shape: + if not o.Shape.isNull(): + if o.Shape.Solids and base.Solids: + base = base.cut(o.Shape) + return base + + class ViewProviderComponent: "A default View Provider for Component objects" def __init__(self,vobj): diff --git a/src/Mod/Arch/ArchRoof.py b/src/Mod/Arch/ArchRoof.py index 03c3173c95..8b20daf5a9 100644 --- a/src/Mod/Arch/ArchRoof.py +++ b/src/Mod/Arch/ArchRoof.py @@ -99,6 +99,7 @@ class _Roof(ArchComponent.Component): self.createGeometry(obj) def onChanged(self,obj,prop): + self.hideSubobjects(obj,prop) if prop in ["Base","Face","Angle","Additions","Subtractions"]: self.createGeometry(obj) @@ -106,6 +107,7 @@ class _Roof(ArchComponent.Component): import Part, math, DraftGeomUtils pl = obj.Placement + base = None if obj.Base and obj.Angle: w = None if obj.Base.isDerivedFrom("Part::Feature"): @@ -134,14 +136,18 @@ class _Roof(ArchComponent.Component): dv.normalize() dv.scale(d,d,d) shps.append(f.extrude(dv)) - c = shps.pop() + base = shps.pop() for s in shps: - c = c.common(s) - c = c.removeSplitter() - if not c.isNull(): - obj.Shape = c + base = base.common(s) + base = base.removeSplitter() + if not base.isNull(): if not DraftGeomUtils.isNull(pl): - obj.Placement = pl + base.Placement = pl + + base = self.processSubShapes(obj,base) + if base: + if not base.isNull(): + obj.Shape = base class _ViewProviderRoof(ArchComponent.ViewProviderComponent): "A View Provider for the Roof object" diff --git a/src/Mod/Arch/ArchStructure.py b/src/Mod/Arch/ArchStructure.py index 6787142d1f..7b6c5ff6a1 100644 --- a/src/Mod/Arch/ArchStructure.py +++ b/src/Mod/Arch/ArchStructure.py @@ -108,6 +108,7 @@ class _Structure(ArchComponent.Component): self.createGeometry(obj) def onChanged(self,obj,prop): + self.hideSubobjects(obj,prop) if prop in ["Base","Length","Width","Height","Normal","Additions","Subtractions","Axes"]: self.createGeometry(obj) @@ -189,20 +190,9 @@ class _Structure(ArchComponent.Component): base = Part.Face(base) base = base.extrude(normal) + base = self.processSubShapes(obj,base) + if base: - # applying adds and subs - if not base.isNull(): - for app in obj.Additions: - if hasattr(app,"Shape"): - if not app.Shape.isNull(): - base = base.fuse(app.Shape) - app.ViewObject.hide() # to be removed - for hole in obj.Subtractions: - if hasattr(hole,"Shape"): - if not hole.Shape.isNull(): - base = base.cut(hole.Shape) - hole.ViewObject.hide() # to be removed - # applying axes pts = self.getAxisPoints(obj) apl = self.getAxisPlacement(obj) @@ -220,6 +210,7 @@ class _Structure(ArchComponent.Component): obj.Shape = Part.makeCompound(fsh) # finalizing + else: if base: if not base.isNull(): diff --git a/src/Mod/Arch/ArchWall.py b/src/Mod/Arch/ArchWall.py index be5be69a8f..9369e251eb 100644 --- a/src/Mod/Arch/ArchWall.py +++ b/src/Mod/Arch/ArchWall.py @@ -267,31 +267,10 @@ class _Wall(ArchComponent.Component): self.createGeometry(obj) def onChanged(self,obj,prop): + self.hideSubobjects(obj,prop) if prop in ["Base","Height","Width","Align","Additions","Subtractions"]: self.createGeometry(obj) - def getSubVolume(self,base,width,plac=None): - "returns a subvolume from a base object" - import Part - max_length = 0 - f = None - for w in base.Shape.Wires: - if w.BoundBox.DiagonalLength > max_length: - max_length = w.BoundBox.DiagonalLength - f = w - if f: - f = Part.Face(f) - n = f.normalAt(0,0) - v1 = DraftVecUtils.scaleTo(n,width) - f.translate(v1) - v2 = DraftVecUtils.neg(v1) - v2 = DraftVecUtils.scale(v1,-2) - f = f.extrude(v2) - if plac: - f.Placement = plac - return f - return None - def createGeometry(self,obj): "builds the wall shape" @@ -393,44 +372,10 @@ class _Wall(ArchComponent.Component): else: FreeCAD.Console.PrintWarning(str(translate("Arch","This mesh is an invalid solid"))) obj.Base.ViewObject.show() - + + base = self.processSubShapes(obj,base) + if base: - - for app in obj.Additions: - if Draft.getType(app) == "Window": - # window - if app.Base and obj.Width: - f = self.getSubVolume(app.Base,width) - if f: - base = base.cut(f) - elif Draft.isClone(app,"Window"): - if app.Objects[0].Base and width: - f = self.getSubVolume(app.Objects[0].Base,width,app.Placement) - if f: - base = base.cut(f) - elif app.isDerivedFrom("Part::Feature"): - if app.Shape: - if not app.Shape.isNull(): - base = base.fuse(app.Shape) - app.ViewObject.hide() #to be removed - for hole in obj.Subtractions: - if Draft.getType(hole) == "Window": - # window - if hole.Base and obj.Width: - f = self.getSubVolume(hole.Base,width) - if f: - base = base.cut(f) - elif Draft.isClone(hole,"Window"): - if hole.Objects[0].Base and width: - f = self.getSubVolume(hole.Objects[0].Base,width,hole.Placement) - if f: - base = base.cut(f) - elif hole.isDerivedFrom("Part::Feature"): - if hole.Shape: - if not hole.Shape.isNull(): - base = base.cut(hole.Shape) - hole.ViewObject.hide() # to be removed - if not base.isNull(): if base.isValid() and base.Solids: if base.Volume < 0: diff --git a/src/Mod/Arch/ArchWindow.py b/src/Mod/Arch/ArchWindow.py index 2b5ac4275d..9768caf002 100644 --- a/src/Mod/Arch/ArchWindow.py +++ b/src/Mod/Arch/ArchWindow.py @@ -120,12 +120,14 @@ class _Window(ArchComponent.Component): self.createGeometry(obj) def onChanged(self,obj,prop): + self.hideSubobjects(obj,prop) if prop in ["Base","WindowParts"]: self.createGeometry(obj) def createGeometry(self,obj): import Part, DraftGeomUtils pl = obj.Placement + base = None if obj.Base: if obj.Base.isDerivedFrom("Part::Feature"): if hasattr(obj,"WindowParts"): @@ -163,37 +165,14 @@ class _Window(ArchComponent.Component): shape.translate(zov) shapes.append(shape) if shapes: - obj.Shape = Part.makeCompound(shapes) + base = Part.makeCompound(shapes) if not DraftGeomUtils.isNull(pl): - obj.Placement = pl - - # processing additions and subtractions - sh = obj.Shape - for app in obj.Additions: - if app.isDerivedFrom("Part::Feature"): - if app.Shape: - if not app.Shape.isNull(): - if sh.isNull(): - sh = app.Shape - else: - if sh.Solids and app.Shape.Solids: - sh = sh.fuse(app.Shape) - app.ViewObject.hide() #to be removed - else: - print "ArchWindow: shape not solid" - for hole in obj.Subtractions: - if hole.isDerivedFrom("Part::Feature"): - if hole.Shape: - if not hole.Shape.isNull(): - if not sh.isNull(): - if sh.Solids and hole.Shape.Solids: - sh = sh.cut(hole.Shape) - hole.ViewObject.hide() # to be removed - else: - print "ArchWindow: shape not solid" - if not sh.isNull(): - sh.removeSplitter() - obj.Shape = sh + base.Placement = pl + + base = self.processSubShapes(obj,base) + if base: + if not base.isNull(): + obj.Shape = base class _ViewProviderWindow(ArchComponent.ViewProviderComponent): "A View Provider for the Window object"