Enhancing the power of rebar object – FreeCAD

Today, I added a Total Length property to the rebar object. Total length is the length of the individual rebar multiplied by the number of occurrences of the rebar. Below is a screenshot of rebar object properties. See the Length and Total Length property in property value table.

length_totallength


Yesterday, I also had a discussion with Sean regarding GCI tasks. He told about interoperability task (for eg. export FreeCAD model to BRL-CAD).

Adding Length property in the rebar object – FreeCAD

Today, I introduced a new property in the rebar object of FreeCAD i.e. Length. This property calculates the total length of the rebar. The user will see this property in the property value table. This property is very useful for Bar bending schedule.

Below is the code which calculates the length of rebar:

def getLengthOfRebar(rebar):
    """ getLengthOfRebar(RebarObject): Calculates the length of the rebar."""
    base = rebar.Base
    # When rebar is derived from DWire
    if hasattr(base, "Length"):
        return base.Length
    # When rebar is derived from Sketch
    elif base.isDerivedFrom("Sketcher::SketchObject"):
        length = 0
        for geo in base.Geometry:
            length += geo.length()
        return length
    else:
        FreeCAD.Console.PrintError("Cannot calculate rebar length from its base object\n")
        return None

Daily diary

Today, I didn’t worked so much but I solved one problem related the Arch module present in the FreeCAD on the Experimental server. Actually, when I imported Arch module in command line FreeCAD freecadcmd it gave a error “Exception while processing file: drawing.FCMacro [‘module’ object has no attribute ‘updateLocale’]”. It was the bug presented in the FreeCAD command line 0.14 version because in 0.14 version Arch module depended on GUI and in command line FreeCAD, GUI is not present. Then, I upgraded the command line FreeCAD to 0.16 version and after this my problem was solved.

Export drawing sheets of FreeCAD into PDF and SVG format from Python console – Done

Finally, I found the answer that how to save the drawing sheets in FreeCAD from Python console. In FreeCAD, whenever we created a new drawing sheet its get stored as temporary file in our system. The below code is used to find the location of the drawing from Python console:

import os
import subprocess

obj = App.ActiveDocument.getObject("Page")
page = getattr(obj, 'PageResult')

The page variable stored the location of the drawing sheet in SVG format.

Converting SVG format to PDF format by using Inkscape:

import os
import subprocess

obj = App.ActiveDocument.getObject("Page")

# Path to Inkscape executable
inkscape_path = "/usr/bin/inkscape"

# Exported PDF file location
file_location = os.path.expanduser("~" + os.sep + obj.Label + ".pdf")

page = getattr(obj, 'PageResult')
call_inkscape = [inkscape_path, "-f", obj.PageResult, "-A", file_location]
subprocess.call(call_inkscape)

Draw sectional view of object – Done

Today, I wrote the below code and by using this code, user can easily draw the sectional view of the object by simply write only two commands.

sec_obj = section_view_specs("Compound", 10, 10, 0, 0, 0, 1, 0, 100, 100, 2, 0)
draw_section_view(sec_obj, "Page")

In the below code I made a one constructor in class section_view_specs which will store all the information which will require to draw the sectional view of the object and function draw_section_view actually draw the sectional view of the given object by the information section_view_specs object.

class section_view_specs:
    def __init__(self, obj, x_dir, y_dir, z_dir, axis_x, axis_y, axis_z,
            angle2axis, x_pos, y_pos, scale, rotation):
        self.obj = obj
        self.x_dir = x_dir
        self.y_dir = y_dir
        self.z_dir = z_dir
        self.axis_x = axis_x
        self.axis_y = axis_y
        self.axis_z = axis_z
        self.angle2axis = angle2axis
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.scale = scale
        self.rotation = rotation

def draw_section_view(view, page_name):
    obj_ref = App.ActiveDocument.getObject(view.obj)
    view_ref = Arch.makeSectionPlane([obj_ref])
    view_ref.Placement = App.Placement(App.Vector(view.x_dir, view.y_dir,
        view.z_dir), App.Rotation(App.Vector(view.axis_x, view.axis_y,
            view.axis_z), view.angle2axis))
    Draft.makeShape2DView(view_ref)
    page_ref = App.ActiveDocument.getObject(page_name)
    draw_ref = Draft.makeDrawingView(view_ref, page_ref)
    draw_ref.X = view.x_pos
    draw_ref.Y = view.y_pos
    draw_ref.Scale = view.scale
    draw_ref.Rotation = view.rotation
    App.ActiveDocument.recompute()

Macro for making a drawing of the building in FreeCAD

Today, I make a macro which automates the drawing of the building on drawing sheet. Here is the code of macro.

