diff --git a/freecad/Curves/splitCurves.py b/freecad/Curves/splitCurves.py deleted file mode 100644 index bdbd25f..0000000 --- a/freecad/Curves/splitCurves.py +++ /dev/null @@ -1,164 +0,0 @@ -# -*- coding: utf-8 -*- - -__title__ = "Split curve" -__author__ = "Christophe Grellier (Chris_G)" -__license__ = "LGPL 2.1" -__doc__ = "Splits the selected edge." - -import FreeCAD -import FreeCADGui -import Part -import _utils - -TOOL_ICON = _utils.iconsPath() + '/splitcurve.svg' -debug = _utils.debug -#debug = _utils.doNothing - -class split: - """Splits the selected edge.""" - def __init__(self, obj, e): - obj.addProperty("App::PropertyLinkSub", "Edge", "Split", "Edge to split").Edge = e - obj.addProperty("App::PropertyEnumeration", "Method", "Split", "Splitting method").Method = ['Parameter','Distance','Percent'] - obj.addProperty("App::PropertyEnumeration", "Output", "Split", "Output type").Output = ['Wire','Start','End'] - obj.addProperty("App::PropertyFloat", "Value", "Split", "Split at given parameter") - obj.addProperty("App::PropertyFloat", "Param", "Split", "Parameter") - obj.setEditorMode("Param", 2) - obj.Method = 'Percent' - obj.Output = 'Wire' - obj.Value = 50.0 - obj.Proxy = self - - def onChanged(self, fp, prop): - e = _utils.getShape(fp, "Edge", "Edge") - if not e: - return - if prop == "Edge": - debug("Split : Edge changed") - if prop == "Method": - debug("Split : Method changed") - if fp.Method == "Percent": - fp.Value = self.ParamToPercent(e, fp.Param) - elif fp.Method == "Distance": - fp.Value = self.ParamToDistance(e, fp.Param) - else: - fp.Value = fp.Param - if prop == "Value": - if fp.Method == "Percent": - if fp.Value < 0: - fp.Value = 0 - elif fp.Value > 100: - fp.Value = 100 - fp.Param = self.PercentToParam(e, fp.Value) - elif fp.Method == "Distance": - if fp.Value < -e.Length: - fp.Value = -e.Length - elif fp.Value > e.Length: - fp.Value = e.Length - fp.Param = self.DistanceToParam(e, fp.Value) - else: # fp.Method == "Parameter" - if fp.Value < e.FirstParameter: - fp.Value = e.FirstParameter - elif fp.Value > e.LastParameter: - fp.Value = e.LastParameter - fp.Param = fp.Value - self.execute(fp) - - def PercentToParam(self, e, per): - prange = e.LastParameter - e.FirstParameter - return (e.FirstParameter + 0.01*per*prange) - - def DistanceToParam(self, e, dis): - prange = e.LastParameter - e.FirstParameter - if dis >= e.Length: - return(e.LastParameter) - elif dis <= -e.Length: - return(e.FirstParameter) - else: - return (e.getParameterByLength(dis)) - - def ParamToPercent(self, e, par): - prange = e.LastParameter - e.FirstParameter - return (100.0*(par-e.FirstParameter)/prange) - - def ParamToDistance(self, e, par): - #prange = e.LastParameter - e.FirstParameter - dis = Part.Edge(e.Curve,e.FirstParameter,par).Length - return (dis) - - def execute(self, obj): - e = _utils.getShape(obj, "Edge", "Edge") - p = obj.Value - if obj.Method == "Percent": - p = self.PercentToParam(e, obj.Value) - elif obj.Method == "Distance": - p = self.DistanceToParam(e, obj.Value) - if p > e.FirstParameter and p < e.LastParameter: - w = e.split(p) - if obj.Output == "Start": - obj.Shape = w.Edges[0] - elif obj.Output == "End": - obj.Shape = w.Edges[-1] - else: - obj.Shape = w - else: - obj.Shape = e - obj.Placement = e.Placement - - def onDocumentRestored(self, fp): - fp.setEditorMode("Param", 2) - -class splitVP: - def __init__(self,vobj): - vobj.Proxy = self - - def getIcon(self): - return (TOOL_ICON) - - def attach(self, vobj): - self.Object = vobj.Object - - def __getstate__(self): - return({"name": self.Object.Name}) - - def __setstate__(self,state): - self.Object = FreeCAD.ActiveDocument.getObject(state["name"]) - return(None) - - def claimChildren(self): - return [self.Object.Edge[0]] - -class splitCommand: - """Splits the selected edges.""" - def makeSplitFeature(self,e): - splitCurve = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","SplitCurve") - split(splitCurve, e) - splitVP(splitCurve.ViewObject) - FreeCAD.ActiveDocument.recompute() - splitCurve.Value = 50.0 - splitCurve.ViewObject.PointSize = 5.0 - - def Activated(self): - edges = [] - sel = FreeCADGui.Selection.getSelectionEx() - if sel == []: - FreeCAD.Console.PrintError("Select the edges to split first !\n") - for selobj in sel: - if selobj.HasSubObjects: - for i in range(len(selobj.SubObjects)): - if isinstance(selobj.SubObjects[i], Part.Edge): - self.makeSplitFeature((selobj.Object, selobj.SubElementNames[i])) - if selobj.Object.Shape: - if len(selobj.Object.Shape.Edges) == 1: - selobj.Object.ViewObject.Visibility = False - - def IsActive(self): - if FreeCAD.ActiveDocument: - f = FreeCADGui.Selection.Filter("SELECT Part::Feature SUBELEMENT Edge COUNT 1..1000") - return f.match() - else: - return(False) - - def GetResources(self): - return {'Pixmap' : TOOL_ICON, 'MenuText': 'Split Curve', 'ToolTip': 'Splits the selected edge'} - -FreeCADGui.addCommand('split', splitCommand()) diff --git a/freecad/Curves/splitCurves_2.py b/freecad/Curves/splitCurves_2.py index ac03ffa..5c41d58 100644 --- a/freecad/Curves/splitCurves_2.py +++ b/freecad/Curves/splitCurves_2.py @@ -15,10 +15,13 @@ import Part from freecad.Curves import _utils from freecad.Curves import ICONPATH +from freecad.Curves.nurbs_tools import knotSeqNormalize + from pivy import coin from freecad.Curves import graphics from freecad.Curves import manipulators + TOOL_ICON = os.path.join(ICONPATH, 'splitcurve.svg') #debug = _utils.debug debug = _utils.doNothing @@ -29,17 +32,25 @@ def __init__(self, obj, e): obj.Proxy = self obj.addProperty("App::PropertyLinkSub", "Source", - "Split", + "Base", "Edge to split").Source = e obj.addProperty("App::PropertyStringList", "Values", "Split", "List of splitting locations\n% and units are allowed\nNegative values are computed from edge end") - #obj.addProperty("App::PropertyFloatList", - #"Parameters", - #"Split", - #"Parameter list") - #obj.setEditorMode("Parameters",2) + obj.addProperty("App::PropertyLinkList", + "CuttingObjects", + "Split", + "List of objects that cut the curve") + obj.addProperty("App::PropertyDistance", + "Distance", + "Split", + "Expression-ready distance value") + obj.addProperty("App::PropertyFloatList", + "NormalizedParameters", + "Output", + "Normalized parameters list") + obj.setEditorMode("NormalizedParameters",2) def getShape(self, fp): if fp.Source is None: @@ -76,6 +87,7 @@ def parse_value(self, edge, v): par = edge.Curve.parameterAtDistance(num_val, edge.FirstParameter) if par > edge.FirstParameter and par < edge.LastParameter: return par, t + return None, None def parse_values(self, edge, values): #edge = self.getShape(fp, "Source", "Edge") @@ -84,7 +96,8 @@ def parse_values(self, edge, values): parameters = [] for v in values: par, t = self.parse_value(edge, v) - parameters.append(par) + if par: + parameters.append(par) parameters.sort() return parameters @@ -103,15 +116,32 @@ def onChanged(self, fp, prop): def execute(self, obj): e, w = self.getShape(obj) - params = [] + if not isinstance(e, Part.Edge): + return + val = [] if hasattr(obj, "Values"): - params = self.parse_values(e, obj.Values) + val = obj.Values + if hasattr(obj, "Distance"): + val.append(obj.Distance.toStr()) + + params = [] + if val: + params = self.parse_values(e, val) + if hasattr(obj, "CuttingObjects"): + for o in obj.CuttingObjects: + d, pts, info = e.distToShape(o.Shape) + if info[0][0] == 'Edge': + debug('adding param : {}'.format(info[0][2])) + params.append(info[0][2]) + if params == []: if w: obj.Shape = obj.Source[0].Shape else: obj.Shape = e return + + params.sort() if params[0] > e.FirstParameter: params.insert(0, e.FirstParameter) if params[-1] < e.LastParameter: @@ -155,6 +185,7 @@ def execute(self, obj): w = Part.Wire(se[0]) if w.isValid(): obj.Shape = w + obj.NormalizedParameters = knotSeqNormalize(params) else: FreeCAD.Console.PrintError("Split curve : Invalid Wire !") obj.Shape = e