Merge branch 'master' into feature/holding-tags-copy

This commit is contained in:
mlampert
2019-10-17 19:17:54 -07:00
committed by GitHub
16 changed files with 444 additions and 174 deletions

View File

@@ -15,6 +15,7 @@
<file>icons/CurvedShapes_workbench_icon.svg</file>
<file>icons/Curves_workbench_icon.svg</file>
<file>icons/Defeaturing_workbench_icon.svg</file>
<file>icons/DesignSPHysics_workbench_icon.svg</file>
<file>icons/dodo_workbench_icon.svg</file>
<file>icons/DynamicData_workbench_icon.svg</file>
<file>icons/EM_workbench_icon.svg</file>

View File

@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
viewBox="0 0 16.933312 16.933312"
version="1.1"
id="svg50"
sodipodi:docname="DesignSPHysics_workbench_icon_new_64x64_2.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata54">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1853"
inkscape:window-height="1019"
id="namedview52"
showgrid="false"
inkscape:zoom="2.6074562"
inkscape:cx="-45.759252"
inkscape:cy="61.417337"
inkscape:window-x="1433"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg50" />
<defs
id="defs32">
<linearGradient
id="linearGradient1091"
inkscape:collect="always">
<stop
id="stop1087"
offset="0"
style="stop-color:#de2230;stop-opacity:1" />
<stop
id="stop1089"
offset="1"
style="stop-color:#2b6ab0;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient1075">
<stop
style="stop-color:#983176;stop-opacity:1"
offset="0"
id="stop1071" />
<stop
style="stop-color:#2b6ab0;stop-opacity:1"
offset="1"
id="stop1073" />
</linearGradient>
<radialGradient
id="A"
cx="282.64999"
cy="29.149"
r="19.570999"
gradientTransform="matrix(0.61866,0.96665,-1.0332,0.66128,-327.28,-255.84)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#71b2f8"
offset="0"
id="stop2" />
<stop
stop-color="#002795"
offset="1"
id="stop4" />
</radialGradient>
<radialGradient
id="B"
cx="270.57999"
cy="33.900002"
r="19.570999"
gradientTransform="matrix(1.1149,0.27223,-0.75072,3.0746,-471.09,-148.33)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#ff6d0f"
offset="0"
id="stop7" />
<stop
stop-color="#ff1000"
offset="1"
id="stop9" />
</radialGradient>
<linearGradient
id="C"
x1="142.42599"
x2="226.73"
y1="162.099"
y2="162.099"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.06151372,0,0,0.06151372,12.90318,-2.121192)">
<stop
stop-color="#666"
stop-opacity=".847"
offset="0"
id="stop12" />
<stop
stop-color="#666"
stop-opacity=".25"
offset=".518"
id="stop14" />
<stop
stop-color="#666"
stop-opacity=".025"
offset=".776"
id="stop16" />
<stop
stop-color="#666"
stop-opacity="0"
offset="1"
id="stop18" />
</linearGradient>
<filter
id="D"
style="color-interpolation-filters:sRGB">
<feFlood
flood-color="#000"
flood-opacity=".498"
id="feFlood21" />
<feComposite
in2="SourceGraphic"
operator="in"
id="feComposite23" />
<feGaussianBlur
stdDeviation="2.5"
id="feGaussianBlur25" />
<feOffset
dx="0.3"
dy="0.8"
id="feOffset27"
result="result1" />
<feComposite
in="SourceGraphic"
in2="result1"
id="feComposite29" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1075"
id="linearGradient1077"
x1="12.879064"
y1="190.00041"
x2="127.98798"
y2="78.355347"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1091"
id="linearGradient1085"
x1="-20.224503"
y1="109.90421"
x2="53.218998"
y2="155.82506"
gradientUnits="userSpaceOnUse" />
</defs>
<g
id="g1069"
transform="matrix(0.10285649,0,0,0.10267995,1.0534131,-5.6318672)"
style="stroke-width:0.59856778">
<path
sodipodi:nodetypes="csczcc"
inkscape:connector-curvature="0"
id="path1061"
d="m 19.243778,189.86421 c 0,0 15.84417,-22.71955 9.352293,-54.45045 -5.996226,-29.30827 -20.8817476,-29.27105 -20.8817476,-29.27105 0,0 6.3886856,-26.330422 22.6624956,-19.823753 16.273809,6.506669 40.275125,77.872223 49.12365,119.176843 z"
style="fill:url(#linearGradient1085);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5745616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccscsc"
inkscape:connector-curvature="0"
id="path871"
d="m 33.57962,193.44157 73.18635,19.80337 c 0,0 -28.276859,-25.17999 -14.063259,-84.66656 7.749139,-32.431605 47.355879,-46.20786 47.355879,-46.20786 0,0 -25.23199,-34.985128 -48.419841,-13.860317 C 49.862564,106.56952 33.57962,193.44157 33.57962,193.44157 Z"
style="fill:url(#linearGradient1077);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5745616;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -1133,6 +1133,19 @@ class _ViewProviderSectionPlane:
self.setEdit(vobj,None)
def setupContextMenu(self,vobj,menu):
"""CONTEXT MENU setup"""
from PySide import QtCore,QtGui
action1 = QtGui.QAction(QtGui.QIcon(":/icons/Draft_Edit.svg"),"Toggle Cutview",menu)
action1.triggered.connect(lambda f=self.contextCutview, arg=vobj:f(arg))
menu.addAction(action1)
def contextCutview(self,vobj):
"""CONTEXT MENU command to toggle CutView property on and off"""
if vobj.CutView:
vobj.CutView = False
else: vobj.CutView = True
class _ArchDrawingView:

