# -*- coding: utf-8 -*- #/****************************************************************************** # * Copyright (c) 2012 Jan Rheinländer * # * * # * 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 * # * * # ******************************************************************************/ import FreeCAD, FreeCADGui import Part, Sketcher class ShaftFeature: "Creates and updates the feature of the shaft" App = FreeCAD Gui = FreeCADGui def __init__(self, doc): "Create new feature" self.Doc = doc # TODO: Discover existing sketch and get data from it self.sketch = self.Doc.addObject("Sketcher::SketchObject","SketchShaft") self.sketch.Placement = self.App.Placement(self.App.Vector(0,0,0),self.App.Rotation(0,0,0,1)) self.feature = 0 self.segments = 0 # number of segments self.totalLength = 0 # total length of all segments self.lastRadius = 0 # radius of last segment (required for adding segments) def addSegment(self, length, diameter, innerdiameter): "Add a segment at the end of the shaft" # Find constraint indices of vertical line constraint, horizontal line constraint # FIXME: Should have a unique id instead of indices that might change with user editing # 0-3 belong to the centerline # 4-6 to the first vertical section # 7-9 to the first horizontal section # 10-12 to the second vertical section # etc. etc. constrRadius = 4 + self.segments * 6 constrLength = 7 + self.segments * 6 constrInnerRadius = 1 + self.segments * 6 # Find line index of vertical segment, horizontal segment, last shaft segment # FIXME: Should have a unique id instead of indices that might change with user editing segRadius = 1 + self.segments * 2 segLength = 2 + self.segments * 2 prevSegLength = 0 + self.segments * 2 prevSegEnd = 3 + (self.segments - 1) * 2 segEnd = prevSegEnd + 2 radius = diameter / 2 innerradius = innerdiameter / 2 oldLength = self.totalLength self.totalLength += length self.segments += 1 if oldLength == 0: # First segment of shaft # Create centerline self.sketch.addGeometry(Part.LineSegment(self.App.Vector(0,0,0), self.App.Vector(self.totalLength,0,0))) self.sketch.addConstraint(Sketcher.Constraint('DistanceX',0, self.totalLength)) # Constraint1 self.sketch.addConstraint(Sketcher.Constraint('DistanceY', -1,1,0,1,innerradius)) # Constraint2 self.sketch.addConstraint(Sketcher.Constraint('PointOnObject',0,1,-2)) # Constraint3 self.sketch.addConstraint(Sketcher.Constraint('Horizontal', 0)) # Constraint4 # Create first segment self.sketch.addGeometry(Part.LineSegment(self.App.Vector(0,innerradius,0), self.App.Vector(0,radius,0))) self.sketch.addConstraint(Sketcher.Constraint('DistanceY',-1,1,1,2,radius)) # Constraint5 self.sketch.addConstraint(Sketcher.Constraint('Coincident',0,1,1,1)) # Constraint6 self.sketch.addConstraint(Sketcher.Constraint('Vertical',1)) # Constraint7 self.sketch.addGeometry(Part.LineSegment(self.App.Vector(0,radius,0), self.App.Vector(length,radius,0))) self.sketch.addConstraint(Sketcher.Constraint('DistanceX',2,length)) # Constraint8 self.sketch.addConstraint(Sketcher.Constraint('Coincident',2,1,1,2)) # Constraint9 self.sketch.addConstraint(Sketcher.Constraint('Horizontal',2)) # Constraint10 else: # remove line that closes the shaft self.sketch.delGeometry(prevSegEnd) # TODO: Delete the two constraints? Or will they disappear automatically? # Adjust length of centerline self.sketch.setDatum(0,self.totalLength) # Add segment at the end self.sketch.addGeometry(Part.LineSegment(self.App.Vector(oldLength,self.lastRadius,0), self.App.Vector(oldLength,radius,0))) self.sketch.addConstraint(Sketcher.Constraint('DistanceY', -1,1, segRadius, 2, radius)) self.sketch.addConstraint(Sketcher.Constraint('Coincident',segRadius,1,prevSegLength,2)) self.sketch.addConstraint(Sketcher.Constraint('Vertical',segRadius)) self.sketch.addGeometry(Part.LineSegment(self.App.Vector(oldLength,radius,0), self.App.Vector(oldLength+length,radius,0))) self.sketch.addConstraint(Sketcher.Constraint('DistanceX',segLength,length)) self.sketch.addConstraint(Sketcher.Constraint('Coincident',segLength,1,segRadius,2)) self.sketch.addConstraint(Sketcher.Constraint('Horizontal',segLength)) # close the sketch self.sketch.addGeometry(Part.LineSegment(self.App.Vector(oldLength+length,radius,0), self.App.Vector(oldLength+length,innerradius,0))) self.sketch.addConstraint(Sketcher.Constraint('Coincident',0,2,segEnd,2)) self.sketch.addConstraint(Sketcher.Constraint('Coincident',segEnd,1,segLength,2)) self.lastRadius = radius if oldLength == 0: # create feature self.feature = self.Doc.addObject("PartDesign::Revolution","RevolutionShaft") self.feature.Profile = self.sketch self.feature.ReferenceAxis = (self.sketch,['H_Axis']) self.feature.Angle = 360.0 self.Doc.recompute() self.Gui.hide("SketchShaft") else: self.Doc.recompute() # FIXME: Will give a warning in the console if the active window is not the feature self.Gui.SendMsgToActiveView("ViewFit") def updateSegment(self, segment, oldLength, length, diameter, innerdiameter): constrRadius = 4 + segment * 6 constrLength = 7 + segment * 6 constrInnerRadius = 1 # Currently we don't allow multiple different innner diameters # update total length self.totalLength = self.totalLength - oldLength + length # Adjust length of centerline self.sketch.setDatum(0,self.totalLength) # Adjust segment length self.sketch.setDatum(constrLength, length) # Adjust diameter self.sketch.setDatum(constrRadius, diameter/2) # Adjust inner diameter self.sketch.setDatum(constrInnerRadius, innerdiameter/2) # Update feature self.Doc.recompute() self.Gui.SendMsgToActiveView("ViewFit")