obj_list = FreeCAD.ActiveDocument.Objects                                      
App.activeDocument().addObject("Part::Compound","Compound")             
App.activeDocument().Compound.Links = obj_list                                 
                                                                        
App.ActiveDocument.addObject('Drawing::FeaturePage','Page')             
App.ActiveDocument.Page.Template = App.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg'
                                                                        
App.ActiveDocument.addObject('Drawing::FeatureViewPart','View')         
App.ActiveDocument.View.Source = App.ActiveDocument.Compound            
App.ActiveDocument.View.Direction = (0.0,0.0,1.0)                       
App.ActiveDocument.View.X = 30.0                                        
App.ActiveDocument.View.Y = 100.0                                       
App.ActiveDocument.View.ShowHiddenLines = False                         
App.ActiveDocument.View.Scale = 2.0                                     
App.ActiveDocument.Page.addObject(App.ActiveDocument.View)                                                        
                                                                        
App.ActiveDocument.addObject('Drawing::FeatureViewPart','ViewIso')      
App.ActiveDocument.ViewIso.Source = App.ActiveDocument.Compound         
App.ActiveDocument.ViewIso.Direction = (1, 1, 1)                        
App.ActiveDocument.ViewIso.X = 335.0                                    
App.ActiveDocument.ViewIso.Y = 60.0                                     
App.ActiveDocument.ViewIso.ShowHiddenLines = True                       
App.ActiveDocument.ViewIso.Rotation = 120                               
App.ActiveDocument.ViewIso.Scale = 2.0                                  
App.ActiveDocument.Page.addObject(App.ActiveDocument.ViewIso)           
App.ActiveDocument.recompute()                                          

Output when you run the above macro:
Drawing of building

Source code:
https://github.com/amrit3701/Drawing-FreeCAD/blob/master/macro_building_drawing.py

Draw whole building on drawing paper – Done

The last two-three days I stuck to drew the drawing of whole building because at present FreeCAD have not the capability for recording everything in a macro because some code is written in C++ and in Python.
After struggling, today I discussed my problem with sir and he gave me many ideas that how I can overcome this problem.

I also chat on IRC of FreeCAD channel and discuss my problem with Yorik that how to draw the drawing of the whole building through Python console. I was using fuse function of FreeCAD in ‘Part’ workbench and he told me not to use fuse function. He told to use Part MakeCompound tool and which was solved my problem. He also told that compound is much, much faster and corrected than fusing.

In python use Part.makeCompound( [list of shapes] )

FreeCAD Drawing module

Today, I tried to elaborate that is FreeCAD capable of converting 3D drawing to 2D and at the end of the day I said that FreeCAD fully capable of converting 3D drawing to 2D drawing by using Drawing module.

The Drawing module allows you to put your 3D work on paper. That is, to put views of your models in a 2D window and to insert that window in a drawing, for example a sheet with a border, a title and your logo and finally print that sheet. The Drawing module is currently under construction and more or less a technology preview!

When I copy paste the code present on http://www.freecadweb.org/wiki/index.php?title=Drawing_Module it gave the below output.

The below is updated code:

# First of all you need the Part and the Drawing module
import FreeCAD, Part, Drawing

# Create a small sample part
Part.show(Part.makeBox(100,100,100).cut(Part.makeCylinder(80,100)).cut(Part.makeBox(90,40,100)).cut(Part.makeBox(20,85,100)))