View File

@@ -41,6 +41,20 @@ if FreeCAD.GuiUp:
from PySide import QtCore
from PySide.QtCore import QT_TRANSLATE_NOOP
from DraftTools import translate
COLORS = {
"default": FreeCADGui.draftToolBar.getDefaultColor("snap"),
"black": (0., 0., 0.),
"white": (1., 1., 1.),
"grey": (.5, .5, .5),
"red": (1., 0., 0.),
"green": (0., 1., 0.),
"blue": (0., 0., 1.),
"yellow": (1., 1., 0.),
"cyan": (0., 1., 1.),
"magenta":(1., 0., 1.)
}
class Edit():
@@ -49,6 +63,7 @@ class Edit():
def __init__(self):
self.running = False
self.trackers = {'object':[]}
self.overNode = None # preselected node with mouseover
self.obj = None
self.editing = None
@@ -271,8 +286,18 @@ class Edit():
if self.editing != None:
self.updateTrackerAndGhost(event)
else:
# TODO add preselection color change for trackers
pass
# look for a node in mouse position and highlight it
pos = event.getPosition()
node = self.getEditNode(pos)
ep = self.getEditNodeIndex(node)
if ep != None:
if self.overNode != None: self.overNode.setColor(COLORS["default"])
self.trackers[str(node.objectName.getValue())][ep].setColor(COLORS["red"])
self.overNode = self.trackers[str(node.objectName.getValue())][ep]
else:
if self.overNode != None:
self.overNode.setColor(COLORS["default"])
self.overNode = None
def startEditing(self, event):
"start editing selected EditNode"

View File

