Sandbox:TechDraw TemplateHelper

Still not finished :-)

Introduction
This document is about creating a drawing template and to insert into a FreeCAD file using a Python macro.

I managed to automate my drawing generation with a Python script which
 * generates a temporary svg template of the desired size (DIN A formats so far...)
 * inserts this temporary template into the active FreeCAD document
 * fills some values into the editable text fields

The development was somehow chaotic, because I'm still learning Python and some solution may seen to be a little odd - but it works at least...

Now I'd like to share what I have learned and coded so far and rewrite it in a tidier way.

I think it is better to show how to solve certain problems rather than just presenting a somehow finished macro.

Anyone is invited to borrow some code and develop similar or hopefully better tools that make handling drawings easier.

This sandbox is to start my documentation. At some further state it may be split into several pages for easier use.

Task list
To automatically generate a drawing page we need to know
 * how to insert a template into a FreeCAD document
 * how to set up a user interface to set some page parameters
 * how to generate a template
 * how to manipulate editable texts

Insert a page and template
Usually a template will be inserted into the active FreeCAD document which means a FreeCAD must be running and a file must be opened.

As this macro is launched from within a FreeCAD file the only variables that needs to be set are
 * templatePath, the path to the template folder and
 * templateName, the name of the template to be inserted.

(MyTemplate.svg is the name for the generated template in a following section. Change it to test the macro with your favourite template.)