# Direct projection. The G0 means hard edge, the G1 is tangent continuous.
Shape = App.ActiveDocument.Shape.Shape
[visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(Shape)
print "visible edges:", len(visibleG0.Edges)
print "hidden edges:", len(hiddenG0.Edges)

# Everything was projected on the Z-plane:
print "Bnd Box shape: X=",Shape.BoundBox.XLength," Y=",Shape.BoundBox.YLength," Z=",Shape.BoundBox.ZLength
print "Bnd Box project: X=",visibleG0.BoundBox.XLength," Y=",visibleG0.BoundBox.YLength," Z=",visibleG0.BoundBox.ZLength

# Different projection vector
[visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(Shape,App.Vector(1,1,1))

# Project to SVG
resultSVG = Drawing.projectToSVG(Shape,App.Vector(1,1,1))
print resultSVG

# Create the body
App.ActiveDocument.addObject("Part::Box","Box")
App.ActiveDocument.Box.Length=100.00
App.ActiveDocument.Box.Width=100.00
App.ActiveDocument.Box.Height=100.00
 
App.ActiveDocument.addObject("Part::Box","Box1")
App.ActiveDocument.Box1.Length=90.00
App.ActiveDocument.Box1.Width=40.00
App.ActiveDocument.Box1.Height=100.00
 
App.ActiveDocument.addObject("Part::Box","Box2")
App.ActiveDocument.Box2.Length=20.00
App.ActiveDocument.Box2.Width=85.00
App.ActiveDocument.Box2.Height=100.00
 
App.ActiveDocument.addObject("Part::Cylinder","Cylinder")
App.ActiveDocument.Cylinder.Radius=80.00
App.ActiveDocument.Cylinder.Height=100.00
App.ActiveDocument.Cylinder.Angle=360.00
# Fuse two boxes and the cylinder
App.ActiveDocument.addObject("Part::Fuse","Fusion")
App.ActiveDocument.Fusion.Base = App.ActiveDocument.Cylinder
App.ActiveDocument.Fusion.Tool = App.ActiveDocument.Box1
 
App.ActiveDocument.addObject("Part::Fuse","Fusion1")
App.ActiveDocument.Fusion1.Base = App.ActiveDocument.Box2
App.ActiveDocument.Fusion1.Tool = App.ActiveDocument.Fusion
# Cut the fused shapes from the first box
App.ActiveDocument.addObject("Part::Cut","Shape")
App.ActiveDocument.Shape.Base = App.ActiveDocument.Box 
App.ActiveDocument.Shape.Tool = App.ActiveDocument.Fusion1
# Hide all the intermediate shapes 
Gui.ActiveDocument.Box.Visibility=False
Gui.ActiveDocument.Box1.Visibility=False
Gui.ActiveDocument.Box2.Visibility=False
Gui.ActiveDocument.Cylinder.Visibility=False
Gui.ActiveDocument.Fusion.Visibility=False
Gui.ActiveDocument.Fusion1.Visibility=False

# Insert a Page object and assign a template
App.ActiveDocument.addObject('Drawing::FeaturePage','Page')
App.ActiveDocument.Page.Template = App.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg'

# Create a view on the "Shape" object, define the position and scale and assign it to a Page
App.ActiveDocument.addObject('Drawing::FeatureViewPart','View')
App.ActiveDocument.View.Source = App.ActiveDocument.Shape
App.ActiveDocument.View.Direction = (0.0,0.0,1.0)
App.ActiveDocument.View.X = 10.0
App.ActiveDocument.View.Y = 10.0
App.ActiveDocument.Page.addObject(App.ActiveDocument.View)


# Create a second view on the same object but this time the view will be rotated by 90 degrees.
App.ActiveDocument.addObject('Drawing::FeatureViewPart','ViewRot')
App.ActiveDocument.ViewRot.Source = App.ActiveDocument.Shape
App.ActiveDocument.ViewRot.Direction = (0.0,0.0,1.0)
App.ActiveDocument.ViewRot.X = 80.0
App.ActiveDocument.ViewRot.Y = 100.0
App.ActiveDocument.ViewRot.Scale = 1.0
App.ActiveDocument.ViewRot.Rotation = 90.0
App.ActiveDocument.Page.addObject(App.ActiveDocument.ViewRot)


# Create a third view on the same object but with an isometric view direction. The hidden lines are activated too.
App.ActiveDocument.addObject('Drawing::FeatureViewPart','ViewIso')
App.ActiveDocument.ViewIso.Source = App.ActiveDocument.Shape
App.ActiveDocument.ViewIso.Direction = (1.0,1.0,1.0)
App.ActiveDocument.ViewIso.X = 335.0
App.ActiveDocument.ViewIso.Y = 140.0
App.ActiveDocument.ViewIso.ShowHiddenLines = True
App.ActiveDocument.Page.addObject(App.ActiveDocument.ViewIso)


# Change something and update. The update process changes the view and the page.
App.ActiveDocument.View.X = 160.0
App.ActiveDocument.View.Y = 140.0
App.ActiveDocument.View.Scale = 1.0
App.ActiveDocument.recompute()

# Get the SVG fragment of a single view
ViewSVG = App.ActiveDocument.View.ViewResult
print ViewSVG

print "Resulting SVG document: ",App.ActiveDocument.Page.PageResult
file = open(App.ActiveDocument.Page.PageResult,"r")
print "Result page is ",len(file.readlines())," lines long"

del file

# Insert a view with your content
App.ActiveDocument.addObject('Drawing::FeatureView','ViewSelf')
App.ActiveDocument.ViewSelf.ViewResult = """
 
  
  """
App.ActiveDocument.Page.addObject(App.ActiveDocument.ViewSelf)
App.ActiveDocument.recompute()
 
del ViewSVG

By running the above code we have two outputs. First is 3D design of the object.

Second is the image which is converted by using Drawing module in FreeCAD.

However, I understand the code little bit and changed the code little bit because positions of object on the drawing was not very good and they overlap with eachother.

http://www.freecadweb.org/wiki/index.php?title=Drawing_Module

There are many templates of drawing sheet present in FreeCAD are
http://www.freecadweb.org/wiki/index.php?title=Drawing_templates