@@ -709,11 +709,11 @@ class editTracker(Tracker):
"""A node edit tracker"""
def __init__(self,pos=Vector(0,0,0),name=None,idx=0,objcol=None,\
marker=FreeCADGui.getMarkerIndex("quad", 9),inactive=False):
color = coin.SoBaseColor()
self.color = coin.SoBaseColor()
if objcol:
color.rgb = objcol[:3]
self.color.rgb = objcol[:3]
else:
color.rgb = FreeCADGui.draftToolBar.getDefaultColor("snap")
self.color.rgb = FreeCADGui.draftToolBar.getDefaultColor("snap")
self.marker = coin.SoMarkerSet() # this is the marker symbol
self.marker.markerIndex = marker
self.coords = coin.SoCoordinate3() # this is the coordinate
@@ -729,7 +729,7 @@ class editTracker(Tracker):
selnode.subElementName.setValue("EditNode"+str(idx))
node = coin.SoAnnotation()
selnode.addChild(self.coords)
selnode.addChild(color)
selnode.addChild(self.color)
selnode.addChild(self.marker)
node.addChild(selnode)
ontop = not inactive
@@ -746,6 +746,12 @@ class editTracker(Tracker):
def move(self,delta):
self.set(self.get().add(delta))
def setColor(self,color):
if color:
self.color.rgb = color
else:
self.color.rgb = FreeCADGui.draftToolBar.getDefaultColor("snap")
class PlaneTracker(Tracker):
"""A working plane tracker"""
def __init__(self):

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -399,6 +399,11 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
if plane.axis.getAngle(angle.Axis) < 0.001:
angle = angle.Angle
elif abs(plane.axis.getAngle(angle.Axis)-math.pi) < 0.001:
if abs(angle.Angle) > 0.1:
angle = -angle.Angle
else:
angle = angle.Angle
elif abs(plane.axis.getAngle(angle.Axis)-math.pi/2) < 0.001:
return "" # text is perpendicular to view, so it shouldn't appear
else:
angle = 0 #TODO maybe there is something better to do here?
@@ -501,8 +506,15 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
angle = -DraftVecUtils.angle(getProj(rv, plane))
#angle = -DraftVecUtils.angle(p3.sub(p2))
svg = ''
nolines = False
if hasattr(obj.ViewObject,"ShowLine"):
if not obj.ViewObject.ShowLine:
nolines = True
# drawing lines
svg = '<path '
if not nolines:
svg += '<path '
if obj.ViewObject.DisplayMode == "2D":
tangle = angle
if tangle > math.pi/2:
@@ -515,51 +527,54 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
if abs(tangle+math.radians(rotation)) < 0.0001:
tangle += math.pi
tbase = tbase.add(DraftVecUtils.rotate(Vector(0,2/scale,0),tangle))
svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' '
svg += 'L '+str(p2.x)+' '+str(p2.y)+' '
svg += 'L '+str(p3.x)+' '+str(p3.y)+' '
svg += 'L '+str(p4.x)+' '+str(p4.y)+'" '
if not nolines:
svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' '
svg += 'L '+str(p2.x)+' '+str(p2.y)+' '
svg += 'L '+str(p3.x)+' '+str(p3.y)+' '
svg += 'L '+str(p4.x)+' '+str(p4.y)+'" '
else:
tangle = 0
if rotation != 0:
tangle = -math.radians(rotation)
tbase = tbase.add(Vector(0,-2.0/scale,0))
svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' '
svg += 'L '+str(p2.x)+' '+str(p2.y)+' '
svg += 'L '+str(p2a.x)+' '+str(p2a.y)+' '
svg += 'M '+str(p2b.x)+' '+str(p2b.y)+' '
svg += 'L '+str(p3.x)+' '+str(p3.y)+' '
svg += 'L '+str(p4.x)+' '+str(p4.y)+'" '
if not nolines:
svg += 'd="M '+str(p1.x)+' '+str(p1.y)+' '
svg += 'L '+str(p2.x)+' '+str(p2.y)+' '
svg += 'L '+str(p2a.x)+' '+str(p2a.y)+' '
svg += 'M '+str(p2b.x)+' '+str(p2b.y)+' '
svg += 'L '+str(p3.x)+' '+str(p3.y)+' '
svg += 'L '+str(p4.x)+' '+str(p4.y)+'" '
svg += 'fill="none" stroke="'
svg += stroke + '" '
svg += 'stroke-width="' + str(linewidth) + ' px" '
svg += 'style="stroke-width:'+ str(linewidth)
svg += ';stroke-miterlimit:4;stroke-dasharray:none" '
svg += 'freecad:basepoint1="'+str(p1.x)+' '+str(p1.y)+'" '
svg += 'freecad:basepoint2="'+str(p4.x)+' '+str(p4.y)+'" '
svg += 'freecad:dimpoint="'+str(p2.x)+' '+str(p2.y)+'"'
svg += '/>\n'
if not nolines:
svg += 'fill="none" stroke="'
svg += stroke + '" '
svg += 'stroke-width="' + str(linewidth) + ' px" '
svg += 'style="stroke-width:'+ str(linewidth)
svg += ';stroke-miterlimit:4;stroke-dasharray:none" '
svg += 'freecad:basepoint1="'+str(p1.x)+' '+str(p1.y)+'" '
svg += 'freecad:basepoint2="'+str(p4.x)+' '+str(p4.y)+'" '
svg += 'freecad:dimpoint="'+str(p2.x)+' '+str(p2.y)+'"'
svg += '/>\n'
# drawing dimension and extension lines overshoots
if hasattr(obj.ViewObject,"DimOvershoot") and obj.ViewObject.DimOvershoot.Value:
shootsize = obj.ViewObject.DimOvershoot.Value/pointratio
svg += getOvershoot(p2,shootsize,stroke,linewidth,angle)
svg += getOvershoot(p3,shootsize,stroke,linewidth,angle+math.pi)
if hasattr(obj.ViewObject,"ExtOvershoot") and obj.ViewObject.ExtOvershoot.Value:
shootsize = obj.ViewObject.ExtOvershoot.Value/pointratio
shootangle = -DraftVecUtils.angle(p1.sub(p2))
svg += getOvershoot(p2,shootsize,stroke,linewidth,shootangle)
svg += getOvershoot(p3,shootsize,stroke,linewidth,shootangle)
# drawing dimension and extension lines overshoots
if hasattr(obj.ViewObject,"DimOvershoot") and obj.ViewObject.DimOvershoot.Value:
shootsize = obj.ViewObject.DimOvershoot.Value/pointratio
svg += getOvershoot(p2,shootsize,stroke,linewidth,angle)
svg += getOvershoot(p3,shootsize,stroke,linewidth,angle+math.pi)
if hasattr(obj.ViewObject,"ExtOvershoot") and obj.ViewObject.ExtOvershoot.Value:
shootsize = obj.ViewObject.ExtOvershoot.Value/pointratio
shootangle = -DraftVecUtils.angle(p1.sub(p2))
svg += getOvershoot(p2,shootsize,stroke,linewidth,shootangle)
svg += getOvershoot(p3,shootsize,stroke,linewidth,shootangle)
# drawing arrows
if hasattr(obj.ViewObject,"ArrowType"):
arrowsize = obj.ViewObject.ArrowSize.Value/pointratio
if hasattr(obj.ViewObject,"FlipArrows"):
if obj.ViewObject.FlipArrows:
angle = angle+math.pi
svg += getArrow(obj.ViewObject.ArrowType,p2,arrowsize,stroke,linewidth,angle)
svg += getArrow(obj.ViewObject.ArrowType,p3,arrowsize,stroke,linewidth,angle+math.pi)
# drawing arrows
if hasattr(obj.ViewObject,"ArrowType"):
arrowsize = obj.ViewObject.ArrowSize.Value/pointratio
if hasattr(obj.ViewObject,"FlipArrows"):
if obj.ViewObject.FlipArrows:
angle = angle+math.pi
svg += getArrow(obj.ViewObject.ArrowType,p2,arrowsize,stroke,linewidth,angle)
svg += getArrow(obj.ViewObject.ArrowType,p3,arrowsize,stroke,linewidth,angle+math.pi)
# drawing text
svg += getText(stroke,fontsize,obj.ViewObject.FontName,tangle,tbase,prx.string)

