From 2ed8e5dd995c76e85db0ea0d8b98ca861bf3834d Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Thu, 21 Jan 2016 14:02:56 -0200 Subject: [PATCH] Path: misc bugfixes + restored node markers --- src/Mod/Draft/DraftGeomUtils.py | 27 ++++++++------- src/Mod/Path/Gui/ViewProviderPath.cpp | 38 +++++++++++++--------- src/Mod/Path/Gui/ViewProviderPath.h | 1 + src/Mod/Path/PathScripts/PathArray.py | 2 +- src/Mod/Path/PathScripts/PathFacePocket.py | 21 ++++++++---- src/Mod/Path/PathScripts/PathProject.py | 22 ++++++++----- 6 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/Mod/Draft/DraftGeomUtils.py b/src/Mod/Draft/DraftGeomUtils.py index be1b866b7..3e9edf6ee 100755 --- a/src/Mod/Draft/DraftGeomUtils.py +++ b/src/Mod/Draft/DraftGeomUtils.py @@ -474,43 +474,48 @@ def pocket2d(shape,offset): if not o.Wires: return [] offsetWires = o.Wires - print("base offset wires:",offsetWires) + #print("base offset wires:",offsetWires) if not innerWires: return offsetWires for innerWire in innerWires: i = innerWire.makeOffset(offset) + if len(innerWire.Edges) == 1: + e = innerWire.Edges[0] + if isinstance(e.Curve,Part.Circle): + e = Part.makeCircle(e.Curve.Radius+offset,e.Curve.Center,e.Curve.Axis) + i = Part.Wire(e) if i.Wires: - print("offsetting island ",innerWire," : ",i.Wires) + #print("offsetting island ",innerWire," : ",i.Wires) for w in i.Wires: added = False - print("checking wire ",w) + #print("checking wire ",w) k = list(range(len(offsetWires))) for j in k: - print("checking against existing wire ",j) + #print("checking against existing wire ",j) ow = offsetWires[j] if ow: if wiresIntersect(w,ow): - print("intersect") + #print("intersect") f1 = Part.Face(ow) f2 = Part.Face(w) f3 = f1.cut(f2) - print("made new wires: ",f3.Wires) + #print("made new wires: ",f3.Wires) offsetWires[j] = f3.Wires[0] if len(f3.Wires) > 1: - print("adding more") + #print("adding more") offsetWires.extend(f3.Wires[1:]) added = True else: a = w.BoundBox b = ow.BoundBox if (a.XMin <= b.XMin) and (a.YMin <= b.YMin) and (a.ZMin <= b.ZMin) and (a.XMax >= b.XMax) and (a.YMax >= b.YMax) and (a.ZMax >= b.ZMax): - print("this wire is bigger than the outer wire") + #print("this wire is bigger than the outer wire") offsetWires[j] = None added = True - else: - print("doesn't intersect") + #else: + #print("doesn't intersect") if not added: - print("doesn't intersect with any other") + #print("doesn't intersect with any other") offsetWires.append(w) offsetWires = [o for o in offsetWires if o != None] return offsetWires diff --git a/src/Mod/Path/Gui/ViewProviderPath.cpp b/src/Mod/Path/Gui/ViewProviderPath.cpp index cfc449f74..0974d45e7 100644 --- a/src/Mod/Path/Gui/ViewProviderPath.cpp +++ b/src/Mod/Path/Gui/ViewProviderPath.cpp @@ -81,6 +81,7 @@ ViewProviderPath::ViewProviderPath() ADD_PROPERTY_TYPE(MarkerColor,(mr,mg,mb),"Path",App::Prop_None,"The color of the markers"); ADD_PROPERTY_TYPE(LineWidth,(lwidth),"Path",App::Prop_None,"The line width of this path"); ADD_PROPERTY_TYPE(ShowFirstRapid,(true),"Path",App::Prop_None,"Turns the display of the first rapid move on/off"); + ADD_PROPERTY_TYPE(ShowNodes,(false),"Path",App::Prop_None,"Turns the display of nodes on/off"); pcPathRoot = new Gui::SoFCSelection(); @@ -204,7 +205,7 @@ void ViewProviderPath::onChanged(const App::Property* prop) } else if (prop == &MarkerColor) { const App::Color& c = MarkerColor.getValue(); pcMarkerColor->rgb.setValue(c.r,c.g,c.b); - } else if (prop == &ShowFirstRapid) { + } else if ( (prop == &ShowFirstRapid) || (prop == &ShowNodes) ) { Path::Feature* pcPathObj = static_cast(pcObject); this->updateData(&pcPathObj->Path); } else { @@ -216,7 +217,7 @@ void ViewProviderPath::updateData(const App::Property* prop) { Path::Feature* pcPathObj = static_cast(pcObject); - if ( prop == &pcPathObj->Path) { + if (prop == &pcPathObj->Path) { const Toolpath &tp = pcPathObj->Path.getValue(); if(tp.getSize()==0) @@ -252,7 +253,8 @@ void ViewProviderPath::updateData(const App::Property* prop) markers.push_back(last); // startpoint of path } points.push_back(next); - //markers.push_back(next); // endpoint + if (ShowNodes.getValue() == true) + markers.push_back(next); // endpoint last = next; if ( (name == "G0") || (name == "G00") ) colorindex.push_back(0); // rapid color @@ -277,9 +279,11 @@ void ViewProviderPath::updateData(const App::Property* prop) //double radius = (last - center).Length(); double angle = (next - center).GetAngle(last - center); // BUGGY: not needed anyway? - //Base::Vector3d anorm = (last - center) % (next - center); - //if (anorm.z < 0) - // angle = M_PI - angle; + Base::Vector3d anorm = (last - center) % (next - center); + if ( (anorm.z < 0) && ( (name == "G3") || (name == "G03") ) ) + angle = M_PI * 2 - angle; + if (angle == 0) + angle = M_PI * 2; int segments = 3/(deviation/angle); //we use a rather simple rule here, provisorily for (int j = 1; j < segments; j++) { //std::cout << "vector " << j << std::endl; @@ -293,8 +297,10 @@ void ViewProviderPath::updateData(const App::Property* prop) } //std::cout << "next " << next.x << " , " << next.y << " , " << next.z << std::endl; points.push_back(next); - //markers.push_back(next); // endpoint - //markers.push_back(center); // add a marker at center too + if (ShowNodes.getValue() == true) { + markers.push_back(next); // endpoint + markers.push_back(center); // add a marker at center too + } last = next; colorindex.push_back(1); @@ -314,14 +320,17 @@ void ViewProviderPath::updateData(const App::Property* prop) Base::Vector3d p1(next.x,next.y,last.z); // Base::Vector3d p1(next.x,next.y,r); points.push_back(p1); - //markers.push_back(p1); + if (ShowNodes.getValue() == true) + markers.push_back(p1); colorindex.push_back(0); Base::Vector3d p2(next.x,next.y,r); points.push_back(p2); - //markers.push_back(p2); + if (ShowNodes.getValue() == true) + markers.push_back(p2); colorindex.push_back(0); points.push_back(next); - //markers.push_back(next); + if (ShowNodes.getValue() == true) + markers.push_back(next); colorindex.push_back(1); double q; if (cmd.has("Q")) { @@ -335,7 +344,8 @@ void ViewProviderPath::updateData(const App::Property* prop) } Base::Vector3d p3(next.x,next.y,last.z); points.push_back(p3); - //markers.push_back(p2); + if (ShowNodes.getValue() == true) + markers.push_back(p2); colorindex.push_back(0); } } @@ -354,10 +364,6 @@ void ViewProviderPath::updateData(const App::Property* prop) pcMarkerCoords->point.deleteValues(0); - // putting one marker at each node makes the display awfully slow - // following 2 lines leave just one at the origin - //pcMarkerCoords->point.setNum(1); - //pcMarkerCoords->point.set1Value(0,markers[0].x,markers[0].y,markers[0].z); pcMarkerCoords->point.setNum(markers.size()); for(unsigned int i=0;ipoint.set1Value(i,markers[i].x,markers[i].y,markers[i].z); diff --git a/src/Mod/Path/Gui/ViewProviderPath.h b/src/Mod/Path/Gui/ViewProviderPath.h index 8e14e2d00..e2ac4bf29 100644 --- a/src/Mod/Path/Gui/ViewProviderPath.h +++ b/src/Mod/Path/Gui/ViewProviderPath.h @@ -55,6 +55,7 @@ public: App::PropertyColor NormalColor; App::PropertyColor MarkerColor; App::PropertyBool ShowFirstRapid; + App::PropertyBool ShowNodes; void attach(App::DocumentObject *pcObject); void setDisplayMode(const char* ModeName); diff --git a/src/Mod/Path/PathScripts/PathArray.py b/src/Mod/Path/PathScripts/PathArray.py index 1008f2cc1..af0b802dd 100644 --- a/src/Mod/Path/PathScripts/PathArray.py +++ b/src/Mod/Path/PathScripts/PathArray.py @@ -42,7 +42,7 @@ class ObjectArray: def __init__(self,obj): obj.addProperty("App::PropertyLink","Base","Path","The path to array") - obj.addProperty("App::PropertyVector","Offset","Path","The spacing between the array copies") + obj.addProperty("App::PropertyVectorDistance","Offset","Path","The spacing between the array copies") obj.addProperty("App::PropertyInteger","Copies","Path","The number of copies") obj.Proxy = self diff --git a/src/Mod/Path/PathScripts/PathFacePocket.py b/src/Mod/Path/PathScripts/PathFacePocket.py index c5c6d518c..c7a71a94d 100644 --- a/src/Mod/Path/PathScripts/PathFacePocket.py +++ b/src/Mod/Path/PathScripts/PathFacePocket.py @@ -45,6 +45,8 @@ class ObjectFacePocket: obj.addProperty("App::PropertyDistance","Offset","Path","The distance between the face and the path") obj.addProperty("App::PropertyInteger","StartVertex","Path","The vertex index to start the path from") obj.addProperty("App::PropertyEnumeration","FirstMove","Path","The type of the first move") + obj.addProperty("App::PropertyDistance","RetractHeight","Path","The height to travel at between loops") + obj.addProperty("App::PropertyBool","Fill","Path","Perform only one loop or fill the whole shape") obj.FirstMove = ["G0","G1"] obj.Proxy = self @@ -55,7 +57,7 @@ class ObjectFacePocket: return None def execute(self,obj): - if obj.Base and obj.Offset: + if obj.Base and obj.Offset.Value: import Part, DraftGeomUtils if "Face" in obj.Base[1][0]: shape = getattr(obj.Base[0].Shape,obj.Base[1][0]) @@ -68,15 +70,18 @@ class ObjectFacePocket: # build offsets offsets = [] - nextradius = obj.Offset + nextradius = obj.Offset.Value result = DraftGeomUtils.pocket2d(shape,nextradius) while result: offsets.extend(result) - nextradius += obj.Offset - result = DraftGeomUtils.pocket2d(shape,nextradius) + if obj.Fill: + nextradius += obj.Offset.Value + result = DraftGeomUtils.pocket2d(shape,nextradius) + else: + result = [] - # first move will be rapid, subsequent will be at feed rate first = True + point = None # revert the list so we start with the outer wires offsets.reverse() @@ -94,6 +99,10 @@ class ObjectFacePocket: output += obj.FirstMove first = False else: + if obj.RetractHeight.Value and point: + output += "G0 X" + str("%f" % point.x) + " Y" + str("%f" % point.y) + " Z" + str("%f" % obj.RetractHeight.Value) + "\n" + last = edge.Vertexes[0].Point + output += "G0 X" + str("%f" % last.x) + " Y" + str("%f" % last.y) + " Z" + str("%f" % obj.RetractHeight.Value) + "\n" output += "G1" last = edge.Vertexes[0].Point output += " X" + str("%f" % last.x) + " Y" + str("%f" % last.y) + " Z" + str("%f" % last.z) + "\n" @@ -105,7 +114,7 @@ class ObjectFacePocket: relcenter = center.sub(last) v1 = last.sub(center) v2 = point.sub(center) - if v1.cross(v2).z < 0: + if edge.Curve.Axis.z < 0: output += "G2" else: output += "G3" diff --git a/src/Mod/Path/PathScripts/PathProject.py b/src/Mod/Path/PathScripts/PathProject.py index a542253d2..004fe6b6e 100644 --- a/src/Mod/Path/PathScripts/PathProject.py +++ b/src/Mod/Path/PathScripts/PathProject.py @@ -66,7 +66,11 @@ class ObjectPathProject: cmds = [] for child in obj.Group: if child.isDerivedFrom("Path::Feature"): - cmds.extend(child.Path.Commands) + if obj.UsePlacements: + for c in child.Path.Commands: + cmds.append(c.transform(child.Placement)) + else: + cmds.extend(child.Path.Commands) if cmds: path = Path.Path(cmds) obj.Path = path @@ -76,16 +80,16 @@ class ViewProviderProject: def __init__(self,vobj): vobj.Proxy = self mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) +# vobj.setEditorMode('LineWidth',mode) +# vobj.setEditorMode('MarkerColor',mode) +# vobj.setEditorMode('NormalColor',mode) # vobj.setEditorMode('ShowFirstRapid',mode) vobj.setEditorMode('BoundingBox',mode) vobj.setEditorMode('DisplayMode',mode) vobj.setEditorMode('Selectable',mode) vobj.setEditorMode('ShapeColor',mode) vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) +# vobj.setEditorMode('Visibility',mode) def __getstate__(self): #mandatory return None @@ -98,16 +102,16 @@ class ViewProviderProject: def onChanged(self,vobj,prop): mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) +# vobj.setEditorMode('LineWidth',mode) +# vobj.setEditorMode('MarkerColor',mode) +# vobj.setEditorMode('NormalColor',mode) # vobj.setEditorMode('ShowFirstRapid',mode) vobj.setEditorMode('BoundingBox',mode) vobj.setEditorMode('DisplayMode',mode) vobj.setEditorMode('Selectable',mode) vobj.setEditorMode('ShapeColor',mode) vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) +# vobj.setEditorMode('Visibility',mode) class CommandProject: