From 34cb60f8cf27fd7fb80acd5434112823b813ff02 Mon Sep 17 00:00:00 2001 From: Jose Luis Cercos Pita Date: Thu, 22 Nov 2012 19:25:54 +0100 Subject: [PATCH 01/15] Added real time reporting and cancel capabilities --- src/Mod/Ship/tankGZ/TaskPanel.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Mod/Ship/tankGZ/TaskPanel.py b/src/Mod/Ship/tankGZ/TaskPanel.py index ce7943139..b2b1b7b92 100644 --- a/src/Mod/Ship/tankGZ/TaskPanel.py +++ b/src/Mod/Ship/tankGZ/TaskPanel.py @@ -39,10 +39,13 @@ class TaskPanel: self.ui = Paths.modulePath() + "/tankGZ/TaskPanel.ui" self.ship = None self.tanks = {} + self.running = False def accept(self): if not self.ship: return False + if self.running: + return # Get general data disp = self.computeDisplacement() draft = self.computeDraft(disp[0], self.form.trim.value()) @@ -57,16 +60,28 @@ class TaskPanel: msg = QtGui.QApplication.translate("ship_console","Computing GZ", None,QtGui.QApplication.UnicodeUTF8) App.Console.PrintMessage(msg + "...\n") + loop=QtCore.QEventLoop() + timer=QtCore.QTimer() + timer.setSingleShot(True) + QtCore.QObject.connect(timer,QtCore.SIGNAL("timeout()"),loop,QtCore.SLOT("quit()")) + self.running = True for i in range(0, nRoll): App.Console.PrintMessage("\t%d/%d\n" % (i+1,nRoll)) roll.append(i*dRoll) GZ.append(self.computeGZ(draft[0], trim, roll[-1])) + timer.start(0.0) + loop.exec_() + if(not self.running): + break PlotAux.Plot(roll, GZ, disp[0]/1000.0, draft[0], trim) return True def reject(self): if not self.ship: return False + if self.running: + self.running = False + return return True def clicked(self, index): From efc67461b890565a3ca4f7eeb49f6bc8db06e617 Mon Sep 17 00:00:00 2001 From: Jose Luis Cercos Pita Date: Thu, 22 Nov 2012 19:42:20 +0100 Subject: [PATCH 02/15] Moved hydrostatics computation from PlotAux to Task manager --- src/Mod/Ship/shipHydrostatics/PlotAux.py | 111 +-------------------- src/Mod/Ship/shipHydrostatics/TaskPanel.py | 108 +++++++++++++++++++- 2 files changed, 110 insertions(+), 109 deletions(-) diff --git a/src/Mod/Ship/shipHydrostatics/PlotAux.py b/src/Mod/Ship/shipHydrostatics/PlotAux.py index 316bed13e..32b2f3fe3 100644 --- a/src/Mod/Ship/shipHydrostatics/PlotAux.py +++ b/src/Mod/Ship/shipHydrostatics/PlotAux.py @@ -27,11 +27,8 @@ import math from PyQt4 import QtGui,QtCore # FreeCAD modules import FreeCAD,FreeCADGui -from FreeCAD import Base, Vector -import Part, Image, ImageGui # FreeCADShip modules from shipUtils import Paths -import Tools header = """ ################################################################# @@ -47,32 +44,14 @@ header = """ ################################################################# """ class Plot(object): - def __init__(self, ship, trim, drafts): + def __init__(self, ship, trim, drafts, points): """ Constructor. performs plot and show it (Using pyxplot). @param ship Selected ship instance @param trim Trim in degrees. @param drafts List of drafts to be performed. + @param points List of computed hydrostatics. """ - # Compute data - # Get external faces - faces = self.externalFaces(ship.Shape) - if len(faces) == 0: - msg = QtGui.QApplication.translate("ship_console", "Can't detect external faces from ship object", - None,QtGui.QApplication.UnicodeUTF8) - FreeCAD.Console.PrintError(msg + '\n') - return - else: - faces = Part.makeShell(faces) - # Print data - msg = QtGui.QApplication.translate("ship_console", "Computing hydrostatics", - None,QtGui.QApplication.UnicodeUTF8) - FreeCAD.Console.PrintMessage(msg + '...\n') - self.points = [] - for i in range(0,len(drafts)): - FreeCAD.Console.PrintMessage("\t%d / %d\n" % (i+1, len(drafts))) - draft = drafts[i] - point = Tools.Point(ship,faces,draft,trim) - self.points.append(point) + self.points = points[:] # Try to plot self.plotVolume() self.plotStability() @@ -392,87 +371,3 @@ class Plot(object): FreeCAD.Console.PrintMessage(msg + ':\n\t' + "\'"+ self.dataFile + "\'\n") return False - def lineFaceSection(self,line,surface): - """ Returns the point of section of a line with a face - @param line Line object, that can be a curve. - @param surface Surface object (must be a Part::Shape) - @return Section points array, [] if line don't cut surface - """ - # Get initial data - result = [] - vertexes = line.Vertexes - nVertex = len(vertexes) - # Perform the cut - section = line.cut(surface) - # Filter all old points - points = section.Vertexes - return points - - def externalFaces(self, shape): - """ Returns detected external faces. - @param shape Shape where external faces wanted. - @return List of external faces detected. - """ - result = [] - faces = shape.Faces - bbox = shape.BoundBox - L = bbox.XMax - bbox.XMin - B = bbox.YMax - bbox.YMin - T = bbox.ZMax - bbox.ZMin - dist = math.sqrt(L*L + B*B + T*T) - msg = QtGui.QApplication.translate("ship_console", "Computing external faces", - None,QtGui.QApplication.UnicodeUTF8) - FreeCAD.Console.PrintMessage(msg + '...\n') - # Valid/unvalid faces detection loop - for i in range(0,len(faces)): - FreeCAD.Console.PrintMessage("\t%d / %d\n" % (i+1, len(faces))) - f = faces[i] - # Create a line normal to surface at middle point - u = 0.0 - v = 0.0 - try: - surf = f.Surface - u = 0.5*(surf.getUKnots()[0]+surf.getUKnots()[-1]) - v = 0.5*(surf.getVKnots()[0]+surf.getVKnots()[-1]) - except: - cog = f.CenterOfMass - [u,v] = f.Surface.parameter(cog) - p0 = f.valueAt(u,v) - try: - n = f.normalAt(u,v).normalize() - except: - continue - p1 = p0 + n.multiply(1.5*dist) - line = Part.makeLine(p0, p1) - # Look for faces in front of this - nPoints = 0 - for j in range(0,len(faces)): - f2 = faces[j] - section = self.lineFaceSection(line, f2) - if len(section) <= 2: - continue - # Add points discarding start and end - nPoints = nPoints + len(section) - 2 - # In order to avoid special directions we can modify line - # normal a little bit. - angle = 5 - line.rotate(p0,Vector(1,0,0),angle) - line.rotate(p0,Vector(0,1,0),angle) - line.rotate(p0,Vector(0,0,1),angle) - nPoints2 = 0 - for j in range(0,len(faces)): - if i == j: - continue - f2 = faces[j] - section = self.lineFaceSection(line, f2) - if len(section) <= 2: - continue - # Add points discarding start and end - nPoints2 = nPoints + len(section) - 2 - # If the number of intersection points is pair, is a - # external face. So if we found an odd points intersection, - # face must be discarded. - if (nPoints % 2) or (nPoints2 % 2): - continue - result.append(f) - return result diff --git a/src/Mod/Ship/shipHydrostatics/TaskPanel.py b/src/Mod/Ship/shipHydrostatics/TaskPanel.py index bc5e2d967..dfd4588b2 100644 --- a/src/Mod/Ship/shipHydrostatics/TaskPanel.py +++ b/src/Mod/Ship/shipHydrostatics/TaskPanel.py @@ -25,6 +25,8 @@ import math # FreeCAD modules import FreeCAD as App import FreeCADGui as Gui +from FreeCAD import Base, Vector +import Part # Qt library from PyQt4 import QtGui,QtCore # Module @@ -48,7 +50,26 @@ class TaskPanel: for i in range(1,self.form.nDraft.value()): draft = draft + dDraft drafts.append(draft) - PlotAux.Plot(self.ship, self.form.trim.value(), drafts) + # Compute data + # Get external faces + faces = self.externalFaces(self.ship.Shape) + if len(faces) == 0: + msg = QtGui.QApplication.translate("ship_console", "Can't detect external faces from ship object", + None,QtGui.QApplication.UnicodeUTF8) + App.Console.PrintError(msg + '\n') + return False + faces = Part.makeShell(faces) + # Get hydrostatics + msg = QtGui.QApplication.translate("ship_console", "Computing hydrostatics", + None,QtGui.QApplication.UnicodeUTF8) + App.Console.PrintMessage(msg + '...\n') + points = [] + for i in range(0,len(drafts)): + App.Console.PrintMessage("\t%d / %d\n" % (i+1, len(drafts))) + draft = drafts[i] + point = Tools.Point(self.ship,faces,draft,self.form.trim.value()) + points.append(point) + PlotAux.Plot(self.ship, self.form.trim.value(), drafts, points) return True def reject(self): @@ -235,6 +256,91 @@ class TaskPanel: self.ship.addProperty("App::PropertyInteger","HydrostaticsNDraft","Ship", tooltip) self.ship.HydrostaticsNDraft = self.form.nDraft.value() + def lineFaceSection(self,line,surface): + """ Returns the point of section of a line with a face + @param line Line object, that can be a curve. + @param surface Surface object (must be a Part::Shape) + @return Section points array, [] if line don't cut surface + """ + # Get initial data + result = [] + vertexes = line.Vertexes + nVertex = len(vertexes) + # Perform the cut + section = line.cut(surface) + # Filter all old points + points = section.Vertexes + return points + + def externalFaces(self, shape): + """ Returns detected external faces. + @param shape Shape where external faces wanted. + @return List of external faces detected. + """ + result = [] + faces = shape.Faces + bbox = shape.BoundBox + L = bbox.XMax - bbox.XMin + B = bbox.YMax - bbox.YMin + T = bbox.ZMax - bbox.ZMin + dist = math.sqrt(L*L + B*B + T*T) + msg = QtGui.QApplication.translate("ship_console", "Computing external faces", + None,QtGui.QApplication.UnicodeUTF8) + App.Console.PrintMessage(msg + '...\n') + # Valid/unvalid faces detection loop + for i in range(0,len(faces)): + App.Console.PrintMessage("\t%d / %d\n" % (i+1, len(faces))) + f = faces[i] + # Create a line normal to surface at middle point + u = 0.0 + v = 0.0 + try: + surf = f.Surface + u = 0.5*(surf.getUKnots()[0]+surf.getUKnots()[-1]) + v = 0.5*(surf.getVKnots()[0]+surf.getVKnots()[-1]) + except: + cog = f.CenterOfMass + [u,v] = f.Surface.parameter(cog) + p0 = f.valueAt(u,v) + try: + n = f.normalAt(u,v).normalize() + except: + continue + p1 = p0 + n.multiply(1.5*dist) + line = Part.makeLine(p0, p1) + # Look for faces in front of this + nPoints = 0 + for j in range(0,len(faces)): + f2 = faces[j] + section = self.lineFaceSection(line, f2) + if len(section) <= 2: + continue + # Add points discarding start and end + nPoints = nPoints + len(section) - 2 + # In order to avoid special directions we can modify line + # normal a little bit. + angle = 5 + line.rotate(p0,Vector(1,0,0),angle) + line.rotate(p0,Vector(0,1,0),angle) + line.rotate(p0,Vector(0,0,1),angle) + nPoints2 = 0 + for j in range(0,len(faces)): + if i == j: + continue + f2 = faces[j] + section = self.lineFaceSection(line, f2) + if len(section) <= 2: + continue + # Add points discarding start and end + nPoints2 = nPoints + len(section) - 2 + # If the number of intersection points is pair, is a + # external face. So if we found an odd points intersection, + # face must be discarded. + if (nPoints % 2) or (nPoints2 % 2): + continue + result.append(f) + return result + def createTask(): panel = TaskPanel() Gui.Control.showDialog(panel) From 9d8747f1f045c3cd6c58764468fdebbe099920fe Mon Sep 17 00:00:00 2001 From: Jose Luis Cercos Pita Date: Thu, 22 Nov 2012 19:58:19 +0100 Subject: [PATCH 03/15] Moved to real time reporting and cancel new stuff --- src/Mod/Ship/shipHydrostatics/PlotAux.py | 10 ++++----- src/Mod/Ship/shipHydrostatics/TaskPanel.py | 25 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/Mod/Ship/shipHydrostatics/PlotAux.py b/src/Mod/Ship/shipHydrostatics/PlotAux.py index 32b2f3fe3..a71b50b23 100644 --- a/src/Mod/Ship/shipHydrostatics/PlotAux.py +++ b/src/Mod/Ship/shipHydrostatics/PlotAux.py @@ -44,11 +44,10 @@ header = """ ################################################################# """ class Plot(object): - def __init__(self, ship, trim, drafts, points): + def __init__(self, ship, trim, points): """ Constructor. performs plot and show it (Using pyxplot). @param ship Selected ship instance @param trim Trim in degrees. - @param drafts List of drafts to be performed. @param points List of computed hydrostatics. """ self.points = points[:] @@ -59,7 +58,7 @@ class Plot(object): # Save data if self.createDirectory(): return - if self.saveData(ship, trim, drafts): + if self.saveData(ship, trim): return def plotVolume(self): @@ -324,11 +323,10 @@ class Plot(object): FreeCAD.Console.PrintError(msg + ':\n\t' + "\'"+ self.path + "\'\n") return False - def saveData(self, ship, trim, drafts): + def saveData(self, ship, trim): """ Write data file. @param ship Selected ship instance @param trim Trim in degrees. - @param drafts List of drafts to be performed. @return True if error happens. """ # Open the file @@ -359,7 +357,7 @@ class Plot(object): Output.write(" #\n") Output.write(" #################################################################\n") # Print data - for i in range(0,len(drafts)): + for i in range(0,len(self.points)): point = self.points[i] string = "%f %f %f %f %f %f %f %f %f %f %f\n" % (point.disp, point.draft, point.wet, point.mom, point.xcb, point.farea, point.KBt, point.BMt, point.Cb, point.Cf, point.Cm) Output.write(string) diff --git a/src/Mod/Ship/shipHydrostatics/TaskPanel.py b/src/Mod/Ship/shipHydrostatics/TaskPanel.py index dfd4588b2..84f3feca1 100644 --- a/src/Mod/Ship/shipHydrostatics/TaskPanel.py +++ b/src/Mod/Ship/shipHydrostatics/TaskPanel.py @@ -39,10 +39,13 @@ class TaskPanel: def __init__(self): self.ui = Paths.modulePath() + "/shipHydrostatics/TaskPanel.ui" self.ship = None + self.running = False def accept(self): if not self.ship: return False + if self.running: + return self.save() draft = self.form.minDraft.value() drafts = [draft] @@ -52,7 +55,14 @@ class TaskPanel: drafts.append(draft) # Compute data # Get external faces + self.loop=QtCore.QEventLoop() + self.timer=QtCore.QTimer() + self.timer.setSingleShot(True) + QtCore.QObject.connect(self.timer,QtCore.SIGNAL("timeout()"),self.loop,QtCore.SLOT("quit()")) + self.running = True faces = self.externalFaces(self.ship.Shape) + if not self.running: + return False if len(faces) == 0: msg = QtGui.QApplication.translate("ship_console", "Can't detect external faces from ship object", None,QtGui.QApplication.UnicodeUTF8) @@ -69,10 +79,19 @@ class TaskPanel: draft = drafts[i] point = Tools.Point(self.ship,faces,draft,self.form.trim.value()) points.append(point) - PlotAux.Plot(self.ship, self.form.trim.value(), drafts, points) + self.timer.start(0.0) + self.loop.exec_() + if(not self.running): + break + PlotAux.Plot(self.ship, self.form.trim.value(), points) return True def reject(self): + if not self.ship: + return False + if self.running: + self.running = False + return return True def clicked(self, index): @@ -339,6 +358,10 @@ class TaskPanel: if (nPoints % 2) or (nPoints2 % 2): continue result.append(f) + self.timer.start(0.0) + self.loop.exec_() + if(not self.running): + break return result def createTask(): From 96f5e18b61b18b49d4b2999610653dc9e52e9c0b Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 23 Nov 2012 12:29:54 +0100 Subject: [PATCH 04/15] Add missing break statement in switch block --- src/Mod/Part/App/PropertyTopoShape.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Mod/Part/App/PropertyTopoShape.cpp b/src/Mod/Part/App/PropertyTopoShape.cpp index f3e83a809..718e7fee9 100644 --- a/src/Mod/Part/App/PropertyTopoShape.cpp +++ b/src/Mod/Part/App/PropertyTopoShape.cpp @@ -158,20 +158,28 @@ PyObject *PropertyPartShape::getPyObject(void) { case TopAbs_COMPOUND: prop = new TopoShapeCompoundPy(new TopoShape(sh)); + break; case TopAbs_COMPSOLID: prop = new TopoShapeCompSolidPy(new TopoShape(sh)); + break; case TopAbs_SOLID: prop = new TopoShapeSolidPy(new TopoShape(sh)); + break; case TopAbs_SHELL: prop = new TopoShapeShellPy(new TopoShape(sh)); + break; case TopAbs_FACE: prop = new TopoShapeFacePy(new TopoShape(sh)); + break; case TopAbs_WIRE: prop = new TopoShapeWirePy(new TopoShape(sh)); + break; case TopAbs_EDGE: prop = new TopoShapeEdgePy(new TopoShape(sh)); + break; case TopAbs_VERTEX: prop = new TopoShapeVertexPy(new TopoShape(sh)); + break; case TopAbs_SHAPE: default: prop = new TopoShapePy(new TopoShape(sh)); From 3347aa91e85443f78617b574b461ed841aa4f7be Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 23 Nov 2012 19:23:10 +0100 Subject: [PATCH 05/15] Fix view fit for perspective camera by setting height angle to 45 deg --- src/Gui/View3DInventorViewer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 47f3b9991..6e17e1d72 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -1378,6 +1378,11 @@ void View3DInventorViewer::viewAll() group->mode = SoSkipBoundingGroup::EXCLUDE_BBOX; } + // Set the height angle to 45 deg + SoCamera* cam = this->getCamera(); + if (cam && cam->getTypeId().isDerivedFrom(SoPerspectiveCamera::getClassTypeId())) + static_cast(cam)->heightAngle = (float)(M_PI / 4.0); + // call the default implementation first to make sure everything is visible SoQtViewer::viewAll(); From 7129840dc8dbe461ea1baf76880a721dce94e37e Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 23 Nov 2012 16:54:15 -0200 Subject: [PATCH 06/15] Draft: Fixed a bug in Shape2Dview --- src/Mod/Draft/Draft.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 57a53e72a..f70beccae 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -2799,7 +2799,10 @@ class _Shape2DView(_DraftObject): newedges = [] for e in oldedges: try: - newedges.append(e.Curve.toShape()) + if isinstance(e.Curve,Part.Line): + newedges.append(e.Curve.toShape()) + else: + newedges.append(e) except: print "Debug: error cleaning edge ",e return Part.makeCompound(newedges) From a2a7f414336bfd71125639876023d0e39305407f Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 23 Nov 2012 18:34:44 -0200 Subject: [PATCH 07/15] 0000887: Draft BSpline bug --- src/Mod/Draft/DraftTools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index f9e84fb00..547c257c9 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -642,11 +642,13 @@ class BSpline(Line): def finish(self,closed=False,cont=False): "terminates the operation and closes the poly if asked" + if self.ui: + self.bsplinetrack.finalize() if not Draft.getParam("UiMode"): FreeCADGui.Control.closeDialog() if (len(self.node) > 1): old = self.obj.Name - self.doc.removeObject(old) + todo.delay(self.doc.removeObject,old) try: # building command string rot,sup,pts,fil = self.getStrings() @@ -656,8 +658,6 @@ class BSpline(Line): 'Draft.makeBSpline(points,closed='+str(closed)+',face='+fil+',support='+sup+')']) except: print "Draft: error delaying commit" - if self.ui: - self.bsplinetrack.finalize() Creator.finish(self) if self.ui: if self.ui.continueMode: From 5522af1ef4c11ba5a05e3ae823c655acf9de0843 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 23 Nov 2012 18:36:43 -0200 Subject: [PATCH 08/15] Draft: Small fix to work without GUI --- src/Mod/Draft/Draft.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index f70beccae..d54523a85 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -3079,6 +3079,6 @@ class _ViewProviderClone(_ViewProviderDraftAlt): def getIcon(self): return ":/icons/Draft_Clone.svg" - -if not hasattr(FreeCADGui,"Snapper"): - import DraftSnap +if gui: + if not hasattr(FreeCADGui,"Snapper"): + import DraftSnap From d90e285f73f14437bd580608c225b8a396c006e2 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 23 Nov 2012 19:22:00 -0200 Subject: [PATCH 09/15] Draft: Optimization in Shape2DView --- src/Mod/Draft/Draft.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index d54523a85..c61ca642f 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -2781,8 +2781,11 @@ class _Shape2DView(_DraftObject): "The way the viewed object must be projected") obj.addProperty("App::PropertyIntegerList","FaceNumbers","Base", "The indices of the faces to be projected in Individual Faces mode") + obj.addProperty("App::PropertyBool","HiddenLines","Base", + "Show hidden lines") obj.Projection = Vector(0,0,1) obj.ProjectionMode = ["Solid","Individual Faces","Cutlines"] + obj.HiddenLines = False _DraftObject.__init__(self,obj,"Shape2DView") def execute(self,obj): @@ -2807,8 +2810,22 @@ class _Shape2DView(_DraftObject): print "Debug: error cleaning edge ",e return Part.makeCompound(newedges) + def getProjected(self,obj,shape,direction): + "returns projected edges from a shape and a direction" + import Part,Drawing + edges = [] + groups = Drawing.projectEx(shape,direction) + for g in groups[0:5]: + if g: + edges.append(g) + if hasattr(obj,"HiddenLines"): + if obj.HiddenLines: + for g in groups[5:]: + edges.append(g) + return self.clean(Part.makeCompound(edges)) + def createGeometry(self,obj): - import Drawing, DraftGeomUtils + import DraftGeomUtils pl = obj.Placement if obj.Base: if getType(obj.Base) == "SectionPlane": @@ -2831,9 +2848,7 @@ class _Shape2DView(_DraftObject): comp = Part.makeCompound(cuts) opl = FreeCAD.Placement(obj.Base.Placement) proj = opl.Rotation.multVec(FreeCAD.Vector(0,0,1)) - [visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(comp,proj) - if visibleG0: - obj.Shape = self.clean(visibleG0) + obj.Shape = self.getProjected(obj,comp,proj) elif obj.ProjectionMode == "Cutlines": for sh in shapes: if sh.Volume < 0: @@ -2849,9 +2864,7 @@ class _Shape2DView(_DraftObject): elif obj.Base.isDerivedFrom("Part::Feature"): if not DraftVecUtils.isNull(obj.Projection): if obj.ProjectionMode == "Solid": - [visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(obj.Base.Shape,obj.Projection) - if visibleG0: - obj.Shape = self.clean(visibleG0) + obj.Shape = self.getProjected(obj,obj.Base.Shape,obj.Projection) elif obj.ProjectionMode == "Individual Faces": import Part if obj.FaceNumbers: @@ -2861,9 +2874,7 @@ class _Shape2DView(_DraftObject): faces.append(obj.Base.Shape.Faces[i]) views = [] for f in faces: - [visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(f,obj.Projection) - if visibleG0: - views.append(visibleG0) + views.append(self.getProjected(obj,f,obj.Projection)) if views: obj.Shape = Part.makeCompound(views) if not DraftGeomUtils.isNull(pl): From 250d00dd7b68cc74c94ffd080a76edb719d59465 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 23 Nov 2012 20:44:01 -0200 Subject: [PATCH 10/15] Draft: small bugfix in shape2dview --- src/Mod/Draft/Draft.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index c61ca642f..6fbd2d2ba 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -2796,14 +2796,24 @@ class _Shape2DView(_DraftObject): self.createGeometry(obj) def clean(self,shape): - "returns a valid compound of edges" - import Part + "returns a valid compound of edges, by recreating them" + # this is because the projection algorithm somehow creates wrong shapes. + # they dispay fine, but on loading the file the shape is invalid + import Part,DraftGeomUtils oldedges = shape.Edges newedges = [] for e in oldedges: try: if isinstance(e.Curve,Part.Line): newedges.append(e.Curve.toShape()) + elif isinstance(e.Curve,Part.Circle): + if len(e.Vertexes) > 1: + mp = DraftGeomUtils.findMidpoint(e) + a = Part.Arc(e.Vertexes[0].Point,mp,e.Vertexes[-1].Point).toShape() + newedges.append(a) + else: + newedges.append(e.Curve.toShape()) + # TODO: treat ellipses and bsplines else: newedges.append(e) except: @@ -2822,6 +2832,7 @@ class _Shape2DView(_DraftObject): if obj.HiddenLines: for g in groups[5:]: edges.append(g) + #return Part.makeCompound(edges) return self.clean(Part.makeCompound(edges)) def createGeometry(self,obj): From 95c5dfad8a0d0feb37c4f1e401a007171e4ae08d Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 23 Nov 2012 22:35:54 -0200 Subject: [PATCH 11/15] Draft: better cleaning of shape2Dview --- src/Mod/Draft/Draft.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 6fbd2d2ba..9eb6d9bb3 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -2813,7 +2813,18 @@ class _Shape2DView(_DraftObject): newedges.append(a) else: newedges.append(e.Curve.toShape()) - # TODO: treat ellipses and bsplines + elif isinstance(e.Curve,Part.Ellipse): + if len(e.Vertexes) > 1: + a = Part.Arc(e.Curve,e.FirstParameter,e.LastParameter).toShape() + newedges.append(a) + else: + newedges.append(e.Curve.toShape()) + elif isinstance(e.Curve,Part.BSplineCurve): + if DraftGeomUtils.isLine(e.Curve): + l = Part.Line(e.Vertexes[0].Point,e.Vertexes[-1].Point).toShape() + newedges.append(l) + else: + newedges.append(e.Curve.toShape()) else: newedges.append(e) except: From 83af7bce0bde8e4e4d3e208705aebf8dc4b40156 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sat, 24 Nov 2012 14:21:42 -0200 Subject: [PATCH 12/15] Draft: Bugfix in parametric dimensions --- src/Mod/Draft/DraftTools.py | 13 +++++++------ src/Mod/Draft/DraftTrackers.py | 4 +++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 547c257c9..f3378ecaa 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -1381,6 +1381,7 @@ class Dimension(Creator): self.arcmode = False self.point2 = None self.force = None + self.info = None msg(translate("draft", "Pick first point:\n")) FreeCADGui.draftToolBar.show() @@ -1451,9 +1452,9 @@ class Dimension(Creator): self.finish() elif arg["Type"] == "SoLocation2Event": #mouse movement detection shift = hasMod(arg,MODCONSTRAIN) + self.point,ctrlPoint,self.info = getPoint(self,arg) if self.arcmode or self.point2: setMod(arg,MODCONSTRAIN,False) - self.point,ctrlPoint,info = getPoint(self,arg) if hasMod(arg,MODALT) and (len(self.node)<3): self.dimtrack.off() if not self.altdown: @@ -1534,11 +1535,11 @@ class Dimension(Creator): if (not self.node) and (not self.support): self.support = getSupport(arg) if hasMod(arg,MODALT) and (len(self.node)<3): - print "snapped: ",info - if info: - ob = self.doc.getObject(info['Object']) - if 'Edge' in info['Component']: - num = int(info['Component'].lstrip('Edge'))-1 + print "snapped: ",self.info + if self.info: + ob = self.doc.getObject(self.info['Object']) + if 'Edge' in self.info['Component']: + num = int(self.info['Component'].lstrip('Edge'))-1 ed = ob.Shape.Edges[num] v1 = ed.Vertexes[0].Point v2 = ed.Vertexes[-1].Point diff --git a/src/Mod/Draft/DraftTrackers.py b/src/Mod/Draft/DraftTrackers.py index be15757b6..fcf88c25f 100644 --- a/src/Mod/Draft/DraftTrackers.py +++ b/src/Mod/Draft/DraftTrackers.py @@ -235,7 +235,9 @@ class dimTracker(Tracker): self.p1 = self.p2 = self.p3 = None def update(self,pts): - if len(pts) == 1: + if not pts: + return + elif len(pts) == 1: self.p3 = pts[0] else: self.p1 = pts[0] From aee645ee9db8628f47340d486acd11fcac97d40f Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 24 Nov 2012 20:45:47 +0100 Subject: [PATCH 13/15] Make more consistent method names in TopoShape --- src/Mod/Part/App/TopoShape.cpp | 95 ++++++++++++++++++++++++++--- src/Mod/Part/App/TopoShape.h | 10 +-- src/Mod/Part/App/TopoShapePy.xml | 2 +- src/Mod/Part/App/TopoShapePyImp.cpp | 23 +++++-- 4 files changed, 110 insertions(+), 20 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 68c731fdc..47a42cb0a 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -1690,21 +1690,98 @@ TopoDS_Shape TopoShape::revolve(const gp_Ax1& axis, double d) const return mkRevol.Shape(); } -TopoDS_Shape TopoShape::makeThickSolid(const TopTools_ListOfShape& remFace, - Standard_Real offset, Standard_Real tolerance) const -{ - BRepOffsetAPI_MakeThickSolid mkThick(this->_Shape, remFace, offset, tolerance); - return mkThick.Shape(); -} +#include +#include -TopoDS_Shape TopoShape::makeOffset(double offset, double tol, bool intersection, - bool selfInter, short offsetMode, short join) +TopoDS_Shape TopoShape::makeOffsetShape(double offset, double tol, bool intersection, + bool selfInter, short offsetMode, short join, + bool fill) const { BRepOffsetAPI_MakeOffsetShape mkOffset(this->_Shape, offset, tol, BRepOffset_Mode(offsetMode), intersection ? Standard_True : Standard_False, selfInter ? Standard_True : Standard_False, GeomAbs_JoinType(join)); - return mkOffset.Shape(); + const TopoDS_Shape& res = mkOffset.Shape(); + if (!fill) + return res; +#if 0 + const BRepOffset_MakeOffset& off = mkOffset.MakeOffset(); + const BRepAlgo_Image& img = off.OffsetEdgesFromShapes(); + + // build up map edge->face + TopTools_IndexedDataMapOfShapeListOfShape edge2Face; + TopExp::MapShapesAndAncestors(this->_Shape, TopAbs_EDGE, TopAbs_FACE, edge2Face); + TopTools_IndexedMapOfShape mapOfShape; + TopExp::MapShapes(this->_Shape, TopAbs_EDGE, mapOfShape); + + TopoDS_Shell shell; + BRep_Builder builder; + TopExp_Explorer xp; + builder.MakeShell(shell); + + for (xp.Init(this->_Shape,TopAbs_FACE); xp.More(); xp.Next()) { + builder.Add(shell, xp.Current()); + } + + for (int i=1; i<= edge2Face.Extent(); ++i) { + const TopTools_ListOfShape& los = edge2Face.FindFromIndex(i); + if (los.Extent() == 1) { + // set the index value as user data to use it in accept() + const TopoDS_Shape& edge = edge2Face.FindKey(i); + Standard_Boolean ok = img.HasImage(edge); + if (ok) { + const TopTools_ListOfShape& edges = img.Image(edge); + TopTools_ListIteratorOfListOfShape it; + it.Initialize(edges); + TopoDS_Face face = BRepFill::Face(TopoDS::Edge(edge), TopoDS::Edge(it.Value())); + builder.Add(shell, face); + } + } + } + + for (xp.Init(mkOffset.Shape(),TopAbs_FACE); xp.More(); xp.Next()) { + builder.Add(shell, xp.Current()); + } + + //BRepBuilderAPI_Sewing sew(offset); + //sew.Load(this->_Shape); + //sew.Add(mkOffset.Shape()); + //sew.Perform(); + + //shell.Closed(Standard_True); + + return shell; +#else + TopoDS_Solid Res; + TopExp_Explorer exp; + BRep_Builder B; + B.MakeSolid(Res); + + BRepTools_Quilt Glue; + for (exp.Init(this->_Shape,TopAbs_FACE); exp.More(); exp.Next()) { + Glue.Add (exp.Current()); + } + for (exp.Init(mkOffset.Shape(),TopAbs_FACE);exp.More(); exp.Next()) { + Glue.Add (exp.Current().Reversed()); + } + TopoDS_Shape S = Glue.Shells(); + for (exp.Init(S,TopAbs_SHELL); exp.More(); exp.Next()) { + B.Add(Res,exp.Current()); + } + Res.Closed(Standard_True); + return Res; +#endif +} + +TopoDS_Shape TopoShape::makeThickSolid(const TopTools_ListOfShape& remFace, + double offset, double tol, bool intersection, + bool selfInter, short offsetMode, short join) const +{ + BRepOffsetAPI_MakeThickSolid mkThick(this->_Shape, remFace, offset, tol, BRepOffset_Mode(offsetMode), + intersection ? Standard_True : Standard_False, + selfInter ? Standard_True : Standard_False, + GeomAbs_JoinType(join)); + return mkThick.Shape(); } void TopoShape::transformGeometry(const Base::Matrix4D &rclMat) diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index 26e891a9c..0369682ff 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -158,8 +158,6 @@ public: const Standard_Boolean isFrenet = Standard_False) const; TopoDS_Shape makePrism(const gp_Vec&) const; TopoDS_Shape revolve(const gp_Ax1&, double d) const; - TopoDS_Shape makeThickSolid(const TopTools_ListOfShape& remFace, - Standard_Real offset, Standard_Real tolerance) const; TopoDS_Shape makeSweep(const TopoDS_Shape& profile, double, int) const; TopoDS_Shape makeTube(double radius, double tol, int cont, int maxdeg, int maxsegm) const; TopoDS_Shape makeHelix(Standard_Real pitch, Standard_Real height, @@ -168,9 +166,13 @@ public: Standard_Real height, Standard_Real radius) const; TopoDS_Shape makeLoft(const TopTools_ListOfShape& profiles, Standard_Boolean isSolid, Standard_Boolean isRuled) const; - TopoDS_Shape makeOffset(double offset, double tol, + TopoDS_Shape makeOffsetShape(double offset, double tol, bool intersection = false, bool selfInter = false, - short offsetMode = 0, short join = 0); + short offsetMode = 0, short join = 0, bool fill = false) const; + TopoDS_Shape makeThickSolid(const TopTools_ListOfShape& remFace, + double offset, double tol, + bool intersection = false, bool selfInter = false, + short offsetMode = 0, short join = 0) const; //@} /** @name Manipulation*/ diff --git a/src/Mod/Part/App/TopoShapePy.xml b/src/Mod/Part/App/TopoShapePy.xml index 222bfd204..bf4dffa9c 100644 --- a/src/Mod/Part/App/TopoShapePy.xml +++ b/src/Mod/Part/App/TopoShapePy.xml @@ -189,7 +189,7 @@ the underlying geometry. - makeThickness(List of shapes, Ofset (Float), Tolerance (Float)) -> Shape + makeThickness(List of shapes, Offset (Float), Tolerance (Float)) -> Shape A hollowed solid is built from an initial solid and a set of faces on this solid, which are to be removed. The remaining faces of the solid become the walls of the hollowed solid, their thickness defined at the time of construction. diff --git a/src/Mod/Part/App/TopoShapePyImp.cpp b/src/Mod/Part/App/TopoShapePyImp.cpp index 1dc8bfc3a..bc74344dd 100644 --- a/src/Mod/Part/App/TopoShapePyImp.cpp +++ b/src/Mod/Part/App/TopoShapePyImp.cpp @@ -1024,7 +1024,15 @@ PyObject* TopoShapePy::makeThickness(PyObject *args) { PyObject *obj; double offset, tolerance; - if (!PyArg_ParseTuple(args, "O!dd", &(PyList_Type), &obj, &offset, &tolerance)) + PyObject* inter = Py_False; + PyObject* self_inter = Py_False; + short offsetMode = 0, join = 0; + if (!PyArg_ParseTuple(args, "O!dd|O!O!hh", + &(PyList_Type), &obj, + &offset, &tolerance, + &(PyBool_Type), &inter, + &(PyBool_Type), &self_inter, + &offsetMode, &join)) return 0; try { @@ -1037,7 +1045,8 @@ PyObject* TopoShapePy::makeThickness(PyObject *args) } } - TopoDS_Shape shape = this->getTopoShapePtr()->makeThickSolid(facesToRemove, offset, tolerance); + TopoDS_Shape shape = this->getTopoShapePtr()->makeThickSolid(facesToRemove, offset, tolerance, + (inter == Py_True), (self_inter == Py_True), offsetMode, join); return new TopoShapeSolidPy(new TopoShape(shape)); } catch (Standard_Failure) { @@ -1052,17 +1061,19 @@ PyObject* TopoShapePy::makeOffsetShape(PyObject *args) double offset, tolerance; PyObject* inter = Py_False; PyObject* self_inter = Py_False; + PyObject* fill = Py_False; short offsetMode = 0, join = 0; - if (!PyArg_ParseTuple(args, "dd|O!O!hh", + if (!PyArg_ParseTuple(args, "dd|O!O!hhO!", &offset, &tolerance, &(PyBool_Type), &inter, &(PyBool_Type), &self_inter, - &offsetMode, &join)) + &offsetMode, &join, + &(PyBool_Type), &fill)) return 0; try { - TopoDS_Shape shape = this->getTopoShapePtr()->makeOffset(offset, tolerance, - (inter == Py_True), (self_inter == Py_True), offsetMode, join); + TopoDS_Shape shape = this->getTopoShapePtr()->makeOffsetShape(offset, tolerance, + (inter == Py_True), (self_inter == Py_True), offsetMode, join, (fill == Py_True)); return new TopoShapePy(new TopoShape(shape)); } catch (Standard_Failure) { From 96afbb275607f668660e667a679d4da79e2308dc Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 24 Nov 2012 21:24:58 +0100 Subject: [PATCH 14/15] Fill&sew shape and its offset --- src/Mod/Part/App/TopoShape.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 47a42cb0a..bd3746a26 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -1690,8 +1690,8 @@ TopoDS_Shape TopoShape::revolve(const gp_Ax1& axis, double d) const return mkRevol.Shape(); } -#include -#include +//#include +//#include TopoDS_Shape TopoShape::makeOffsetShape(double offset, double tol, bool intersection, bool selfInter, short offsetMode, short join, @@ -1704,7 +1704,9 @@ TopoDS_Shape TopoShape::makeOffsetShape(double offset, double tol, bool intersec const TopoDS_Shape& res = mkOffset.Shape(); if (!fill) return res; -#if 0 +#if 1 + //s=Part.makePlane(10,10) + //s.makeOffsetShape(1.0,0.01,False,False,0,0,True) const BRepOffset_MakeOffset& off = mkOffset.MakeOffset(); const BRepAlgo_Image& img = off.OffsetEdgesFromShapes(); @@ -1733,8 +1735,15 @@ TopoDS_Shape TopoShape::makeOffsetShape(double offset, double tol, bool intersec const TopTools_ListOfShape& edges = img.Image(edge); TopTools_ListIteratorOfListOfShape it; it.Initialize(edges); - TopoDS_Face face = BRepFill::Face(TopoDS::Edge(edge), TopoDS::Edge(it.Value())); - builder.Add(shell, face); + BRepOffsetAPI_ThruSections aGenerator (0,0); + aGenerator.AddWire(BRepBuilderAPI_MakeWire(TopoDS::Edge(edge)).Wire()); + aGenerator.AddWire(BRepBuilderAPI_MakeWire(TopoDS::Edge(it.Value())).Wire()); + aGenerator.Build(); + for (xp.Init(aGenerator.Shape(),TopAbs_FACE); xp.More(); xp.Next()) { + builder.Add(shell, xp.Current()); + } + //TopoDS_Face face = BRepFill::Face(TopoDS::Edge(edge), TopoDS::Edge(it.Value())); + //builder.Add(shell, face); } } } From 89e5215d3b7379354642f8b75838ade09325ced1 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 24 Nov 2012 22:46:16 +0100 Subject: [PATCH 15/15] Offset function --- src/Mod/Part/Gui/CMakeLists.txt | 5 ++ src/Mod/Part/Gui/Command.cpp | 30 +++++++ src/Mod/Part/Gui/TaskOffset.cpp | 133 ++++++++++++++++++++++++++++++++ src/Mod/Part/Gui/TaskOffset.h | 75 ++++++++++++++++++ src/Mod/Part/Gui/TaskOffset.ui | 115 +++++++++++++++++++++++++++ src/Mod/Part/Gui/Workbench.cpp | 2 +- 6 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 src/Mod/Part/Gui/TaskOffset.cpp create mode 100644 src/Mod/Part/Gui/TaskOffset.h create mode 100644 src/Mod/Part/Gui/TaskOffset.ui diff --git a/src/Mod/Part/Gui/CMakeLists.txt b/src/Mod/Part/Gui/CMakeLists.txt index f6a41f935..e138c13ec 100644 --- a/src/Mod/Part/Gui/CMakeLists.txt +++ b/src/Mod/Part/Gui/CMakeLists.txt @@ -41,6 +41,7 @@ set(PartGui_MOC_HDRS TaskFaceColors.h TaskShapeBuilder.h TaskLoft.h + TaskOffset.h TaskSweep.h TaskCheckGeometry.h ) @@ -67,6 +68,7 @@ set(PartGui_UIC_SRCS TaskFaceColors.ui TaskShapeBuilder.ui TaskLoft.ui + TaskOffset.ui TaskSweep.ui ) qt4_wrap_ui(PartGui_UIC_HDRS ${PartGui_UIC_SRCS}) @@ -158,6 +160,9 @@ SET(PartGui_SRCS TaskLoft.cpp TaskLoft.h TaskLoft.ui + TaskOffset.cpp + TaskOffset.h + TaskOffset.ui TaskSweep.cpp TaskSweep.h TaskSweep.ui diff --git a/src/Mod/Part/Gui/Command.cpp b/src/Mod/Part/Gui/Command.cpp index 51f84675c..d796c31c7 100644 --- a/src/Mod/Part/Gui/Command.cpp +++ b/src/Mod/Part/Gui/Command.cpp @@ -62,6 +62,7 @@ #include "TaskShapeBuilder.h" #include "TaskLoft.h" #include "TaskSweep.h" +#include "TaskOffset.h" #include "TaskCheckGeometry.h" @@ -990,6 +991,34 @@ bool CmdPartSweep::isActive(void) //-------------------------------------------------------------------------------------- +DEF_STD_CMD_A(CmdPartOffset); + +CmdPartOffset::CmdPartOffset() + : Command("Part_Offset") +{ + sAppModule = "Part"; + sGroup = QT_TR_NOOP("Part"); + sMenuText = QT_TR_NOOP("Offset..."); + sToolTipText = QT_TR_NOOP("Utility to offset"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Part_Offset"; +} + +void CmdPartOffset::activated(int iMsg) +{ + Gui::Control().showDialog(new PartGui::TaskOffset()); +} + +bool CmdPartOffset::isActive(void) +{ + Base::Type partid = Base::Type::fromName("Part::Feature"); + bool objectsSelected = Gui::Selection().countObjectsOfType(partid) == 1; + return (objectsSelected && !Gui::Control().activeDialog()); +} + +//-------------------------------------------------------------------------------------- + DEF_STD_CMD_A(CmdShapeInfo); CmdShapeInfo::CmdShapeInfo() @@ -1260,5 +1289,6 @@ void CreatePartCommands(void) rcCmdMgr.addCommand(new CmdPartBuilder()); rcCmdMgr.addCommand(new CmdPartLoft()); rcCmdMgr.addCommand(new CmdPartSweep()); + rcCmdMgr.addCommand(new CmdPartOffset()); rcCmdMgr.addCommand(new CmdCheckGeometry()); } diff --git a/src/Mod/Part/Gui/TaskOffset.cpp b/src/Mod/Part/Gui/TaskOffset.cpp new file mode 100644 index 000000000..5324e17ea --- /dev/null +++ b/src/Mod/Part/Gui/TaskOffset.cpp @@ -0,0 +1,133 @@ +/*************************************************************************** + * Copyright (c) 2012 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +#endif + +#include "ui_TaskOffset.h" +#include "TaskOffset.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +using namespace PartGui; + +class OffsetWidget::Private +{ +public: + Ui_TaskOffset ui; + std::string document; + Private() + { + } + ~Private() + { + } +}; + +/* TRANSLATOR PartGui::OffsetWidget */ + +OffsetWidget::OffsetWidget(QWidget* parent) + : d(new Private()) +{ + Gui::Application::Instance->runPythonCode("from FreeCAD import Base"); + Gui::Application::Instance->runPythonCode("import Part"); + + d->ui.setupUi(this); +} + +OffsetWidget::~OffsetWidget() +{ + delete d; +} + +bool OffsetWidget::accept() +{ + return true; +} + +bool OffsetWidget::reject() +{ + return true; +} + +void OffsetWidget::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + d->ui.retranslateUi(this); + } +} + + +/* TRANSLATOR PartGui::TaskOffset */ + +TaskOffset::TaskOffset() +{ + widget = new OffsetWidget(); + taskbox = new Gui::TaskView::TaskBox( + Gui::BitmapFactory().pixmap("Part_Offset"), + widget->windowTitle(), true, 0); + taskbox->groupLayout()->addWidget(widget); + Content.push_back(taskbox); +} + +TaskOffset::~TaskOffset() +{ +} + +void TaskOffset::open() +{ +} + +void TaskOffset::clicked(int) +{ +} + +bool TaskOffset::accept() +{ + return widget->accept(); +} + +bool TaskOffset::reject() +{ + return widget->reject(); +} + +#include "moc_TaskOffset.cpp" diff --git a/src/Mod/Part/Gui/TaskOffset.h b/src/Mod/Part/Gui/TaskOffset.h new file mode 100644 index 000000000..d1dc8d47b --- /dev/null +++ b/src/Mod/Part/Gui/TaskOffset.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (c) 2012 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef PARTGUI_TASKOFFSET_H +#define PARTGUI_TASKOFFSET_H + +#include +#include + +namespace PartGui { + +class OffsetWidget : public QWidget +{ + Q_OBJECT + +public: + OffsetWidget(QWidget* parent = 0); + ~OffsetWidget(); + + bool accept(); + bool reject(); + +private: + void changeEvent(QEvent *e); + +private: + class Private; + Private* d; +}; + +class TaskOffset : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskOffset(); + ~TaskOffset(); + +public: + void open(); + bool accept(); + bool reject(); + void clicked(int); + + QDialogButtonBox::StandardButtons getStandardButtons() const + { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } + +private: + OffsetWidget* widget; + Gui::TaskView::TaskBox* taskbox; +}; + +} //namespace PartGui + +#endif // PARTGUI_TASKOFFSET_H diff --git a/src/Mod/Part/Gui/TaskOffset.ui b/src/Mod/Part/Gui/TaskOffset.ui new file mode 100644 index 000000000..a2a0300c6 --- /dev/null +++ b/src/Mod/Part/Gui/TaskOffset.ui @@ -0,0 +1,115 @@ + + + PartGui::TaskOffset + + + + 0 + 0 + 256 + 217 + + + + Offset + + + + + + Offset + + + + + + + + + + Tolerance + + + + + + + + + + Mode + + + + + + + + Skin + + + + + Pipe + + + + + RectoVerso + + + + + + + + Join type + + + + + + + + Arc + + + + + Tangent + + + + + Intersection + + + + + + + + Intersection + + + + + + + Self-intersection + + + + + + + spinOffset + spinTolerance + comboBox + comboBox_2 + checkBox + checkBox_2 + + + + diff --git a/src/Mod/Part/Gui/Workbench.cpp b/src/Mod/Part/Gui/Workbench.cpp index ddd441b7d..079815731 100644 --- a/src/Mod/Part/Gui/Workbench.cpp +++ b/src/Mod/Part/Gui/Workbench.cpp @@ -72,7 +72,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Part_SimpleCopy" << "Part_RefineShape" << "Part_CheckGeometry" << "Separator" << "Part_Boolean" << "Part_CrossSections" << "Part_Extrude" << "Part_Revolve" << "Part_Mirror" << "Part_Fillet" << "Part_Chamfer" - << "Part_RuledSurface" << "Part_Loft" << "Part_Sweep"; + << "Part_RuledSurface" << "Part_Loft" << "Part_Sweep" << "Part_Offset"; return root; }