View File

@@ -29,8 +29,7 @@
#***************************************************************************/
import FreeCAD
param = FreeCAD.ParamGet(\
"User parameter:BaseApp/Preferences/Mod/OpenSCAD")
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD")
openscadfilename = param.GetString('openscadexecutable')
@@ -39,26 +38,26 @@ class OpenSCADWorkbench ( Workbench ):
def __init__(self):
self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/OpenSCAD/Resources/icons/OpenSCADWorkbench.svg"
self.__class__.MenuText = "OpenSCAD"
self.__class__.ToolTip = "OpenSCAD workbench"
self.__class__.ToolTip = "OpenSCAD is an application for creating solid 3D CAD." + '\n' +
"FreeCAD utizes OpenSCAD's capability as a script-only based modeller that uses its own description language" + '\n' +
"Note: the Mesh workbench heavily uses the boolean operations of this workbench because they are quite robust"
def Initialize(self):
def QT_TRANSLATE_NOOP(scope, text):
return text
import OpenSCAD_rc,OpenSCADCommands
commands=['OpenSCAD_ReplaceObject','OpenSCAD_RemoveSubtree',\
'OpenSCAD_RefineShapeFeature',\
'OpenSCAD_IncreaseToleranceFeature', 'OpenSCAD_Edgestofaces', \
'OpenSCAD_ExpandPlacements','OpenSCAD_ExplodeGroup']
toolbarcommands=['OpenSCAD_ReplaceObject','OpenSCAD_RemoveSubtree',\
'OpenSCAD_ExplodeGroup','OpenSCAD_RefineShapeFeature']
#'OpenSCAD_IncreaseToleranceFeature' #icon still missing
commands = ['OpenSCAD_ReplaceObject','OpenSCAD_RemoveSubtree',
'OpenSCAD_RefineShapeFeature','OpenSCAD_IncreaseToleranceFeature',
'OpenSCAD_Edgestofaces', 'OpenSCAD_ExpandPlacements','OpenSCAD_ExplodeGroup']
toolbarcommands = ['OpenSCAD_ReplaceObject','OpenSCAD_RemoveSubtree',
'OpenSCAD_ExplodeGroup','OpenSCAD_RefineShapeFeature',
'OpenSCAD_IncreaseToleranceFeature']
import PartGui
parttoolbarcommands = ['Part_CheckGeometry',"Part_Primitives",\
"Part_Builder",'Part_Cut','Part_Fuse','Part_Common',\
'Part_Extrude',"Part_Revolve"]
parttoolbarcommands = ['Part_CheckGeometry','Part_Primitives',
'Part_Builder','Part_Cut','Part_Fuse','Part_Common',
'Part_Extrude','Part_Revolve']
import FreeCAD
param = FreeCAD.ParamGet(\
"User parameter:BaseApp/Preferences/Mod/OpenSCAD")
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD")
openscadfilename = param.GetString('openscadexecutable')
if not openscadfilename:
@@ -68,10 +67,11 @@ class OpenSCADWorkbench ( Workbench ):
FreeCAD.addImportType("OpenSCAD Format (*.scad)","importCSG")
param.SetString('openscadexecutable',openscadfilename) #save the result
if openscadfilename:
commands.extend(['OpenSCAD_AddOpenSCADElement',
'OpenSCAD_MeshBoolean','OpenSCAD_Hull','OpenSCAD_Minkowski'])
toolbarcommands.extend(['OpenSCAD_AddOpenSCADElement',
'OpenSCAD_MeshBoolean','OpenSCAD_Hull','OpenSCAD_Minkowski'])
commands.extend(['OpenSCAD_AddOpenSCADElement', 'OpenSCAD_MeshBoolean',
'OpenSCAD_Hull','OpenSCAD_Minkowski'])
toolbarcommands.extend(['OpenSCAD_AddOpenSCADElement', 'OpenSCAD_MeshBoolean',
'OpenSCAD_Hull','OpenSCAD_Minkowski'])
else:
FreeCAD.Console.PrintWarning('OpenSCAD executable not found\n')

