Arch: General optimization

This commit is contained in:
Yorik van Havre 2013-02-14 18:37:14 -02:00
parent af529e2603
commit 35709cc7e4
6 changed files with 139 additions and 109 deletions

View File

@ -21,6 +21,8 @@
#* *
#***************************************************************************
#### WARNING: CELL OBJECT IS OBSOLETED
import FreeCAD,FreeCADGui,Draft,ArchComponent,ArchCommands
from FreeCAD import Vector
from PyQt4 import QtCore

View File

@ -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):

View File

@ -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"

View File

@ -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():

View File

@ -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:

View File

@ -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"