diff --git a/src/Mod/OpenSCAD/CMakeLists.txt b/src/Mod/OpenSCAD/CMakeLists.txt index f77a9d599b..a60d1225f0 100644 --- a/src/Mod/OpenSCAD/CMakeLists.txt +++ b/src/Mod/OpenSCAD/CMakeLists.txt @@ -41,6 +41,8 @@ SET(OpenSCADTestsFiles_SRCS OpenSCADTest/data/__init__.py OpenSCADTest/data/CSG.scad OpenSCADTest/data/CSG.csg + OpenSCADTest/data/Cube.stl + OpenSCADTest/data/Square.dxf ) SET(OpenSCADTests_ALL diff --git a/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py b/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py index fb4f0d7cd5..1f493461d3 100644 --- a/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py +++ b/src/Mod/OpenSCAD/OpenSCADTest/app/test_importCSG.py @@ -41,7 +41,6 @@ class TestImportCSG(unittest.TestCase): def setUp(self): self.test_dir = join(FreeCAD.getHomePath(), "Mod", "OpenSCAD", "OpenSCADTest", "data") - pass def test_open_scad(self): testfile = join(self.test_dir, "CSG.scad") @@ -141,7 +140,7 @@ class TestImportCSG(unittest.TestCase): with tempfile.TemporaryDirectory() as temp_dir: filename = temp_dir + os.pathsep + "text.scad" f = open(filename,"w+") - f.write("text(\"FreeCAD\");") + f.write("text(\"X\");") # Keep it short to keep the test fast-ish f.close() try: doc = importCSG.open(filename) @@ -196,21 +195,127 @@ polyhedron( self.assertAlmostEqual (polyhedron.Shape.Volume, 1333.3333, 4) FreeCAD.closeDocument(doc.Name) + def utility_create_scad(self, scadCode, name): + with tempfile.TemporaryDirectory() as temp_dir: + filename = temp_dir + os.pathsep + name + ".scad" + f = open(filename,"w+") + f.write(scadCode) + f.close() + return importCSG.open(filename) -""" -Actions to test: ------------------ -difference_action -intersection_action -union_action -rotate_extrude_action -linear_extrude_with_twist -rotate_extrude_file -import_file1 -resize_action -surface_action -projection_action -hull_action -minkowski_action -offset_action -""" \ No newline at end of file + def test_import_difference(self): + doc = self.utility_create_scad("difference() { cube(15, center=true); sphere(10); }", "difference") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 266.1323, 3) + FreeCAD.closeDocument(doc.Name) + + def test_import_intersection(self): + doc = self.utility_create_scad("intersection() { cube(15, center=true); sphere(10); }", "intersection") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 3108.8677, 3) + FreeCAD.closeDocument(doc.Name) + + def test_import_union(self): + doc = self.utility_create_scad("union() { cube(15, center=true); sphere(10); }", "union") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 4454.9224, 3) + FreeCAD.closeDocument(doc.Name) + + def test_import_rotate_extrude(self): + doc = self.utility_create_scad("rotate_extrude() translate([10, 0]) square(5);", "rotate_extrude_simple") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 1963.4954, 3) + FreeCAD.closeDocument(doc.Name) + + doc = self.utility_create_scad("translate([0, 30, 0]) rotate_extrude($fn = 80) polygon( points=[[0,0],[8,4],[4,8],[4,12],[12,16],[0,20]] );", "rotate_extrude_no_hole") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 2412.7431, 3) + FreeCAD.closeDocument(doc.Name) + + def test_import_linear_extrude(self): + doc = self.utility_create_scad("linear_extrude(height = 20) square([20, 10], center = true);", "linear_extrude_simple") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 4000.000, 3) + FreeCAD.closeDocument(doc.Name) + + doc = self.utility_create_scad("linear_extrude(height = 20, scale = 0.2) square([20, 10], center = true);", "linear_extrude_scale") + object = doc.ActiveObject + # Not actually supported - this does not create a frustum, but a cube: scale does nothing + FreeCAD.closeDocument(doc.Name) + + doc = self.utility_create_scad("linear_extrude(height = 20, twist = 90) square([20, 10], center = true);", "linear_extrude_twist") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 3999.9961, 3) + FreeCAD.closeDocument(doc.Name) + + def test_import_rotate_extrude_file(self): + # OpenSCAD doesn't seem to have this feature at this time (March 2021) + pass + +# There is a problem with the DXF code right now, it doesn't like this square. +# def test_import_import_dxf(self): +# testfile = join(self.test_dir, "Square.dxf").replace('\\','/') +# doc = self.utility_create_scad("import(\"{}\");".format(testfile), "import_dxf"); +# object = doc.ActiveObject +# self.assertTrue (object is not None) +# FreeCAD.closeDocument(doc.Name) + + def test_import_import_stl(self): + testfile = join(self.test_dir, "Cube.stl").replace('\\','/') + doc = self.utility_create_scad("import(\"{}\");".format(testfile), "import_stl"); + object = doc.ActiveObject + self.assertTrue (object is not None) + FreeCAD.closeDocument(doc.Name) + + def test_import_resize(self): + doc = self.utility_create_scad("resize([2,2,2]) cube();", "resize_simple") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 8.000000, 6) + FreeCAD.closeDocument(doc.Name) + + doc = self.utility_create_scad("resize([2,2,0]) cube();", "resize_with_zero") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 4.000000, 6) + FreeCAD.closeDocument(doc.Name) + + doc = self.utility_create_scad("resize([2,0,0], auto=true) cube();", "resize_with_auto") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 8.000000, 6) + FreeCAD.closeDocument(doc.Name) + + doc = self.utility_create_scad("resize([2,2,2]) cube([2,2,2]);", "resize_no_change") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 8.000000, 6) + FreeCAD.closeDocument(doc.Name) + + doc = self.utility_create_scad("resize([2,2,2]) cube([4,8,12]);", "resize_non_uniform") + object = doc.ActiveObject + self.assertTrue (object is not None) + self.assertAlmostEqual (object.Shape.Volume, 8.000000, 6) + FreeCAD.closeDocument(doc.Name) + + def test_import_surface(self): + pass + + def test_import_projection(self): + pass + + def test_import_hull(self): + pass + + def test_import_minkowski(self): + pass + + def test_import_offset(self): + pass diff --git a/src/Mod/OpenSCAD/OpenSCADTest/data/Cube.stl b/src/Mod/OpenSCAD/OpenSCADTest/data/Cube.stl new file mode 100644 index 0000000000..b0986e354f Binary files /dev/null and b/src/Mod/OpenSCAD/OpenSCADTest/data/Cube.stl differ diff --git a/src/Mod/OpenSCAD/OpenSCADTest/data/Square.dxf b/src/Mod/OpenSCAD/OpenSCADTest/data/Square.dxf new file mode 100644 index 0000000000..fe38010419 --- /dev/null +++ b/src/Mod/OpenSCAD/OpenSCADTest/data/Square.dxf @@ -0,0 +1,818 @@ +999 +FreeCAD v0.20 24388 (Git) + 0 +SECTION + 2 +HEADER + 9 +$ACADVER + 1 +AC1014 + 9 +$ACADMAINTVER + 70 + 9 + 9 +$DWGCODEPAGE + 3 +ANSI_1252 + 9 +$TEXTSTYLE + 7 +STANDARD + 9 +$DIMSTYLE + 2 +STANDARD + 9 +$DIMTXSTY + 7 +STANDARD + 9 +$CMLSTYLE + 2 +STANDARD + 9 +$PEXTMAX + 10 +50 + 20 +50 + 30 +50 + 9 +$PEXTMIN + 10 +0 + 20 +0 + 30 +0 + 9 +$HANDSEED + 5 +FFFF + 0 +ENDSEC + 0 +SECTION + 2 +CLASSES + 0 +CLASS + 1 +ACDBDICTIONARYWDFLT + 2 +AcDbDictionaryWithDefault + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +XRECORD + 2 +AcDbXrecord + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 0 + 0 +CLASS + 1 +LWPOLYLINE + 2 +AcDbPolyline + 3 +ObjectDBX Classes + 90 + 0 +280 + 0 +281 + 1 + 0 +ENDSEC + 0 +SECTION + 2 +TABLES + 0 +TABLE + 2 +VPORT + 5 +20 +330 +0 +100 +AcDbSymbolTable + 70 + 1 + 0 +VPORT + 5 +21 +330 +20 +100 +AcDbSymbolTableRecord +100 +AcDbViewportTableRecord + 2 +*ACTIVE + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +LTYPE + 5 +22 +330 +0 +100 +AcDbSymbolTable + 70 + 1 + 0 +LTYPE + 5 +23 +330 +21 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +BYBLOCK + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +LTYPE + 5 +24 +330 +21 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +BYLAYER + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +LTYPE + 5 +25 +330 +21 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord + 2 +CONTINUOUS + 70 + 0 + 3 +Solid line + 72 + 65 + 73 + 0 + 40 +0.0 + 0 +ENDTAB + 0 +TABLE + 2 +LAYER + 5 +A0C +330 +0 +100 +AcDbSymbolTable + 70 +3 + 0 +LAYER + 5 +A0D +330 +A0C +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +0 + 70 + 0 + 62 + 7 + 6 +CONTINUOUS + 0 +LAYER + 5 +A0E +330 +A0C +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +none + 70 + 0 + 62 + 7 + 6 +CONTINUOUS + 0 +LAYER + 5 +A0F +330 +A0C +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord + 2 +Sketch + 70 + 0 + 62 + 7 + 6 +CONTINUOUS + 0 +ENDTAB + 0 +TABLE + 2 +STYLE + 5 +70 +330 +0 +100 +AcDbSymbolTable + 70 + 2 + 0 +STYLE + 5 +71 +330 +70 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord + 2 +STANDARD + 70 + 0 + 40 +0.0 + 41 +1.0 + 50 +0.0 + 71 + 0 + 42 +2.5 + 3 +arial.ttf + 4 + + 0 +STYLE + 5 +72 +330 +70 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord + 2 +ANNOTATIVE + 70 + 0 + 40 +0.0 + 41 +1.0 + 50 +0.0 + 71 + 0 + 42 +2.5 + 3 +arial.ttf + 4 + + 0 +ENDTAB + 0 +TABLE + 2 +VIEW + 5 +73 +330 +0 +100 +AcDbSymbolTable + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +UCS + 5 +74 +330 +0 +100 +AcDbSymbolTable + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +APPID + 5 +75 +330 +0 +100 +AcDbSymbolTable + 70 + 2 + 0 +APPID + 5 +76 +330 +75 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord + 2 +ACAD + 70 + 0 + 0 +APPID + 5 +77 +330 +75 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord + 2 +ACADANNOTATIVE + 70 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +DIMSTYLE + 5 +78 +330 +0 +100 +AcDbSymbolTable + 70 + 2 + 0 +DIMSTYLE +105 +79 +330 +78 +100 +AcDbSymbolTableRecord +100 +AcDbDimStyleTableRecord + 2 +STANDARD + 70 + 0 + 3 + + 4 + + 5 + + 6 + + 7 + + 40 +0.0 + 41 +2.5 + 42 +0.625 + 43 +3.75 + 44 +1.25 + 45 +0.0 + 46 +0.0 + 47 +0.0 + 48 +0.0 +140 +2.5 +141 +2.5 +142 +0.0 +143 +0.03937007874016 +144 +1.0 +145 +0.0 +146 +1.0 +147 +0.625 + 71 + 0 + 72 + 0 + 73 + 0 + 74 + 0 + 75 + 0 + 76 + 0 + 77 + 1 + 78 + 8 +170 + 0 +171 + 3 +172 + 1 +173 + 0 +174 + 0 +175 + 0 +176 + 0 +177 + 0 +178 + 0 +270 + 2 +271 + 2 +272 + 2 +273 + 2 +274 + 3 +340 +71 +275 + 0 +280 + 0 +281 + 0 +282 + 0 +283 + 0 +284 + 8 +285 + 0 +286 + 0 +287 + 3 +288 + 0 + 0 +ENDTAB + 0 +TABLE + 2 +BLOCK_RECORD + 5 +A01 +330 +0 +100 +AcDbSymbolTable + 70 +5 + 0 +BLOCK_RECORD + 5 +A02 +330 +A01 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*MODEL_SPACE + 0 +BLOCK_RECORD + 5 +A03 +330 +A01 +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord + 2 +*PAPER_SPACE + 0 +ENDTAB + 0 +ENDSEC + 0 +SECTION + 2 +BLOCKS + 0 +BLOCK + 5 +A04 +330 +A02 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockBegin + 2 +*MODEL_SPACE + 70 + 0 + 10 +0 + 20 +0 + 30 +0 + 3 +*MODEL_SPACE + 1 + + 0 +ENDBLK + 5 +A05 +330 +A02 +100 +AcDbEntity + 8 +0 +100 +AcDbBlockEnd + 0 +BLOCK + 5 +A06 +330 +A03 +100 +AcDbEntity + 67 +1 + 8 +0 +100 +AcDbBlockBegin + 2 +*PAPER_SPACE + 70 + 0 + 10 +0 + 20 +0 + 30 +0 + 3 +*PAPER_SPACE + 1 + + 0 +ENDBLK + 5 +A07 +330 +A03 +100 +AcDbEntity + 67 + 1 + 8 +0 +100 +AcDbBlockEnd + 0 +ENDSEC + 0 +SECTION + 2 +ENTITIES + 0 +LINE + 5 +A08 +330 +A02 +100 +AcDbEntity + 8 +Sketch +100 +AcDbLine + 10 +0 + 20 +10 + 30 +0 + 11 +10 + 21 +10 + 31 +0 + 0 +LINE + 5 +A09 +330 +A02 +100 +AcDbEntity + 8 +Sketch +100 +AcDbLine + 10 +10 + 20 +10 + 30 +0 + 11 +10 + 21 +0 + 31 +0 + 0 +LINE + 5 +A0A +330 +A02 +100 +AcDbEntity + 8 +Sketch +100 +AcDbLine + 10 +10 + 20 +0 + 30 +0 + 11 +0 + 21 +0 + 31 +0 + 0 +LINE + 5 +A0B +330 +A02 +100 +AcDbEntity + 8 +Sketch +100 +AcDbLine + 10 +0 + 20 +0 + 30 +0 + 11 +0 + 21 +10 + 31 +0 + 0 +ENDSEC + 0 +SECTION + 2 +OBJECTS + 0 +DICTIONARY + 5 +F000 +330 +0 +100 +AcDbDictionary + 3 +ACAD_GROUP +350 +F001 + 0 +DICTIONARY + 5 +F001 +330 +F000 +100 +AcDbDictionary + 0 +ENDSEC + 0 +EOF \ No newline at end of file