View File

@@ -22,7 +22,7 @@
__title__="FreeCAD OpenSCAD Workbench - 2D helper functions"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
__url__ = ["https://www.freecadweb.org"]
'''
This Script includes python functions to convert imported dxf geometry to Faces

View File

@@ -22,7 +22,7 @@
__title__="FreeCAD OpenSCAD Workbench - GUI Commands"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
__url__ = ["https://www.freecadweb.org"]
'''
This Script includes the GUI Commands of the OpenSCAD module
@@ -53,11 +53,10 @@ class ExplodeGroup:
return f1 == f2
else:
return abs((f1-f2)/f1) < 2**-24
scol=FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View")\
.GetUnsigned('DefaultShapeColor',0xccccccff)
defaultcolor = (((scol >> 24) & 0xff) / 255.0,\
((scol >> 16) & 0xff) / 255.0,\
((scol >> 8) & 0xff) / 255.0, 0.0)
scol=FreeCAD.ParamGet("User parameter:BaseApp/Preferences/View").GetUnsigned('DefaultShapeColor',0xccccccff)
defaultcolor = (((scol >> 24) & 0xff) / 255.0,
((scol >> 16) & 0xff) / 255.0,
((scol >> 8) & 0xff) / 255.0, 0.0)
return all(all(comparefloat(fcc,dcc) for fcc,dcc in \
zip(facecolor,defaultcolor)) for facecolor in shapecolor)
@@ -92,19 +91,16 @@ class ExplodeGroup:
else:
oo.ViewObject.DiffuseColor=color
else:
FreeCAD.Console.PrintError(translate('OpenSCAD',\
'Unable to explode %s') % obj.Name +u'\n')
FreeCAD.Console.PrintError(translate('OpenSCAD', 'Unable to explode %s') % obj.Name +u'\n')
for obj in FreeCADGui.Selection.getSelection():
if len(obj.InList) == 0: # allowed only for for top level objects
explode(obj)
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_Explode_Group', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ExplodeGroup',\
'Explode Group'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ExplodeGroup',\
'Remove fusion, apply placement to children, and color randomly')}
return {'Pixmap' : 'OpenSCAD_Explode_Group',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ExplodeGroup', 'Explode Group'),
'ToolTip': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ExplodeGroup', 'Remove fusion, apply placement to children, and color randomly')}
class ColorCodeShape:
"Change the Color of selected or all Shapes based on their validity"
@@ -118,11 +114,9 @@ class ColorCodeShape:
objs=FreeCAD.ActiveDocument.Objects
colorcodeshapes.colorcodeshapes(objs)
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_ColorCodeShape', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ColorCodeShape',\
'Color Shapes'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ColorCodeShape',\
'Color Shapes by validity and type')}
return {'Pixmap' : 'OpenSCAD_ColorCodeShape',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ColorCodeShape', 'Color Shapes'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ColorCodeShape', 'Color Shapes by validity and type')}
class Edgestofaces:
def IsActive(self):
@@ -140,10 +134,9 @@ class Edgestofaces:
FreeCAD.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'Python', 'MenuText': QtCore.QT_TRANSLATE_NOOP(\
'OpenSCAD_Edgestofaces','Convert Edges To Faces'),
'ToolTip': QtCore.QT_TRANSLATE_NOOP('OpenSCAD',\
'Convert Edges to Faces')}
return {'Pixmap' : 'Python',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Edgestofaces', 'Convert Edges To Faces'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD', 'Convert Edges to Faces')}
class RefineShapeFeature:
def IsActive(self):
@@ -160,11 +153,9 @@ class RefineShapeFeature:
selobj.Object.ViewObject.hide()
FreeCAD.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_RefineShapeFeature', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RefineShapeFeature',\
'Refine Shape Feature'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RefineShapeFeature',\
'Create Refine Shape Feature')}
return {'Pixmap' : 'OpenSCAD_RefineShapeFeature',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RefineShapeFeature', 'Refine Shape Feature'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RefineShapeFeature', 'Create Refine Shape Feature')}
class IncreaseToleranceFeature:
def IsActive(self):
@@ -181,12 +172,9 @@ class IncreaseToleranceFeature:
selobj.Object.ViewObject.hide()
FreeCAD.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_IncreaseToleranceFeature', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_IncreaseToleranceFeature',\
'Increase Tolerance Feature'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_IncreaseToleranceFeature',\
'Create Feature that allows to increase the tolerance')}
return {'Pixmap' : 'OpenSCAD_IncreaseToleranceFeature',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_IncreaseToleranceFeature', 'Increase Tolerance Feature'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_IncreaseToleranceFeature', 'Create Feature that allows to increase the tolerance')}
class ExpandPlacements:
'''This should aid interactive repair in the future
@@ -201,10 +189,9 @@ class ExpandPlacements:
expandplacements.expandplacements(selobj.Object,FreeCAD.Placement())
FreeCAD.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'Python', 'MenuText': QtCore.QT_TRANSLATE_NOOP(\
'OpenSCAD_ExpandPlacements','Expand Placements'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ExpandPlacements',\
'Expand all placements downwards the FeatureTree')}
return {'Pixmap' : 'Python',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ExpandPlacements', 'Expand Placements'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ExpandPlacements', 'Expand all placements downwards the FeatureTree')}
class ReplaceObject:
def IsActive(self):
@@ -221,15 +208,11 @@ class ReplaceObject:
tuple((len(obj.InList)) for obj in objs) in ((0,1),(1,0)):
replaceobj.replaceobjfromselection(objs)
else:
FreeCAD.Console.PrintError(translate('OpenSCAD',\
'Please select 3 objects first')+u'\n')
FreeCAD.Console.PrintError(translate('OpenSCAD', 'Please select 3 objects first')+u'\n')
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_ReplaceObject', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ReplaceObject',\
'Replace Object'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ReplaceObject',\
'Replace an object in the Feature Tree. Please select old, new, and parent object')}
return {'Pixmap' : 'OpenSCAD_ReplaceObject',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ReplaceObject', 'Replace Object'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_ReplaceObject', 'Replace an object in the Feature Tree. Please select old, new, and parent object')}
class RemoveSubtree:
def IsActive(self):
@@ -239,11 +222,9 @@ class RemoveSubtree:
OpenSCADUtils.removesubtree(FreeCADGui.Selection.getSelection())
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_RemoveSubtree', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RemoveSubtree',\
'Remove Objects and their Children'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RemoveSubtree',\
'Removes the selected objects and all children that are not referenced from other objects')}
return {'Pixmap' : 'OpenSCAD_RemoveSubtree',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RemoveSubtree', 'Remove Objects and their Children'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_RemoveSubtree', 'Removes the selected objects and all children that are not referenced from other objects')}
class AddSCADWidget(QtGui.QWidget):
def __init__(self,*args):
@@ -382,11 +363,10 @@ class AddOpenSCADElement:
panel = AddSCADTask()
FreeCADGui.Control.showDialog(panel)
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_AddOpenSCADElement', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_AddOpenSCADElement',\
'Add OpenSCAD Element...'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_AddOpenSCADElement',\
'Add an OpenSCAD element by entering OpenSCAD code and executing the OpenSCAD binary')}
return {'Pixmap' : 'OpenSCAD_AddOpenSCADElement',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_AddOpenSCADElement', 'Add OpenSCAD Element...'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_AddOpenSCADElement',
'Add an OpenSCAD element by entering OpenSCAD code and executing the OpenSCAD binary')}
class OpenSCADMeshBoolean:
def IsActive(self):
@@ -396,11 +376,10 @@ class OpenSCADMeshBoolean:
panel = OpenSCADMeshBooleanTask()
FreeCADGui.Control.showDialog(panel)
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_MeshBooleans', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_MeshBoolean',\
'Mesh Boolean...'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_MeshBoolean',\
'Export objects as meshes and use OpenSCAD to perform a boolean operation')}
return {'Pixmap' : 'OpenSCAD_MeshBooleans',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_MeshBoolean','Mesh Boolean...'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_MeshBoolean',
'Export objects as meshes and use OpenSCAD to perform a boolean operation')}
class Hull:
def IsActive(self):
@@ -417,11 +396,9 @@ class Hull:
importCSG.process_ObjectsViaOpenSCAD(FreeCAD.activeDocument(),objList,"hull")
FreeCAD.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_Hull', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Hull',\
'Hull'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Hull',\
'Perform Hull')}
return {'Pixmap' : 'OpenSCAD_Hull',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Hull', 'Hull'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Hull', 'Perform Hull')}
class Minkowski:
def IsActive(self):
@@ -438,11 +415,9 @@ class Minkowski:
importCSG.process_ObjectsViaOpenSCAD(FreeCAD.activeDocument(),objList,"minkowski")
FreeCAD.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'OpenSCAD_Minkowski', 'MenuText': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Minkowski',\
'Minkowski'), 'ToolTip': \
QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Minkowski',\
'Perform Minkowski')}
return {'Pixmap' : 'OpenSCAD_Minkowski',
'MenuText': QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Minkowski', 'Minkowski'),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP('OpenSCAD_Minkowski', 'Perform Minkowski')}
FreeCADGui.addCommand('OpenSCAD_ColorCodeShape',ColorCodeShape())
FreeCADGui.addCommand('OpenSCAD_ExplodeGroup',ExplodeGroup())

View File

@@ -22,7 +22,7 @@
__title__="FreeCAD OpenSCAD Workbench - Parametric Features"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
__url__ = ["https://www.freecadweb.org"]
try:
long

View File

@@ -22,7 +22,7 @@
__title__="FreeCAD OpenSCAD Workbench - Utility Functions"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
__url__ = ["https://www.freecadweb.org"]
'''
This Script includes various python helper functions that are shared across
@@ -70,9 +70,9 @@ def searchforopenscadexe():
return testpath
elif sys.platform == 'darwin':
ascript = (b'tell application "Finder"\n'
b'POSIX path of (application file id "org.openscad.OpenSCAD"'
b'as alias)\n'
b'end tell')
b'POSIX path of (application file id "org.openscad.OpenSCAD"'
b'as alias)\n'
b'end tell')
p1=subprocess.Popen(['osascript','-'],stdin=subprocess.PIPE,\
stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout,stderr = p1.communicate(ascript)
@@ -488,7 +488,7 @@ def meshoponobjs(opname,inobjs):
def process2D_ObjectsViaOpenSCADShape(ObjList,Operation,doc):
import FreeCAD,importDXF
import os,tempfile
# Mantis 3419
# https://www.freecadweb.org/tracker/view.php?id=3419
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD")
fn = params.GetInt('fnForImport',32)
fnStr = ",$fn=" + str(fn)
@@ -499,7 +499,7 @@ def process2D_ObjectsViaOpenSCADShape(ObjList,Operation,doc):
outputfilename=os.path.join(dir1,'%s.dxf' % next(tempfilenamegen))
importDXF.export([item],outputfilename,True,True)
filenames.append(outputfilename)
# Mantis 3419
# https://www.freecadweb.org/tracker/view.php?id=3419
dxfimports = ' '.join("import(file = \"%s\" %s);" % \
#filename \
(os.path.split(filename)[1], fnStr) for filename in filenames)

View File

@@ -22,7 +22,7 @@
__title__="FreeCAD OpenSCAD Workbench - 2D helper functions"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
__url__ = ["https://www.freecadweb.org"]
'''
This Script includes python functions to find out the most basic shape type

View File

@@ -22,7 +22,7 @@
__title__="FreeCAD OpenSCAD Workbench - expand placements and matrices functions"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
__url__ = ["https://www.freecadweb.org"]
'''
This Script includes python functions to shift all placements down the
@@ -99,7 +99,7 @@ def expandplacements(obj,placement):
elif obj.isDerivedFrom('Part::Mirroring'):
import OpenSCADUtils
mm = OpenSCADUtils.mirror2mat(obj.Normal,obj.Base)
#todo: set the base to 0,0,0
#TODO: set the base to 0,0,0
innerp=FreeCAD.Placement(mm * ownplacement.toMatrix() *mm)
expandplacements(obj.Source,innerp)
obj.Placement=FreeCAD.Placement()

View File

@@ -40,8 +40,7 @@ def openscadmesh(doc,scadstr,objname):
class Node:
#fnmin=12 # maximal fn for implicit polygon rendering
fnmin= FreeCAD.ParamGet(\
"User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
GetInt('useMaxFN')
"User parameter:BaseApp/Preferences/Mod/OpenSCAD").GetInt('useMaxFN')
planedim=1e10 #size of the square used as x-y-plane
def __init__(self,name,arguments=None,children=None,):
pass
@@ -58,8 +57,8 @@ class Node:
return str1+')'
def __nonzero__(self):
'''a Node is not obsolete if doesn't have children. Only if as neither name children or
arguments'''
'''A Node is not obsolete if doesn't have children.
Only if as neither name children or arguments'''
return bool(self.name or self.arguments or self.children)
def __len__(self):
@@ -389,8 +388,7 @@ class Node:
try:
f=edgestofaces(edges)
except Part.OCCError:
FreeCAD.Console.PrintError(\
'processing of dxf import failed\nPlease rework \'%s\' manually\n' % layera)
FreeCAD.Console.PrintError('processing of dxf import failed\nPlease rework \'%s\' manually\n' % layera)
f=Part.Shape() #empty Shape
obj=doc.addObject("Part::FeaturePython",'import_dxf_%s_%s'%(objname,layera))
#obj=doc.addObject('Part::Feature',)
@@ -399,8 +397,7 @@ class Node:
obj.Shape=f
else:
FreeCAD.Console.ErrorMessage(\
'Filetype of %s not supported\n' % (filename))
FreeCAD.Console.ErrorMessage('Filetype of %s not supported\n' % (filename))
raise(NotImplementedError)
if obj: #handle origin and scale
if scale is not None and scale !=1:
@@ -530,10 +527,10 @@ class Node:
def flattengroups(self,name='group'):
"""removes group node with only one child and no arguments and empty groups"""
node=self
while (node.name==name and len(node.children)==1 and len(node.arguments)==0):
node=node.children[0]
node.children=[child for child in node.children if not (len(child.children)==0 and child.name==name)]
node = self
while (node.name == name and len(node.children) == 1 and len(node.arguments) == 0):
node = node.children[0]
node.children = [child for child in node.children if not (len(child.children) == 0 and child.name == name)]
if node.children:
node.children = [child.flattengroups() for child in node.children]
return node
@@ -688,5 +685,3 @@ def insert(filename,docname):
global dxfcache
dxfcache = {}

View File

@@ -22,7 +22,7 @@
__title__="FreeCAD OpenSCAD Workbench - replace object function"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
__url__ = ["https://www.freecadweb.org"]
'''
This functions allows to replace an object in the feature hierarchy