(This has still to be done manually before running the macro as long as I'm not sure where to read the path variable ...)

An object to address the active document is introduced and named activeDoc.

And finally two variables are filled with the names of the generated page and template. (I prefer 2 digits for the numbers in contrast to FreeCAD)

Insert just one page and template
Code to add a page and insert a template


 * A page object and a template object are added to the active document's object list.
 * The content of the svg document is loaded into the template object.
 * The template object is put onto the page's objects list.
 * Drawings are on sheets rather than on pages and so they are renamed.
 * Since the property "Name" cannot be changed the property "Label" must be altered.
 * Finally the drawing view is opened and activated for editing.

Insert more than just one page and template
The above code works for single pages only. It needs some extra lines to detect existing pages and to increment the page number.

The macro tries to read the property label of Page01 to detect if page01 exists. If it doesn't it will be created.

If it exists the page number will be incremented and the next try to detect a page starts.

Code to check for existing pages to add a first page or yet another

I recommend to save the file after each added page.

Generate a template
A template provides a background for the drawing tasks. The template's dimensions are used by the printer drivers to scale the drawing correctly.

The templates are svg-files and so the macro has to write lines of svg code (which is a subset of xml code).

Generate a simple blank page template
This macro shows the principle how an svg-file can be put together. (Format is A3)

Code to create a simple svg-file


 * The result, a simple template for a blank page (A3 landscape):


 * The main principle is to open a file for writing and so start an svg-file from scratch, write the header line and close the file as a first step.
 * After that the file will be repeatedly opened to append further segments and closed again after appending.
 * (The FreeCAD namespace is an investment into the future when editable texts come into play)

Now some ink will be added to the blank page:

Add code segments to...
The following code segments are to be added to the above code. They should placed between the svg-tags.

They are usually split in a part to collect data for parameter values and one part to create the Python code lines with given parameters.

All functions dealing with formatWidth and formatHeight can create svg-code to match each DIN format from A4 to A0.

... create frames
Code segments (to create the svg-instructions) to draw two rectangles, one for a sheet frame and one around the drawing area.

Additional code to create frames


 * Each write instruction has to start with a specific number of blank spaces for the correct indentation of the resulting svg-file.
 * The toteBag class is used to collect and distribute global values. I'm not sure yet if this really makes sense...

... to add index fields
Code segments to calculate a few parameters based on sheet dimensions and then create code to place the separator lines, index letters and numbers and a few lines to help folding this drawing and placing a puncher. Additional functions to create several path and text instructions for the svg-file.

Additional code to create index fields


 * Comment.
 * More comments.

... create title block elements
Code segments (to create the svg-instructions) to draw
 * a title block outline
 * the inner segmentation
 * static texts like e.g.labels for the text boxes
 * editable texts, at least their placeholders

The first two points can be combined if only one line type and a single thickness is use.

All except the editable texts can be drawn in relation to the svg-file's origin as the base point of the title block and then be grouped to move them to the desired position in a single step.

Additional code to create a title block

Now there will be a supergroup "title block" containing the groups "titleblock-frame", "titleblock-text-non-editable", and"titleblock-revision-indexes" in the resulting svg-file.

The editable texts are put into a separate group as they require absolute coordinates

Additional code to create a editable texts

The resulting macro
All sections put together give a macro like this:
 * (Don't forget to edit the template path and start the macro from within FreeCAD.)

Complete code to create a template

The tote bag concept could be used to shorten function calls as the needed parameters could be distributed by global classes...

And this is the resulting Page:



Set up a user interface
A single format template generator is a bit lame and so a way to choose a format is needed.

As a user interface a pop-up window with a list to choose from would be nice, but let's start simple:

A simple user interface window
There are some changes in coming versions of Python or Qt and so some principles described in the FreeCAD wiki will not be supported anymore.

If FreeCAD has Python 3.4 or later pre-installed then deprecation warnings are shown in the console window to remind us that some code should be modified to still work in the future.

This is my try to code future-proof.

This opens a window on the screen - no more, no less

The action will take place within the initUI function in further steps. And the main part is a function itself to get a bit more object oriented...

A user interface window with buttons
Like the one above plus OK and cancel buttons and adjusted window dimensions.

This opens a window on the screen which can be closed with an OK or a cancel button.

Each button launches a function setting a result value and closing the window.
 * Two print instructions to check if it does what it should...

A user interface window with combo-box
Like the one above plus a label and a combo-box to select a sheet format.

This opens a window on the screen which can used to select a sheet format.

The combo-box is setting another result value without closing the window.
 * Two print instructions to check if it does what it should...

Manipulate editable texts
Whenever a new page is generated and inserted, default values are used for the editable texts.

To change the values we use the green handlers and change them one by one. That is acceptable for one page, but quickly becomes annoying if the file contains several pages (sheets) and it would be fine to change entries, that are identical on all pages, in one step.

What do we need beforehand:
 * a FreeCAD file containing one or more pages that are named/labeled in a compatible way
 * editable text objects for each page which must be named/labeled identical on all pages

Steps to achieve the goal:
 * scan the active document for drawing pages
 * read the values of the first page as default values
 * use a user interface to check and change the values
 * distribute the values to all pages

Look for existing Pages
Code to search and count pages in the active document

Read and write editable texts
Now that we can be sure that there are pages in the active document it is time to read and write some editable texts.

All entries for part number, title, and subtitle should be identical on all pages within a document. to achieve this the values are read from the first page and distributed to the following page. (In preparation for the next step the values are written to the first page as well)

The above code extended to read entries from the first pages and copy them to the following pages

Add a user interface
Between reading and writing there should be the opportunity to check and modify the values.

We create a gui window and use the first page's entries as default values. The entry fields offer some choices to select from (right mouse button) or the entries can be overwritten.

The above code extended to create a user interface and to handle input data

More results:

Generate A3 template and insert it
Just copy this code and paste it into an empty *.py file, edit the template path, save and start the macro from within FreeCAD:

Complete code to create an A3 template and insert it into the active document

Select format and generate a template then insert it
This combines the tasks to set up an input window to select the sheet format, to generate a template with the chosen dimensions, and to insert it into our active document.

Complete code to select the sheet format, generate a template with the chosen dimensions, and insert it into the active document (In this macro the sheet dimensions are no longer handed over to the functions as parameter but will be read from a global variable)

This is a sandbox / Dies ist eine Sandbox