1. Add CenterOfBoundBox() and CombinedCenterOfBoundBox() functions into Shape class; 2. Add another parameter centerOption into CQ.workplane([offset, invert]), and default the parameter to CenterOfMass which is the current behavior.

This commit is contained in:
Youbao Zhang 2015-11-21 15:00:55 +00:00
parent 146ecd589b
commit f7738dd857
2 changed files with 44 additions and 4 deletions

View File

@ -262,7 +262,7 @@ class CQ(object):
return self.objects[0].wrapped
def workplane(self, offset=0.0, invert=False):
def workplane(self, offset=0.0, invert=False, centerOption='CenterOfMass'):
"""
Creates a new 2-D workplane, located relative to the first face on the stack.
@ -341,7 +341,11 @@ class CQ(object):
if not all(_isCoPlanar(self.objects[0], f) for f in self.objects[1:]):
raise ValueError("Selected faces must be co-planar.")
center = Shape.CombinedCenter(self.objects)
if centerOption == 'CenterOfMass':
center = Shape.CombinedCenter(self.objects)
elif centerOption == 'CenterOfBoundBox':
center = Shape.CombinedCenterOfBoundBox(self.objects)
normal = self.objects[0].normalAt()
xDir = _computeXdir(normal)
@ -349,12 +353,18 @@ class CQ(object):
obj = self.objects[0]
if isinstance(obj, Face):
center = obj.Center()
if centerOption == 'CenterOfMass':
center = obj.Center()
elif centerOption == 'CenterOfBoundBox':
center = obj.CenterOfBoundBox()
normal = obj.normalAt(center)
xDir = _computeXdir(normal)
else:
if hasattr(obj, 'Center'):
center = obj.Center()
if centerOption == 'CenterOfMass':
center = obj.Center()
elif centerOption == 'CenterOfBoundBox':
center = obj.CenterOfBoundBox()
normal = self.plane.zDir
xDir = self.plane.xDir
else:

View File

@ -199,6 +199,20 @@ class Shape(object):
else:
raise ValueError("Cannot find the center of %s object type" % str(type(self.Solids()[0].wrapped)))
def CenterOfBoundBox(self):
if isinstance(self.wrapped, FreeCADPart.Shape):
# If there are no Solids, we're probably dealing with a Face or something similar
if len(self.Solids()) == 0:
return Vector(self.wrapped.BoundBox.Center)
elif len(self.Solids()) == 1:
return Vector(self.Solids()[0].wrapped.BoundBox.Center)
elif len(self.Solids()) > 1:
return self.CombinedCenterOfBoundBox(self.Solids())
elif isinstance(self.wrapped, FreeCADPart.Solid):
return Vector(self.wrapped.BoundBox.Center)
else:
raise ValueError("Cannot find the center(BoundBox's) of %s object type" % str(type(self.Solids()[0].wrapped)))
@staticmethod
def CombinedCenter(objects):
"""
@ -215,6 +229,22 @@ class Shape(object):
return Vector(sum_wc.multiply(1./total_mass))
@staticmethod
def CombinedCenterOfBoundBox(objects):
"""
Calculates the center of BoundBox of multiple objects.
:param objects: a list of objects with mass 1
"""
total_mass = len(objects)
weighted_centers = [o.wrapped.BoundBox.Center.multiply(1.0) for o in objects]
sum_wc = weighted_centers[0]
for wc in weighted_centers[1:] :
sum_wc = sum_wc.add(wc)
return Vector(sum_wc.multiply(1./total_mass))
def Closed(self):
return self.wrapped.Closed