Thursday, 6 August 2015

FreeCAD: Double Slider Mechanism Animation

Since few days ago, this blog is two years old, and, also, last month it crossed the 4000 views/month barrier.
I was thinking about a way of celebrating this events, and last night I saw a .gif image about a flat mechanism at which I could be staring the whole day:


I don't know its exact name, but "double slider mechanism" seems appropriate. It belongs to the family of flat, four bar linkage mechanisms, and, possibly, there is no real use for this one. But it moves very smoothly, with the outer end of the rotating arm drawing some kind of ellipse.



The kinematics of this one are not too difficult (none of the family of four bar linkage mechanism are), and for the animation I have solved it in an analytical way.

The code:


# Javier Martinez Garcia    August 2015   GPL V2.0

from PySide import QtCore
from math import sin, cos, radians

# retrieve the objects from the document
slider_x = FreeCAD.ActiveDocument.getObject("Pad003002")
slider_y = FreeCAD.ActiveDocument.getObject("Pad003001")
arm = FreeCAD.ActiveDocument.getObject("Pad002001")


# store initial placement (needed to restore initial position)
slider_x_placement = slider_x.Placement
slider_y_placement = slider_y.Placement
arm_placement = arm.Placement

# store object placements in a new variable
r_slider_x_pl = slider_x.Placement
r_slider_y_pl = slider_y.Placement
r_arm_pl = arm.Placement


def reset():
  # function to restore initial position of the objects
  slider_x.Placement = r_slider_x_pl
  slider_y.Placement = r_slider_y_pl
  arm.Placement = r_arm_pl


# In this mechanism, "i" represents the angle of the rod in degrees
i = 0

# update function calculates object position as f(i) and increases i
def update():
  global i
  alpha = radians( i )
  x = 150.0*cos( alpha )
  y = 150.0*sin( alpha )
  slider_x.Placement = FreeCAD.Placement( slider_x_placement.Base + FreeCAD.Vector( 150-x, 0, 0 ),
                                          slider_x_placement.Rotation )
  
  slider_y.Placement = FreeCAD.Placement( slider_y_placement.Base + FreeCAD.Vector( 0, y, 0 ),
                                          slider_y_placement.Rotation )
  
  arm.Placement = FreeCAD.Placement( arm_placement.Base + FreeCAD.Vector( 0, y, 0 ),
                                     FreeCAD.Rotation( FreeCAD.Vector( 0,0,1), i))
  # update the scene
  FreeCAD.Gui.updateGui()
  # increase mechanism input position
  i += 1


# create a timer object
timer = QtCore.QTimer()
# connect timer event to function "update"
timer.timeout.connect( update )
# start the timer to trigger "update" every 10 ms
timer.start( 10 )



Download the .fcstd model and animation script here, on github.


Have fun!

Saturday, 18 July 2015

FreeCAD: Drill macro

I am working on a project that has a lot of drill operations. Being an "assembly", it can get quite tedious to create an sketch or part cylinder, place it and then do a boolean cut to make the drill. To speed it up, I have written a short macro that drills existing holes into the selected shapes:

 

Selection:


 

Script:

"""
Drill Macro
JMG 2015 GPL

Select a set of circles and then the shapes that you want to drill
"""

#get user selection of edges
SelEdges = Gui.Selection.getSelectionEx()[0].SubObjects  

# get user selection for shapes
SelectedShapes = Gui.Selection.getSelectionEx() 

# create the faces that will be extruded to create the drill
cutFaces = []
for edge in SelEdges:
  cutFace = Part.Face(Part.Wire(edge)) # create face from edge
  cutFaces.append( cutFace ) 

# drill all selected shapes minus first one (selected edges)
for i in range(len(SelectedShapes)-1): 
  #retrieve object from selection list
  SelShape = SelectedShapes[i+1].Object 

  #create an empty part object in the document
  drilledShape=FreeCAD.ActiveDocument.addObject("Part::Feature",'Drilled'+SelShape.Name)
  drilledShape.Shape = SelShape.Shape
  #cut selected shape and assign shape to "drilledShape"
  for f in cutFaces:
    drilledShape.Shape=drilledShape.Shape.cut(f.extrude(f.normalAt(0,0)*1000000))
    drilledShape.Shape=drilledShape.Shape.cut(f.extrude(f.normalAt(0,0)*-1000000))
  
  #turn off visibility of the selected shape and set same color for the new object
  SelShape.ViewObject.Visibility = False
  drilledShape.ViewObject.ShapeColor = SelShape.ViewObject.ShapeColor

Output:



Also, if you want to drill something more complex, like a slot, a variation of the script can do it:

Selection:

Script:
"""
Drill Edges Macro
JMG 2015 GPL

Select a set of edges that form a closed wire and then the shapes
that you want to drill
"""

#get user selection of edges
SelEdges = Gui.Selection.getSelectionEx()[0].SubObjects  

# get user selection for shapes
SelectedShapes = Gui.Selection.getSelectionEx() 

# create the face that will be extruded to create the drill
cutFace = Part.Face(Part.Wire( SelEdges )) 

# drill all selected shapes minus first one (selected edges)
for i in range(len(SelectedShapes)-1): 
    #retrieve object from selection list
    SelShape = SelectedShapes[i+1].Object 
    
    #create an empty part object in the document
    drilledShape=FreeCAD.ActiveDocument.addObject("Part::Feature",'Drilled'+SelShape.Name)
    
    #cut selected shape and assign shape to "drilledShape"
    drilledShape.Shape=SelShape.Shape.cut(cutFace.extrude(cutFace.normalAt(0,0)*1000000))
    drilledShape.Shape=drilledShape.Shape.cut(cutFace.extrude(cutFace.normalAt(0,0)*-1000000))
    
    #turn off visibility of the selected shape and set same color for the new object
    SelShape.ViewObject.Visibility = False
    drilledShape.ViewObject.ShapeColor = SelShape.ViewObject.ShapeColor

Result:




I have them in a custom toolbar and they have helped me to do things faster.

Maybe it helps you too :)

Bye!

Monday, 13 July 2015

What's going on this summer?

Hello!

I write this brief post to explain, among other things, what is currently happening with the sheet metal workbench:

The workbench at the moment is at 30%: Document structure is almost done, simple unfold is working and there are tools, like this one, to create even more complex and powerful features.


Also, I talked about some crowdfounding campaign or paid development for this workbench: all it is stopped because I've found a powerful sponsor (to be revealed in a future).

 

Am I working at sheet metal?

No. I'm going to be studying from now until I finish my degree, somewhere around December. But this does not mean a complete shutoff, there are things and important works on the way.

For example, for  the "maker" community, I am developing a new machine that is being born by the end of this year (and is part of my degree project). An open source machine with stepper motors, completely designed with FreeCAD, that works using Arduino and Python and is not a 3D printer.




Also, I've been working in improvements at the "Exploded Assembly Animation workbench" and additions to the macro "WorkFeatures"


In conclusion, things are going to freeze a bit, but no project is going to disappear.


Have a nice summer!!


Javier.