Part: clean up spacing of lines in BOP JoinFeatures
This commit is contained in:
@@ -40,18 +40,27 @@ def myCustomFusionRoutine(list_of_shapes):
|
||||
... (use attributes and methods of ao) ..."""
|
||||
|
||||
def __define_attributes(self):
|
||||
self.gfa_return = None #stores the data returned by generalFuse, supplied to class constructor
|
||||
# stores the data returned by generalFuse, supplied to class constructor
|
||||
self.gfa_return = None
|
||||
|
||||
self.pieces = None #pieces that resulted from intersetion routine. List of shapes (non-decorated).
|
||||
self._piece_to_index = {} # key = decorated shape. Value = index (int) into self.pieces
|
||||
# pieces that resulted from intersetion routine. List of shapes (non-decorated).
|
||||
self.pieces = None
|
||||
# key = decorated shape. Value = index (int) into self.pieces
|
||||
self._piece_to_index = {}
|
||||
|
||||
self.source_shapes = [] # list of shapes that was supplied to generalFuse (plus the self-shape). List of shapes (non-decorated)
|
||||
self._source_to_index = {} # key = decorated shape. Value = index (int) into self.source_shapes
|
||||
# list of shapes that was supplied to generalFuse (plus the self-shape). List of shapes (non-decorated)
|
||||
self.source_shapes = []
|
||||
# key = decorated shape. Value = index (int) into self.source_shapes
|
||||
self._source_to_index = {}
|
||||
|
||||
self._pieces_of_source = [] #list of pieces (indexes) generated from a source shape, by index of source shape. List of lists of ints.
|
||||
self._sources_of_piece = [] #list of source shapes (indexes) the piece came from, by index of piece. List of lists of ints.
|
||||
#list of pieces (indexes) generated from a source shape, by index of source shape. List of lists of ints.
|
||||
self._pieces_of_source = []
|
||||
#list of source shapes (indexes) the piece came from, by index of piece. List of lists of ints.
|
||||
self._sources_of_piece = []
|
||||
|
||||
self._element_to_source = {} #dictionary for finding, which source shapes did an element of pieces come from. key = HashableShape (element). Value = set of ints
|
||||
# dictionary for finding, which source shapes did an element of pieces come from.
|
||||
# key = HashableShape (element). Value = set of ints
|
||||
self._element_to_source = {}
|
||||
|
||||
self._freeze()
|
||||
|
||||
@@ -138,7 +147,8 @@ def myCustomFusionRoutine(list_of_shapes):
|
||||
for iSource in range(len(map)):
|
||||
if len(map[iSource]) == 0:
|
||||
import FreeCAD as App
|
||||
App.Console.PrintWarning("Map entry {num} is empty. Source-to-piece correspondence information is probably incomplete.".format(num= iSource))
|
||||
App.Console.PrintWarning("Map entry {num} is empty. "
|
||||
"Source-to-piece correspondence information is probably incomplete.".format(num=iSource))
|
||||
|
||||
self._pieces_of_source = [[] for i in range(len(self.source_shapes))]
|
||||
self._sources_of_piece = [[] for i in range(len(self.pieces))]
|
||||
@@ -311,7 +321,8 @@ def myCustomFusionRoutine(list_of_shapes):
|
||||
#can't split the shape
|
||||
return [shape]
|
||||
|
||||
# for each joint, test if all bits it's connected to are from same number of sources. If not, this is a joint for splitting
|
||||
# for each joint, test if all bits it's connected to are from same number of sources.
|
||||
# If not, this is a joint for splitting
|
||||
# FIXME: this is slow, and maybe can be optimized
|
||||
splits = []
|
||||
for joint in joint_extractor(shape):
|
||||
@@ -372,7 +383,9 @@ class GeneralFuseReturnBuilder(FrozenClass):
|
||||
"GeneralFuseReturnBuilder: utility class used by splitAggregates to build fake return of generalFuse, for re-parsing."
|
||||
def __define_attributes(self):
|
||||
self.pieces = []
|
||||
self._piece_to_index = {} # key = hasher_class(shape). Value = (index_into_self_dot_pieces, shape). Note that GeneralFuseResult uses this item directly.
|
||||
# key = hasher_class(shape). Value = (index_into_self_dot_pieces, shape).
|
||||
# Note that GeneralFuseResult uses this item directly.
|
||||
self._piece_to_index = {}
|
||||
|
||||
self._pieces_from_source = [] #list of list of ints
|
||||
self.source_shapes = []
|
||||
|
||||
@@ -32,7 +32,8 @@ from .GeneralFuseResult import GeneralFuseResult
|
||||
from .Utils import compoundLeaves
|
||||
|
||||
def shapeOfMaxSize(list_of_shapes):
|
||||
"""shapeOfMaxSize(list_of_shapes): finds the shape that has the largest mass in the list and returns it. The shapes in the list must be of same dimension."""
|
||||
"""shapeOfMaxSize(list_of_shapes): finds the shape that has the largest "
|
||||
"mass in the list and returns it. The shapes in the list must be of same dimension."""
|
||||
#first, check if shapes can be compared by size
|
||||
ShapeMerge.dimensionOfShapes(list_of_shapes)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
__title__="BOPTools.JoinFeatures module"
|
||||
__title__ = "BOPTools.JoinFeatures module"
|
||||
__author__ = "DeepSOIC"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Implementation of document objects (features) for connect, ebmed and cutout operations."
|
||||
@@ -32,11 +32,11 @@ import Part
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
from PySide import QtCore, QtGui
|
||||
# -------------------------- common stuff --------------------------------------------------
|
||||
|
||||
#-------------------------- translation-related code ----------------------------------------
|
||||
#Thanks, yorik! (see forum thread "A new Part tool is being born... JoinFeatures!"
|
||||
#http://forum.freecadweb.org/viewtopic.php?f=22&t=11112&start=30#p90239 )
|
||||
# -------------------------- common stuff -------------------------------------
|
||||
|
||||
# -------------------------- translation-related code -------------------------
|
||||
# Thanks, yorik! (see forum thread "A new Part tool is being born... JoinFeatures!"
|
||||
# http://forum.freecadweb.org/viewtopic.php?f=22&t=11112&start=30#p90239 )
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
@@ -53,18 +53,20 @@ if FreeCAD.GuiUp:
|
||||
else:
|
||||
def _translate(context, text, disambig):
|
||||
return text
|
||||
#--------------------------/translation-related code ----------------------------------------
|
||||
# --------------------------/translation-related code -------------------------
|
||||
|
||||
|
||||
def getParamRefine():
|
||||
return FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Part/Boolean").GetBool("RefineModel")
|
||||
|
||||
|
||||
def cmdCreateJoinFeature(name, mode):
|
||||
"cmdCreateJoinFeature(name, mode): generalized implementation of GUI commands."
|
||||
"""cmdCreateJoinFeature(name, mode): generalized implementation of GUI commands."""
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
|
||||
FreeCAD.ActiveDocument.openTransaction("Create "+mode)
|
||||
FreeCADGui.addModule("BOPTools.JoinFeatures")
|
||||
FreeCADGui.doCommand("j = BOPTools.JoinFeatures.make{mode}(name = '{name}')".format(mode= mode, name= name))
|
||||
FreeCADGui.doCommand("j = BOPTools.JoinFeatures.make{mode}(name='{name}')".format(mode=mode, name=name))
|
||||
if mode == "Embed" or mode == "Cutout":
|
||||
FreeCADGui.doCommand("j.Base = App.ActiveDocument."+sel[0].Object.Name)
|
||||
FreeCADGui.doCommand("j.Tool = App.ActiveDocument."+sel[1].Object.Name)
|
||||
@@ -73,7 +75,7 @@ def cmdCreateJoinFeature(name, mode):
|
||||
sel= "[" + ", ".join(["App.ActiveDocument."+so.Object.Name for so in sel]) + "]"
|
||||
))
|
||||
else:
|
||||
raise ValueError("cmdCreateJoinFeature: Unexpected mode {mode}".format(mode= repr(mode)))
|
||||
raise ValueError("cmdCreateJoinFeature: Unexpected mode {mode}".format(mode=repr(mode)))
|
||||
|
||||
try:
|
||||
FreeCADGui.doCommand("j.Proxy.execute(j)")
|
||||
@@ -81,13 +83,16 @@ def cmdCreateJoinFeature(name, mode):
|
||||
except Exception as err:
|
||||
mb = QtGui.QMessageBox()
|
||||
mb.setIcon(mb.Icon.Warning)
|
||||
mb.setText(_translate("Part_JoinFeatures","Computing the result failed with an error: \n\n{err}\n\n Click 'Continue' to create the feature anyway, or 'Abort' to cancel.", None)
|
||||
.format(err= str(err)))
|
||||
mb.setText(_translate("Part_JoinFeatures",
|
||||
"Computing the result failed with an error:\n\n"
|
||||
"{err}\n\n"
|
||||
"Click 'Continue' to create the feature anyway, or 'Abort' to cancel.", None)
|
||||
.format(err=str(err)))
|
||||
mb.setWindowTitle(_translate("Part_JoinFeatures","Bad selection", None))
|
||||
btnAbort = mb.addButton(QtGui.QMessageBox.StandardButton.Abort)
|
||||
btnOK = mb.addButton(_translate("Part_JoinFeatures","Continue",None), QtGui.QMessageBox.ButtonRole.ActionRole)
|
||||
btnOK = mb.addButton(_translate("Part_JoinFeatures","Continue",None),
|
||||
QtGui.QMessageBox.ButtonRole.ActionRole)
|
||||
mb.setDefaultButton(btnOK)
|
||||
|
||||
mb.exec_()
|
||||
|
||||
if mb.clickedButton() is btnAbort:
|
||||
@@ -99,12 +104,13 @@ def cmdCreateJoinFeature(name, mode):
|
||||
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
|
||||
|
||||
def getIconPath(icon_dot_svg):
|
||||
return icon_dot_svg
|
||||
|
||||
# -------------------------- /common stuff --------------------------------------------------
|
||||
# -------------------------- /common stuff ------------------------------------
|
||||
|
||||
# -------------------------- Connect --------------------------------------------------
|
||||
# -------------------------- Connect ------------------------------------------
|
||||
|
||||
def makeConnect(name):
|
||||
'''makeConnect(name): makes an Connect object.'''
|
||||
@@ -114,13 +120,18 @@ def makeConnect(name):
|
||||
ViewProviderConnect(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
class FeatureConnect:
|
||||
"The PartJoinFeature object"
|
||||
"""The PartJoinFeature object."""
|
||||
|
||||
def __init__(self,obj):
|
||||
obj.addProperty("App::PropertyLinkList","Objects","Connect","Object to be connectded.")
|
||||
obj.addProperty("App::PropertyBool","Refine","Connect","True = refine resulting shape. False = output as is.")
|
||||
obj.addProperty("App::PropertyBool","Refine","Connect",
|
||||
"True = refine resulting shape. False = output as is.")
|
||||
obj.Refine = getParamRefine()
|
||||
obj.addProperty("App::PropertyLength","Tolerance","Connect","Tolerance when intersecting (fuzzy value). In addition to tolerances of the shapes.")
|
||||
obj.addProperty("App::PropertyLength","Tolerance","Connect",
|
||||
"Tolerance when intersecting (fuzzy value). "
|
||||
"In addition to tolerances of the shapes.")
|
||||
|
||||
obj.Proxy = self
|
||||
self.Type = "FeatureConnect"
|
||||
@@ -133,7 +144,7 @@ class FeatureConnect:
|
||||
|
||||
|
||||
class ViewProviderConnect:
|
||||
"A View Provider for the Part Connect feature"
|
||||
"""A View Provider for the Part Connect feature."""
|
||||
|
||||
def __init__(self,vobj):
|
||||
vobj.Proxy = self
|
||||
@@ -179,20 +190,23 @@ class ViewProviderConnect:
|
||||
|
||||
|
||||
class CommandConnect:
|
||||
"Command to create Connect feature"
|
||||
"""Command to create Connect feature."""
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap' : getIconPath("Part_JoinConnect.svg"),
|
||||
return {'Pixmap': getIconPath("Part_JoinConnect.svg"),
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Part_JoinConnect","Connect objects"),
|
||||
'Accel': "",
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Part_JoinConnect","Fuses objects, taking care to preserve voids.")}
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Part_JoinConnect",
|
||||
"Fuses objects, taking care to preserve voids.")}
|
||||
|
||||
def Activated(self):
|
||||
if len(FreeCADGui.Selection.getSelectionEx()) >= 1 :
|
||||
cmdCreateJoinFeature(name = "Connect", mode = "Connect")
|
||||
if len(FreeCADGui.Selection.getSelectionEx()) >= 1:
|
||||
cmdCreateJoinFeature(name="Connect", mode="Connect")
|
||||
else:
|
||||
mb = QtGui.QMessageBox()
|
||||
mb.setIcon(mb.Icon.Warning)
|
||||
mb.setText(_translate("Part_JoinFeatures", "Select at least two objects, or one or more compounds, first!", None))
|
||||
mb.setText(_translate("Part_JoinFeatures",
|
||||
"Select at least two objects, or one or more compounds", None))
|
||||
mb.setWindowTitle(_translate("Part_JoinFeatures","Bad selection", None))
|
||||
mb.exec_()
|
||||
|
||||
@@ -202,10 +216,10 @@ class CommandConnect:
|
||||
else:
|
||||
return False
|
||||
|
||||
# -------------------------- /Connect --------------------------------------------------
|
||||
# -------------------------- /Connect -----------------------------------------
|
||||
|
||||
|
||||
# -------------------------- Embed --------------------------------------------------
|
||||
# -------------------------- Embed --------------------------------------------
|
||||
|
||||
|
||||
def makeEmbed(name):
|
||||
@@ -216,14 +230,19 @@ def makeEmbed(name):
|
||||
ViewProviderEmbed(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
class FeatureEmbed:
|
||||
"The Part Embed object"
|
||||
"""The Part Embed object."""
|
||||
|
||||
def __init__(self,obj):
|
||||
obj.addProperty("App::PropertyLink","Base","Embed","Object to embed into.")
|
||||
obj.addProperty("App::PropertyLink","Tool","Embed","Object to be embedded.")
|
||||
obj.addProperty("App::PropertyBool","Refine","Embed","True = refine resulting shape. False = output as is.")
|
||||
obj.addProperty("App::PropertyBool","Refine","Embed",
|
||||
"True = refine resulting shape. False = output as is.")
|
||||
obj.Refine = getParamRefine()
|
||||
obj.addProperty("App::PropertyLength","Tolerance","Embed","Tolerance when intersecting (fuzzy value). In addition to tolerances of the shapes.")
|
||||
obj.addProperty("App::PropertyLength","Tolerance","Embed",
|
||||
"Tolerance when intersecting (fuzzy value). "
|
||||
"In addition to tolerances of the shapes.")
|
||||
|
||||
obj.Proxy = self
|
||||
self.Type = "FeatureEmbed"
|
||||
@@ -236,7 +255,7 @@ class FeatureEmbed:
|
||||
|
||||
|
||||
class ViewProviderEmbed:
|
||||
"A View Provider for the Part Embed feature"
|
||||
"""A View Provider for the Part Embed feature."""
|
||||
|
||||
def __init__(self,vobj):
|
||||
vobj.Proxy = self
|
||||
@@ -265,36 +284,39 @@ class ViewProviderEmbed:
|
||||
FreeCAD.Console.PrintError("Error in onDelete: " + str(err))
|
||||
return True
|
||||
|
||||
|
||||
class CommandEmbed:
|
||||
"Command to create Part Embed feature"
|
||||
"""Command to create Part Embed feature."""
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap' : getIconPath("Part_JoinEmbed.svg"),
|
||||
return {'Pixmap': getIconPath("Part_JoinEmbed.svg"),
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Part_JoinEmbed","Embed object"),
|
||||
'Accel': "",
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Part_JoinEmbed","Fuses one object into another, taking care to preserve voids.")}
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Part_JoinEmbed",
|
||||
"Fuses one object into another, taking care to preserve voids.")}
|
||||
|
||||
def Activated(self):
|
||||
if len(FreeCADGui.Selection.getSelectionEx()) == 2 :
|
||||
if len(FreeCADGui.Selection.getSelectionEx()) == 2:
|
||||
cmdCreateJoinFeature(name = "Embed", mode = "Embed")
|
||||
else:
|
||||
mb = QtGui.QMessageBox()
|
||||
mb.setIcon(mb.Icon.Warning)
|
||||
mb.setText(_translate("Part_JoinFeatures","Select base object, then the object to embed, and invoke this tool.", None))
|
||||
mb.setText(_translate("Part_JoinFeatures",
|
||||
"Select base object, then the object to embed, "
|
||||
"and then invoke this tool.", None))
|
||||
mb.setWindowTitle(_translate("Part_JoinFeatures","Bad selection", None))
|
||||
mb.exec_()
|
||||
|
||||
|
||||
def IsActive(self):
|
||||
if FreeCAD.ActiveDocument:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
# -------------------------- /Embed --------------------------------------------------
|
||||
# -------------------------- /Embed -------------------------------------------
|
||||
|
||||
|
||||
|
||||
# -------------------------- Cutout --------------------------------------------------
|
||||
# -------------------------- Cutout -------------------------------------------
|
||||
|
||||
def makeCutout(name):
|
||||
'''makeCutout(name): makes an Cutout object.'''
|
||||
@@ -304,14 +326,18 @@ def makeCutout(name):
|
||||
ViewProviderCutout(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
class FeatureCutout:
|
||||
"The Part Cutout object"
|
||||
"""The Part Cutout object."""
|
||||
|
||||
def __init__(self,obj):
|
||||
obj.addProperty("App::PropertyLink","Base","Cutout","Object to be cut.")
|
||||
obj.addProperty("App::PropertyLink","Tool","Cutout","Object to make cutout for.")
|
||||
obj.addProperty("App::PropertyBool","Refine","Cutout","True = refine resulting shape. False = output as is.")
|
||||
obj.addProperty("App::PropertyBool","Refine","Cutout",
|
||||
"True = refine resulting shape. False = output as is.")
|
||||
obj.Refine = getParamRefine()
|
||||
obj.addProperty("App::PropertyLength","Tolerance","Cutout","Tolerance when intersecting (fuzzy value). In addition to tolerances of the shapes.")
|
||||
obj.addProperty("App::PropertyLength","Tolerance","Cutout",
|
||||
"Tolerance when intersecting (fuzzy value). In addition to tolerances of the shapes.")
|
||||
|
||||
obj.Proxy = self
|
||||
self.Type = "FeatureCutout"
|
||||
@@ -324,7 +350,7 @@ class FeatureCutout:
|
||||
|
||||
|
||||
class ViewProviderCutout:
|
||||
"A View Provider for the Part Cutout feature"
|
||||
"""A View Provider for the Part Cutout feature."""
|
||||
|
||||
def __init__(self,vobj):
|
||||
vobj.Proxy = self
|
||||
@@ -355,20 +381,25 @@ class ViewProviderCutout:
|
||||
|
||||
|
||||
class CommandCutout:
|
||||
"Command to create PartJoinFeature in Cutout mode"
|
||||
"""Command to create PartJoinFeature in Cutout mode."""
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap' : getIconPath("Part_JoinCutout.svg"),
|
||||
return {'Pixmap': getIconPath("Part_JoinCutout.svg"),
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Part_JoinCutout","Cutout for object"),
|
||||
'Accel': "",
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Part_JoinCutout","Makes a cutout in one object to fit another object.")}
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Part_JoinCutout",
|
||||
"Makes a cutout in one object to fit another object.")}
|
||||
|
||||
def Activated(self):
|
||||
if len(FreeCADGui.Selection.getSelectionEx()) == 2 :
|
||||
cmdCreateJoinFeature(name = "Cutout", mode = "Cutout")
|
||||
if len(FreeCADGui.Selection.getSelectionEx()) == 2:
|
||||
cmdCreateJoinFeature(name="Cutout", mode="Cutout")
|
||||
else:
|
||||
mb = QtGui.QMessageBox()
|
||||
mb.setIcon(mb.Icon.Warning)
|
||||
mb.setText(_translate("Part_JoinFeatures","Select the object to make a cutout in, then the object that should fit into the cutout, and invoke this tool.", None))
|
||||
mb.setText(_translate("Part_JoinFeatures",
|
||||
"Select the object to make a cutout in, "
|
||||
"then the object that should fit into the cutout, "
|
||||
"and then invoke this tool.", None))
|
||||
mb.setWindowTitle(_translate("Part_JoinFeatures","Bad selection", None))
|
||||
mb.exec_()
|
||||
|
||||
@@ -378,9 +409,9 @@ class CommandCutout:
|
||||
else:
|
||||
return False
|
||||
|
||||
# -------------------------- /Cutout --------------------------------------------------
|
||||
# -------------------------- /Cutout ------------------------------------------
|
||||
|
||||
def addCommands():
|
||||
FreeCADGui.addCommand('Part_JoinCutout',CommandCutout())
|
||||
FreeCADGui.addCommand('Part_JoinEmbed',CommandEmbed())
|
||||
FreeCADGui.addCommand('Part_JoinConnect',CommandConnect())
|
||||
FreeCADGui.addCommand('Part_JoinCutout', CommandCutout())
|
||||
FreeCADGui.addCommand('Part_JoinEmbed', CommandEmbed())
|
||||
FreeCADGui.addCommand('Part_JoinConnect', CommandConnect())
|
||||
|
||||
Reference in New Issue
Block a user