Merge branch 'master' into RRF-PP-for-Path

This commit is contained in:
P-C-R
2021-11-08 05:57:12 +01:00
committed by GitHub
75 changed files with 1028 additions and 827 deletions

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) Juergen Riegel <juergen.riegel@web.de> *
* Copyright (c) 2008 Juergen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) Juergen Riegel <juergen.riegel@web.de> *
* Copyright (c) 2008 Juergen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) Juergen Riegel <juergen.riegel@web.de> *
* Copyright (c) 2008 Juergen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) Juergen Riegel <juergen.riegel@web.de> *
* Copyright (c) 2008 Juergen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,3 +1,25 @@
#***************************************************************************
#* Copyright (c) 2017 Lorenz Lechner *
#* *
#* This file is part of the FreeCAD CAx development system. *
#* *
#* This library is free software; you can redistribute it and/or *
#* modify it under the terms of the GNU Library General Public *
#* License as published by the Free Software Foundation; either *
#* version 2 of the License, or (at your option) any later version. *
#* *
#* This library is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this library; see the file COPYING.LIB. If not, *
#* write to the Free Software Foundation, Inc., 59 Temple Place, *
#* Suite 330, Boston, MA 02111-1307, USA *
#* *
#***************************************************************************/
import Mesh
import FreeCAD as App
import FreeCADGui as Gui

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *

View File

@@ -1,8 +1,8 @@
# FreeCAD init script of the MeshPart module
# FreeCAD init script of the MeshPart module
# (c) 2001 Juergen Riegel
#***************************************************************************
#* (c) Juergen Riegel (juergen.riegel@web.de) 2002 *
#* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
#* *
#* This file is part of the FreeCAD CAx development system. *
#* *
@@ -13,14 +13,13 @@
#* for detail see the LICENCE text file. *
#* *
#* FreeCAD is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Lesser General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with FreeCAD; if not, write to the Free Software *
#* License along with FreeCAD; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#* Juergen Riegel 2002 *
#***************************************************************************/

View File

@@ -1,4 +1,4 @@
# MeshPart gui init module
# MeshPart gui init module
# (c) 2003 Juergen Riegel
#
# Gathering all the information to start FreeCAD
@@ -6,7 +6,7 @@
# runs when the gui is up
#***************************************************************************
#* (c) Juergen Riegel (juergen.riegel@web.de) 2002 *
#* Copyright (c) 2002 Juergen Riegel <juergen.riegel@web.de> *
#* *
#* This file is part of the FreeCAD CAx development system. *
#* *
@@ -26,44 +26,46 @@
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#* Juergen Riegel 2002 *
#***************************************************************************/
class MeshPartWorkbench ( Workbench ):
"MeshPart workbench object"
Icon = """
/* XPM */
static const char *MeshPart_Box[]={
"16 16 3 1",
". c None",
"# c #000000",
"a c #c6c642",
"................",
".......#######..",
"......#aaaaa##..",
".....#aaaaa###..",
"....#aaaaa##a#..",
"...#aaaaa##aa#..",
"..#aaaaa##aaa#..",
".########aaaa#..",
".#aaaaa#aaaaa#..",
".#aaaaa#aaaa##..",
".#aaaaa#aaa##...",
".#aaaaa#aa##....",
".#aaaaa#a##... .",
".#aaaaa###......",
".########.......",
"................"};
"""
MenuText = "MeshPart"
ToolTip = "MeshPart workbench"
"MeshPart workbench object"
Icon = """
/* XPM */
static const char *MeshPart_Box[]={
"16 16 3 1",
". c None",
"# c #000000",
"a c #c6c642",
"................",
".......#######..",
"......#aaaaa##..",
".....#aaaaa###..",
"....#aaaaa##a#..",
"...#aaaaa##aa#..",
"..#aaaaa##aaa#..",
".########aaaa#..",
".#aaaaa#aaaaa#..",
".#aaaaa#aaaa##..",
".#aaaaa#aaa##...",
".#aaaaa#aa##....",
".#aaaaa#a##... .",
".#aaaaa###......",
".########.......",
"................"};
"""
MenuText = "MeshPart"
ToolTip = "MeshPart workbench"
def Initialize(self):
# load the module
import MeshPartGui
import MeshPart
def GetClassName(self):
return "MeshPartGui::Workbench"
#Gui.addWorkbench(MeshPartWorkbench())
def Initialize(self):
# load the module
import MeshPartGui
import MeshPart
def GetClassName(self):
return "MeshPartGui::Workbench"
# Gui.addWorkbench(MeshPartWorkbench())

View File

