[OpenSCAD] Fix OpenSCAD bounding box calculations

When not using the GUI, bounding box calculations can sometimes use the
B-spline represenation in OCCT, which can in some cases give incorrect
results. To correct for this, explicit calls to tessellate() are added
to ensure that the bounding box calculation uses the true shape, even if
the GUI is not running.

Fixes #4622 - OpenSCAD/OpenSCADTest/app/test_importCSG.py assertion failure
This commit is contained in:
Chris Hennes
2021-08-17 11:09:55 -05:00
parent 785a5023c4
commit 274544d868
2 changed files with 4 additions and 5 deletions

View File

@@ -349,6 +349,7 @@ resize(newsize = [0,0,10], auto = [0,0,0]) {
}""", "resize_non_uniform_sphere")
object = doc.ActiveObject
self.assertTrue (object is not None)
object.Shape.tessellate(0.025) # To ensure the bounding box calculation is correct
self.assertAlmostEqual (object.Shape.BoundBox.XLength, 2*8.5, 1)
self.assertAlmostEqual (object.Shape.BoundBox.YLength, 2*8.5, 1)
self.assertAlmostEqual (object.Shape.BoundBox.ZLength, 10.0, 1)

View File

@@ -466,23 +466,19 @@ def p_minkowski_action(p):
def p_resize_action(p):
'''
resize_action : resize LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE '''
print(p[3])
new_size = p[3]['newsize']
auto = p[3]['auto']
print(new_size)
print(auto)
p[6][0].recompute()
if p[6][0].Shape.isNull():
doc.recompute()
p[6][0].Shape.tessellate(0.05)
old_bbox = p[6][0].Shape.BoundBox
print ("Old bounding box: " + str(old_bbox))
old_size = [old_bbox.XLength, old_bbox.YLength, old_bbox.ZLength]
for r in range(0,3) :
if auto[r] == '1' :
new_size[r] = new_size[0]
if new_size[r] == '0' :
new_size[r] = str(old_size[r])
print(new_size)
# Calculate a transform matrix from the current bounding box to the new one:
transform_matrix = FreeCAD.Matrix()
@@ -1314,8 +1310,10 @@ def p_projection_action(p) :
if printverbose: print('Projection')
doc.recompute()
p[6][0].Shape.tessellate(0.05) # Ensure the bounding box calculation is not done with the splines, which can give a bad result
bbox = p[6][0].Shape.BoundBox
for shape in p[6]:
shape.Shape.tessellate(0.05)
bbox.add(shape.Shape.BoundBox)
print (bbox)
plane = doc.addObject("Part::Plane","xy_plane_used_for_projection")