@@ -200,13 +200,11 @@ class Resize :
self.createGeometry(fp)
def createGeometry(self, fp) :
print("Resize create Geometry")
import FreeCAD
mat = FreeCAD.Matrix()
mat.A11 = self.Vector[0]
mat.A22 = self.Vector[1]
mat.A33 = self.Vector[2]
print(mat)
fp.Shape = self.Target.Shape.transformGeometry(mat)
def __getstate__(self):
@@ -387,7 +385,7 @@ class Frustum:
fp.Placement = plm
class Twist:
def __init__(self, obj,child=None,h=1.0,angle=0.0,scale=[1.0,1.0]):
def __init__(self, obj, child=None, h=1.0, angle=0.0, scale=[1.0,1.0]):
import FreeCAD
obj.addProperty("App::PropertyLink","Base","Base",
"The base object that must be transformed")
@@ -406,10 +404,10 @@ class Twist:
self.createGeometry(fp)
def onChanged(self, fp, prop):
if prop in ["Angle","Height"]:
if prop in ["Angle","Height","Scale"]:
self.createGeometry(fp)
def createGeometry(self,fp):
def createGeometry(self, fp):
import FreeCAD,Part,math,sys
if fp.Base and fp.Height and fp.Base.Shape.isValid():
solids = []
@@ -443,7 +441,6 @@ class Twist:
pipe_shell.add(wire1)
pipe_shell.add(wire2)
pipe_shell.setAuxiliarySpine(auxiliary_spine,True,0)
print(pipe_shell.getStatus())
assert(pipe_shell.isReady())
pipe_shell.build()
faces.extend(pipe_shell.shape().Faces)
@@ -534,10 +531,9 @@ class PrismaticToroid:
solid = Part.makeSolid (clean_shell)
if solid.Volume < 0:
solid.reverse()
print (f"Solid volume is {solid.Volume}")
solids.append(solid)
except Part.OCCError:
print ("Could not create solid: creating compound instead")
FreeCAD.Console.PrintWarning("Could not create solid: creating compound instead")
solids.append(Part.Compound(faces))
fp.Shape = Part.Compound(solids)
@@ -587,139 +583,146 @@ class CGALFeature:
raise ValueError
def makeSurfaceVolume(filename):
import FreeCAD,Part,sys
import FreeCAD
import Part
import sys
coords = []
with open(filename) as f1:
coords = []
min_z = sys.float_info.max
for line in f1.readlines():
sline=line.strip()
sline = line.strip()
if sline and not sline.startswith('#'):
ycoord=len(coords)
lcoords=[]
ycoord = len(coords)
lcoords = []
for xcoord, num in enumerate(sline.split()):
fnum=float(num)
fnum = float(num)
lcoords.append(FreeCAD.Vector(float(xcoord),float(ycoord),fnum))
min_z = min(fnum,min_z)
coords.append(lcoords)
num_rows = len(coords)
num_cols = len(coords[0])
# OpenSCAD does not spline this surface, so neither do we: just create a bunch of faces,
# using four triangles per quadrilateral
faces = []
for row in range(num_rows-1):
for col in range(num_cols-1):
a = coords[row+0][col+0]
b = coords[row+0][col+1]
c = coords[row+1][col+1]
d = coords[row+1][col+0]
centroid = 0.25 * (a + b + c + d)
ab = Part.makeLine(a,b)
bc = Part.makeLine(b,c)
cd = Part.makeLine(c,d)
da = Part.makeLine(d,a)
num_rows = len(coords)
if num_rows == 0:
FreeCAD.Console.PrintWarning(f"No data found in surface file {filename}")
return None,0,0
num_cols = len(coords[0])
diag_a = Part.makeLine(a, centroid)
diag_b = Part.makeLine(b, centroid)
diag_c = Part.makeLine(c, centroid)
diag_d = Part.makeLine(d, centroid)
# OpenSCAD does not spline this surface, so neither do we: just create a
# bunch of faces,
# using four triangles per quadrilateral
faces = []
for row in range(num_rows - 1):
for col in range(num_cols - 1):
a = coords[row + 0][col + 0]
b = coords[row + 0][col + 1]
c = coords[row + 1][col + 1]
d = coords[row + 1][col + 0]
centroid = 0.25 * (a + b + c + d)
ab = Part.makeLine(a,b)
bc = Part.makeLine(b,c)
cd = Part.makeLine(c,d)
da = Part.makeLine(d,a)
wire1 = Part.Wire([ab,diag_a,diag_b])
wire2 = Part.Wire([bc,diag_b,diag_c])
wire3 = Part.Wire([cd,diag_c,diag_d])
wire4 = Part.Wire([da,diag_d,diag_a])
diag_a = Part.makeLine(a, centroid)
diag_b = Part.makeLine(b, centroid)
diag_c = Part.makeLine(c, centroid)
diag_d = Part.makeLine(d, centroid)
try:
face = Part.Face(wire1)
faces.append(face)
face = Part.Face(wire2)
faces.append(face)
face = Part.Face(wire3)
faces.append(face)
face = Part.Face(wire4)
faces.append(face)
except Exception:
print ("Failed to create the face from {},{},{},{}".format(coords[row+0][col+0],\
coords[row+0][col+1],coords[row+1][col+1],coords[row+1][col+0]))
last_row = num_rows-1
last_col = num_cols-1
wire1 = Part.Wire([ab,diag_a,diag_b])
wire2 = Part.Wire([bc,diag_b,diag_c])
wire3 = Part.Wire([cd,diag_c,diag_d])
wire4 = Part.Wire([da,diag_d,diag_a])
# Create the face to close off the y-min border: OpenSCAD places the lower surface of the shell
# at 1 unit below the lowest coordinate in the surface
lines = []
corner1 = FreeCAD.Vector(coords[0][0].x, coords[0][0].y, min_z-1)
lines.append (Part.makeLine(corner1,coords[0][0]))
for col in range(num_cols-1):
a = coords[0][col]
b = coords[0][col+1]
lines.append (Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[0][last_col].x, coords[0][last_col].y, min_z-1)
lines.append (Part.makeLine(corner2,coords[0][last_col]))
lines.append (Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
# Create the face to close off the y-max border
lines = []
corner1 = FreeCAD.Vector(coords[last_row][0].x, coords[last_row][0].y, min_z-1)
lines.append (Part.makeLine(corner1,coords[last_row][0]))
for col in range(num_cols-1):
a = coords[last_row][col]
b = coords[last_row][col+1]
lines.append (Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[last_row][last_col].x, coords[last_row][last_col].y, min_z-1)
lines.append (Part.makeLine(corner2,coords[last_row][last_col]))
lines.append (Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
try:
face = Part.Face(wire1)
faces.append(face)
face = Part.Face(wire2)
faces.append(face)
face = Part.Face(wire3)
faces.append(face)
face = Part.Face(wire4)
faces.append(face)
except Exception:
FreeCAD.Console.PrintWarning("Failed to create the face from {},{},{},{}".format(coords[row + 0][col + 0],\
coords[row + 0][col + 1],coords[row + 1][col + 1],coords[row + 1][col + 0]))
# Create the face to close off the x-min border
lines = []
corner1 = FreeCAD.Vector(coords[0][0].x, coords[0][0].y, min_z-1)
lines.append (Part.makeLine(corner1,coords[0][0]))
for row in range(num_rows-1):
a = coords[row][0]
b = coords[row+1][0]
lines.append (Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[last_row][0].x, coords[last_row][0].y, min_z-1)
lines.append (Part.makeLine(corner2,coords[last_row][0]))
lines.append (Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
last_row = num_rows - 1
last_col = num_cols - 1
# Create the face to close off the x-max border
lines = []
corner1 = FreeCAD.Vector(coords[0][last_col].x, coords[0][last_col].y, min_z-1)
lines.append (Part.makeLine(corner1,coords[0][last_col]))
for row in range(num_rows-1):
a = coords[row][last_col]
b = coords[row+1][last_col]
lines.append (Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[last_row][last_col].x, coords[last_row][last_col].y, min_z-1)
lines.append (Part.makeLine(corner2,coords[last_row][last_col]))
lines.append (Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
# Create the face to close off the y-min border: OpenSCAD places the lower
# surface of the shell
# at 1 unit below the lowest coordinate in the surface
lines = []
corner1 = FreeCAD.Vector(coords[0][0].x, coords[0][0].y, min_z - 1)
lines.append(Part.makeLine(corner1,coords[0][0]))
for col in range(num_cols - 1):
a = coords[0][col]
b = coords[0][col + 1]
lines.append(Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[0][last_col].x, coords[0][last_col].y, min_z - 1)
lines.append(Part.makeLine(corner2,coords[0][last_col]))
lines.append(Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
# Create a bottom surface to close off the shell
a = FreeCAD.Vector(coords[0][0].x, coords[0][0].y, min_z-1)
b = FreeCAD.Vector(coords[0][last_col].x, coords[0][last_col].y, min_z-1)
c = FreeCAD.Vector(coords[last_row][last_col].x, coords[last_row][last_col].y, min_z-1)
d = FreeCAD.Vector(coords[last_row][0].x, coords[last_row][0].y, min_z-1)
ab = Part.makeLine(a,b)
bc = Part.makeLine(b,c)
cd = Part.makeLine(c,d)
da = Part.makeLine(d,a)
wire = Part.Wire([ab,bc,cd,da])
face = Part.Face(wire)
faces.append(face)
# Create the face to close off the y-max border
lines = []
corner1 = FreeCAD.Vector(coords[last_row][0].x, coords[last_row][0].y, min_z - 1)
lines.append(Part.makeLine(corner1,coords[last_row][0]))
for col in range(num_cols - 1):
a = coords[last_row][col]
b = coords[last_row][col + 1]
lines.append(Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[last_row][last_col].x, coords[last_row][last_col].y, min_z - 1)
lines.append(Part.makeLine(corner2,coords[last_row][last_col]))
lines.append(Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
s = Part.Shell(faces)
solid = Part.Solid(s)
return solid,last_col,last_row
# Create the face to close off the x-min border
lines = []
corner1 = FreeCAD.Vector(coords[0][0].x, coords[0][0].y, min_z - 1)
lines.append(Part.makeLine(corner1,coords[0][0]))
for row in range(num_rows - 1):
a = coords[row][0]
b = coords[row + 1][0]
lines.append(Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[last_row][0].x, coords[last_row][0].y, min_z - 1)
lines.append(Part.makeLine(corner2,coords[last_row][0]))
lines.append(Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
# Create the face to close off the x-max border
lines = []
corner1 = FreeCAD.Vector(coords[0][last_col].x, coords[0][last_col].y, min_z - 1)
lines.append(Part.makeLine(corner1,coords[0][last_col]))
for row in range(num_rows - 1):
a = coords[row][last_col]
b = coords[row + 1][last_col]
lines.append(Part.makeLine(a, b))
corner2 = FreeCAD.Vector(coords[last_row][last_col].x, coords[last_row][last_col].y, min_z - 1)
lines.append(Part.makeLine(corner2,coords[last_row][last_col]))
lines.append(Part.makeLine(corner1,corner2))
wire = Part.Wire(lines)
face = Part.Face(wire)
faces.append(face)
# Create a bottom surface to close off the shell
a = FreeCAD.Vector(coords[0][0].x, coords[0][0].y, min_z - 1)
b = FreeCAD.Vector(coords[0][last_col].x, coords[0][last_col].y, min_z - 1)
c = FreeCAD.Vector(coords[last_row][last_col].x, coords[last_row][last_col].y, min_z - 1)
d = FreeCAD.Vector(coords[last_row][0].x, coords[last_row][0].y, min_z - 1)
ab = Part.makeLine(a,b)
bc = Part.makeLine(b,c)
cd = Part.makeLine(c,d)
da = Part.makeLine(d,a)
wire = Part.Wire([ab,bc,cd,da])
face = Part.Face(wire)
faces.append(face)
s = Part.Shell(faces)
solid = Part.Solid(s)
return solid,last_col,last_row

View File

@@ -38,6 +38,7 @@ __url__ = "https://www.freecadweb.org"
class TestImportCSG(unittest.TestCase):
MODULE = 'test_importCSG' # file name without extension
temp_dir = tempfile.TemporaryDirectory()
def setUp(self):
@@ -73,113 +74,78 @@ class TestImportCSG(unittest.TestCase):
FreeCAD.closeDocument("CSG")
def utility_create_scad(self, scadCode, name):
filename = self.temp_dir.name + os.path.sep + name + ".scad"
print (f"Creating {filename}")
f = open(filename,"w+")
f.write(scadCode)
f.close()
return importCSG.open(filename)
def test_import_sphere(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "sphere.scad"
f = open(filename,"w+")
f.write("sphere(10.0);")
f.close()
doc = importCSG.open(filename)
sphere = doc.getObject("sphere")
self.assertTrue (sphere is not None)
self.assertTrue (sphere.Radius == 10.0)
FreeCAD.closeDocument(doc.Name)
doc = self.utility_create_scad("sphere(10.0);","sphere")
sphere = doc.getObject("sphere")
self.assertTrue (sphere is not None)
self.assertTrue (sphere.Radius == 10.0)
FreeCAD.closeDocument(doc.Name)
def test_import_cylinder(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "cylinder.scad"
f = open(filename,"w+")
f.write("cylinder(50.0,d=10.0);")
f.close()
doc = importCSG.open(filename)
cylinder = doc.getObject("cylinder")
self.assertTrue (cylinder is not None)
self.assertTrue (cylinder.Radius == 5.0)
self.assertTrue (cylinder.Height == 50.0)
FreeCAD.closeDocument(doc.Name)
doc = self.utility_create_scad("cylinder(50.0,d=10.0);","cylinder")
cylinder = doc.getObject("cylinder")
self.assertTrue (cylinder is not None)
self.assertTrue (cylinder.Radius == 5.0)
self.assertTrue (cylinder.Height == 50.0)
FreeCAD.closeDocument(doc.Name)
def test_import_cube(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "cube.scad"
f = open(filename,"w+")
f.write("cube([1.0,2.0,3.0]);")
f.close()
doc = importCSG.open(filename)
cube = doc.getObject("cube")
self.assertTrue (cube is not None)
self.assertTrue (cube.Length == 1.0)
self.assertTrue (cube.Width == 2.0)
self.assertTrue (cube.Height == 3.0)
FreeCAD.closeDocument(doc.Name)
doc = self.utility_create_scad("cube([1.0,2.0,3.0]);","cube")
cube = doc.getObject("cube")
self.assertTrue (cube is not None)
self.assertTrue (cube.Length == 1.0)
self.assertTrue (cube.Width == 2.0)
self.assertTrue (cube.Height == 3.0)
FreeCAD.closeDocument(doc.Name)
def test_import_circle(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "circle.scad"
f = open(filename,"w+")
f.write("circle(10.0);")
f.close()
doc = importCSG.open(filename)
circle = doc.getObject("circle")
self.assertTrue (circle is not None)
self.assertTrue (circle.Radius == 10.0)
FreeCAD.closeDocument(doc.Name)
doc = self.utility_create_scad("circle(10.0);","circle")
circle = doc.getObject("circle")
self.assertTrue (circle is not None)
self.assertTrue (circle.Radius == 10.0)
FreeCAD.closeDocument(doc.Name)
def test_import_square(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "square.scad"
f = open(filename,"w+")
f.write("square([1.0,2.0]);")
f.close()
doc = importCSG.open(filename)
square = doc.getObject("square")
self.assertTrue (square is not None)
self.assertTrue (square.Length == 1.0)
self.assertTrue (square.Width == 2.0)
FreeCAD.closeDocument(doc.Name)
doc = self.utility_create_scad("square([1.0,2.0]);","square")
square = doc.getObject("square")
self.assertTrue (square is not None)
self.assertTrue (square.Length == 1.0)
self.assertTrue (square.Width == 2.0)
FreeCAD.closeDocument(doc.Name)
def test_import_text(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "text.scad"
f = open(filename,"w+")
f.write("text(\"X\");") # Keep it short to keep the test fast-ish
f.close()
try:
doc = importCSG.open(filename)
text = doc.getObject("text")
self.assertTrue (text is not None)
FreeCAD.closeDocument(doc.Name)
except Exception:
pass # We may not have the DXF importer available
try:
doc = self.utility_create_scad("text(\"X\");","text") # Keep it short to keep the test fast-ish
text = doc.getObject("text")
self.assertTrue (text is not None)
FreeCAD.closeDocument(doc.Name)
except Exception:
pass # We may not have the DXF importer available
def test_import_polygon_nopath(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "polygon_nopath.scad"
f = open(filename,"w+")
f.write("polygon(points=[[0,0],[100,0],[130,50],[30,50]]);")
f.close()
doc = importCSG.open(filename)
polygon = doc.getObject("polygon")
self.assertTrue (polygon is not None)
self.assertAlmostEqual (polygon.Shape.Area, 5000.0)
FreeCAD.closeDocument(doc.Name)
doc = self.utility_create_scad("polygon(points=[[0,0],[100,0],[130,50],[30,50]]);","polygon_nopath")
polygon = doc.getObject("polygon")
self.assertTrue (polygon is not None)
self.assertAlmostEqual (polygon.Shape.Area, 5000.0)
FreeCAD.closeDocument(doc.Name)
def test_import_polygon_path(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "polygon_path.scad"
f = open(filename,"w+")
f.write("polygon([[0,0],[100,0],[130,50],[30,50]], paths=[[0,1,2,3]]);")
f.close()
doc = importCSG.open(filename)
wire = doc.ActiveObject # With paths, the polygon gets created as a wire...
self.assertTrue (wire is not None)
self.assertAlmostEqual (wire.Shape.Area, 5000.0)
FreeCAD.closeDocument(doc.Name)
doc = self.utility_create_scad("polygon([[0,0],[100,0],[130,50],[30,50]], paths=[[0,1,2,3]]);","polygon_path")
wire = doc.ActiveObject # With paths, the polygon gets created as a wire...
self.assertTrue (wire is not None)
self.assertAlmostEqual (wire.Shape.Area, 5000.0)
FreeCAD.closeDocument(doc.Name)
def test_import_polyhedron(self):
with tempfile.TemporaryDirectory() as temp_dir:
filename = temp_dir + os.path.sep + "polyhedron.scad"
f = open(filename,"w+")
f.write(
doc = self.utility_create_scad(
"""
polyhedron(
points=[ [10,10,0],[10,-10,0],[-10,-10,0],[-10,10,0], // the four points at base
@@ -187,22 +153,12 @@ polyhedron(
faces=[ [0,1,4],[1,2,4],[2,3,4],[3,0,4], // each triangle side
[1,0,3],[2,1,3] ] // two triangles for square base
);
"""
""","polyhedron"
)
f.close()
doc = importCSG.open(filename)
polyhedron = doc.ActiveObject # With paths, the polygon gets created as a wire...
self.assertTrue (polyhedron is not None)
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.path.sep + name + ".scad"
f = open(filename,"w+")
f.write(scadCode)
f.close()
return importCSG.open(filename)
polyhedron = doc.ActiveObject # With paths, the polygon gets created as a wire...
self.assertTrue (polyhedron is not None)
self.assertAlmostEqual (polyhedron.Shape.Volume, 1333.3333, 4)
FreeCAD.closeDocument(doc.Name)
def test_import_difference(self):
doc = self.utility_create_scad("difference() { cube(15, center=true); sphere(10); }", "difference")

View File

@@ -79,7 +79,7 @@ def setColorRecursively(obj, color, transp):
"Part::Common", "Part::MultiCommon"]
if obj.TypeId in boolean_features:
for currentObject in obj.OutList:
print(f"Fixing up colors for: {currentObject.FullName}")
if printverbose: print(f"Fixing up colors for: {currentObject.FullName}")
if currentObject not in hassetcolor:
setColorRecursively(currentObject, color, transp)
@@ -767,14 +767,15 @@ def p_linear_extrude_with_transform(p):
'linear_extrude_with_transform : linear_extrude LPAREN keywordargument_list RPAREN OBRACE block_list EBRACE'
if printverbose: print("Linear Extrude With Transform")
h = float(p[3]['height'])
s = 1.0
if printverbose: print("Height : ",h)
s = [1.0,1.0]
t = 0.0
if printverbose: print("Twist : ",p[3])
if 'scale' in p[3]:
s = [float(p[3]['scale'][0]), float(p[3]['scale'][1])]
print ("Scale: " + str(s))
if printverbose: print ("Scale: " + str(s))
if 'twist' in p[3]:
t = float(p[3]['twist'])
if printverbose: print("Twist : ",t)
# Test if null object like from null text
if (len(p[6]) == 0) :
p[0] = []
@@ -783,7 +784,7 @@ def p_linear_extrude_with_transform(p):
obj = fuse(p[6],"Linear Extrude Union")
else :
obj = p[6][0]
if t != 0.0 or s != 1.0:
if t != 0.0 or s[0] != 1.0 or s[1] != 1.0:
newobj = process_linear_extrude_with_transform(obj,h,t,s)
else:
newobj = process_linear_extrude(obj,h)
@@ -1286,11 +1287,7 @@ def p_polyhedron_action(p) :
pp =[v2(v[k]) for k in i]
# Add first point to end of list to close polygon
pp.append(pp[0])
print("pp")
print(pp)
w = Part.makePolygon(pp)
print("w")
print(w)
try:
f = Part.Face(w)
except Exception:
@@ -1315,7 +1312,6 @@ def p_projection_action(p) :
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")
plane.Length = bbox.XLength
plane.Width = bbox.YLength

View File

@@ -55,7 +55,7 @@ using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskLoftParameters */
TaskLoftParameters::TaskLoftParameters(ViewProviderLoft *LoftView,bool /*newObj*/, QWidget *parent)
TaskLoftParameters::TaskLoftParameters(ViewProviderLoft *LoftView, bool /*newObj*/, QWidget *parent)
: TaskSketchBasedParameters(LoftView, parent, "PartDesign_AdditiveLoft", tr("Loft parameters"))
, ui(new Ui_TaskLoftParameters)
{
@@ -69,7 +69,7 @@ TaskLoftParameters::TaskLoftParameters(ViewProviderLoft *LoftView,bool /*newObj*
connect(ui->buttonRefAdd, SIGNAL(toggled(bool)),
this, SLOT(onRefButtonAdd(bool)));
connect(ui->buttonRefRemove, SIGNAL(toggled(bool)),
this, SLOT(onRefButtonRemvove(bool)));
this, SLOT(onRefButtonRemove(bool)));
connect(ui->checkBoxRuled, SIGNAL(toggled(bool)),
this, SLOT(onRuled(bool)));
connect(ui->checkBoxClosed, SIGNAL(toggled(bool)),
@@ -129,16 +129,15 @@ TaskLoftParameters::TaskLoftParameters(ViewProviderLoft *LoftView,bool /*newObj*
for (QWidget* child : proxy->findChildren<QWidget*>())
child->blockSignals(false);
updateUI(0);
updateUI();
}
TaskLoftParameters::~TaskLoftParameters()
{
}
void TaskLoftParameters::updateUI(int index)
void TaskLoftParameters::updateUI()
{
Q_UNUSED(index);
}
void TaskLoftParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
@@ -324,7 +323,7 @@ void TaskLoftParameters::onRefButtonAdd(bool checked) {
}
}
void TaskLoftParameters::onRefButtonRemvove(bool checked) {
void TaskLoftParameters::onRefButtonRemove(bool checked) {
if (checked) {
Gui::Selection().clearSelection();
@@ -359,7 +358,7 @@ bool TaskDlgLoftParameters::accept()
// TODO Fill this with commands (2015-09-11, Fat-Zer)
PartDesign::Loft* pcLoft = static_cast<PartDesign::Loft*>(vp->getObject());
for(App::DocumentObject* obj : pcLoft->Sections.getValues()) {
for (App::DocumentObject* obj : pcLoft->Sections.getValues()) {
FCMD_OBJ_HIDE(obj);
}

View File

@@ -56,7 +56,7 @@ public:
private Q_SLOTS:
void onProfileButton(bool);
void onRefButtonAdd(bool);
void onRefButtonRemvove(bool);
void onRefButtonRemove(bool);
void onClosed(bool);
void onRuled(bool);
void onDeleteSection();
@@ -67,7 +67,7 @@ protected:
private:
void onSelectionChanged(const Gui::SelectionChanges& msg);
void updateUI(int index);
void updateUI();
bool referenceSelected(const Gui::SelectionChanges& msg) const;
void removeFromListWidget(QListWidget*w, QString name);
void clearButtons();

View File

@@ -94,6 +94,7 @@ TaskPipeParameters::TaskPipeParameters(ViewProviderPipe *PipeView, bool /*newObj
// Create context menu
QAction* remove = new QAction(tr("Remove"), this);
remove->setShortcut(QKeySequence::Delete);
remove->setShortcutContext(Qt::WidgetShortcut);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// display shortcut behind the context menu entry
remove->setShortcutVisibleInContextMenu(true);
@@ -587,6 +588,7 @@ TaskPipeOrientation::TaskPipeOrientation(ViewProviderPipe* PipeView, bool /*newO
// Create context menu
QAction* remove = new QAction(tr("Remove"), this);
remove->setShortcut(QKeySequence::Delete);
remove->setShortcutContext(Qt::WidgetShortcut);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// display shortcut behind the context menu entry
remove->setShortcutVisibleInContextMenu(true);
@@ -902,6 +904,7 @@ TaskPipeScaling::TaskPipeScaling(ViewProviderPipe* PipeView, bool /*newObj*/, QW
// Create context menu
QAction* remove = new QAction(tr("Remove"), this);
remove->setShortcut(QKeySequence::Delete);
remove->setShortcutContext(Qt::WidgetShortcut);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// display shortcut behind the context menu entry
remove->setShortcutVisibleInContextMenu(true);

View File

@@ -555,7 +555,8 @@ public:
"conList.append(Sketcher.Constraint('Horizontal',%i))\n"
"conList.append(Sketcher.Constraint('Vertical',%i))\n"
"conList.append(Sketcher.Constraint('Vertical',%i))\n"
"%s.addConstraint(conList)\n",
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y, // line 1
EditCurve[1].x,EditCurve[1].y,EditCurve[2].x,EditCurve[2].y, // line 2
EditCurve[2].x,EditCurve[2].y,EditCurve[3].x,EditCurve[3].y, // line 3
@@ -594,7 +595,8 @@ public:
"conList.append(Sketcher.Constraint('Vertical',%i))\n"
"conList.append(Sketcher.Constraint('Vertical',%i))\n"
"conList.append(Sketcher.Constraint('Symmetric',%i,2,%i,1,%i,1))\n"
"%s.addConstraint(conList)\n",
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y, // line 1
EditCurve[1].x,EditCurve[1].y,EditCurve[2].x,EditCurve[2].y, // line 2
EditCurve[2].x,EditCurve[2].y,EditCurve[3].x,EditCurve[3].y, // line 3
@@ -930,7 +932,8 @@ public:
"conList.append(Sketcher.Constraint('Equal', %i, %i))\n"
"conList.append(Sketcher.Constraint('Equal', %i, %i))\n"
"conList.append(Sketcher.Constraint('Equal', %i, %i))\n"
"%s.addConstraint(conList)\n",
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
StartPos.x + (signX * radius), StartPos.y + (signY * radius), // center of the arc 1
radius,
start, end, // start and end angle of arc1
@@ -984,7 +987,8 @@ public:
"conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n"
"conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n"
"conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n"
"%s.addConstraint(conList)\n",
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
StartPos.x, StartPos.y, // point at StartPos
EndPos.x, EndPos.y, // point at EndPos
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
@@ -4843,6 +4847,7 @@ public:
}
cstream << Gui::Command::getObjectCmd(sketchgui->getObject()) << ".addConstraint(conList)\n";
cstream << "del conList\n";
Gui::Command::doCommand(Gui::Command::Doc, cstream.str().c_str());
@@ -7129,7 +7134,8 @@ public:
"conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 1))\n"
"conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 1))\n"
"conList.append(Sketcher.Constraint('Equal', %i, %i))\n"
"%s.addConstraint(conList)\n",
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
StartPos.x, StartPos.y, // center of the arc1
r, // radius arc1
start, end, // start and end angle of arc1

View File

@@ -379,7 +379,7 @@ public:
class ExpressionDelegate : public QStyledItemDelegate
{
public:
ExpressionDelegate(QListWidget * _view) : view(_view) { }
ExpressionDelegate(QListWidget * _view) : QStyledItemDelegate(_view), view(_view) { }
protected:
QPixmap getIcon(const char* name, const QSize& size) const
{

View File

@@ -6376,6 +6376,7 @@ bool ViewProviderSketch::setEdit(int ModNum)
" tv.sketchClipPlane(ActiveSketch, ActiveSketch.ViewObject.SectionView)\n"
"tv.hide(ActiveSketch)\n"
"del(tv)\n"
"del(ActiveSketch)\n"
).arg(QString::fromLatin1(getDocument()->getDocument()->getName()),
QString::fromLatin1(getSketchObject()->getNameInDocument()),
QString::fromLatin1(Gui::Command::getObjectCmd(editObj).c_str()),
@@ -6907,6 +6908,7 @@ void ViewProviderSketch::unsetEdit(int ModNum)
" tv.restore()\n"
"ActiveSketch.ViewObject.TempoVis = None\n"
"del(tv)\n"
"del(ActiveSketch)\n"
).arg(QString::fromLatin1(getDocument()->getDocument()->getName())).arg(
QString::fromLatin1(getSketchObject()->getNameInDocument()));
QByteArray cmdstr_bytearray = cmdstr.toLatin1();

View File

@@ -288,6 +288,42 @@ def retranslateUi():
</tr>
</table>"""
global t9
t9 = "<p align='center'><b>OpenSCAD</b> " + text06 + """</p>
<table>
<tr>
<th><small>""" + text01 + """</small></th>
<th><small>""" + text02 + """</small></th>
<th><small>""" + text02 + """</small></th>
<th><small>""" + text03 + """</small></th>
<th><small>""" + text04 + """</small></th>
</tr>
<tr>
<td align='center'><img src=':/icons/NavigationOpenSCAD_Select.svg'></td>
<td align='center'><img src=':/icons/NavigationOpenSCAD_Zoom.svg'></td>
<td align='center'><img src=':/icons/NavigationOpenSCAD_ZoomAlt.svg'></td>
<td align='center'><img src=':/icons/NavigationOpenSCAD_Rotate.svg'></td>
<td align='center'><img src=':/icons/NavigationOpenSCAD_Pan.svg'></td>
</tr>
</table>"""
global t10
t10 = "<p align='center'><b>TinkerCAD</b> " + text06 + """</p>
<table>
<tr>
<th><small>""" + text01 + """</small></th>
<th><small>""" + text02 + """</small></th>
<th><small>""" + text03 + """</small></th>
<th><small>""" + text04 + """</small></th>
</tr>
<tr>
<td align='center'><img src=':/icons/NavigationTinkerCAD_Select.svg'></td>
<td align='center'><img src=':/icons/NavigationTinkerCAD_Zoom.svg'></td>
<td align='center'><img src=':/icons/NavigationTinkerCAD_Rotate.svg'></td>
<td align='center'><img src=':/icons/NavigationTinkerCAD_Pan.svg'></td>
</tr>
</table>"""
menuSettings.setTitle(translate("NavigationIndicator", "Settings"))
menuOrbit.setTitle(translate("NavigationIndicator", "Orbit style"))
aCompact.setText(translate("NavigationIndicator", "Compact"))
@@ -384,6 +420,18 @@ a8.setText("OpenCascade")
a8.setData("Gui::OpenCascadeNavigationStyle")
a8.setObjectName("Indicator_NavigationOpenCascade")
a9 = QtGui.QAction(gStyle)
a9.setIcon(QtGui.QIcon(":/icons/NavigationOpenSCAD_dark.svg"))
a9.setText("OpenSCAD")
a9.setData("Gui::OpenSCADNavigationStyle")
a9.setObjectName("Indicator_NavigationOpenSCAD")
a10 = QtGui.QAction(gStyle)
a10.setIcon(QtGui.QIcon(":/icons/NavigationTinkerCAD_dark.svg"))
a10.setText("TinkerCAD")
a10.setData("Gui::TinkerCADNavigationStyle")
a10.setObjectName("Indicator_NavigationTinkerCAD")
menu.addMenu(menuSettings)
menu.addSeparator()
menu.addAction(a0)
@@ -395,6 +443,8 @@ menu.addAction(a5)
menu.addAction(a6)
menu.addAction(a7)
menu.addAction(a8)
menu.addAction(a9)
menu.addAction(a10)
def onCompact():
@@ -430,6 +480,8 @@ def onTooltip():
a6.setToolTip(t6)
a7.setToolTip(t7)
a8.setToolTip(t8)
a9.setToolTip(t9)
a10.setToolTip(t10)
p.SetBool("Tooltip", 1)
else:
for i in gStyle.actions():

View File

@@ -58,6 +58,17 @@
<file>icons/NavigationOpenInventor_dark.svg</file>
<file>icons/NavigationOpenInventor_ZoomAlt.svg</file>
<file>icons/NavigationOpenInventor_Zoom.svg</file>
<file alias="icons/NavigationOpenSCAD_dark.svg">icons/NavigationCAD_dark.svg</file>
<file alias="icons/NavigationOpenSCAD_Select.svg">icons/NavigationOpenCascade_Select.svg</file>
<file alias="icons/NavigationOpenSCAD_Zoom.svg">icons/NavigationOpenCascade_PanAlt.svg</file>
<file alias="icons/NavigationOpenSCAD_ZoomAlt.svg">icons/NavigationOpenCascade_PanAlt.svg</file>
<file alias="icons/NavigationOpenSCAD_Rotate.svg">icons/NavigationOpenCascade_Select.svg</file>
<file alias="icons/NavigationOpenSCAD_Pan.svg">icons/NavigationGesture_Pan.svg</file>
<file alias="icons/NavigationTinkerCAD_dark.svg">icons/NavigationCAD_dark.svg</file>
<file alias="icons/NavigationTinkerCAD_Select.svg">icons/NavigationOpenCascade_Select.svg</file>
<file alias="icons/NavigationTinkerCAD_Zoom.svg">icons/NavigationOpenCascade_Zoom.svg</file>
<file alias="icons/NavigationTinkerCAD_Rotate.svg">icons/NavigationGesture_Pan.svg</file>
<file alias="icons/NavigationTinkerCAD_Pan.svg">icons/NavigationOpenCascade_PanAlt.svg</file>
<file>icons/NavigationRevit_Pan.svg</file>
<file>icons/NavigationRevit_Rotate.svg</file>
<file>icons/NavigationRevit_light.svg</file>