├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── MANIFEST.in
├── README.md
├── docs
├── commands.md
├── images
│ ├── 00-create-sketch.png
│ ├── 01-select-orientation.png
│ ├── 02-create-frame-skeleton.png
│ ├── 10-profiles-task-2.png
│ ├── 10-profiles-task.png
│ ├── 10-profiles.png
│ ├── 11-profiles-family.png
│ ├── 13-edge-selection.png
│ ├── 14-profiles-done.png
│ ├── 14-zoom-on-profiles.png
│ ├── 20-sketch-base-placement-2.png
│ ├── 20-sketch-base-placement.png
│ ├── 21-stacked-frames.png
│ ├── 22-hide-profiles.png
│ ├── 23-select-vertexes.png
│ ├── 24-create-parametric-line.png
│ ├── 25-parametric-line.png
│ ├── 26-cube-done.png
│ ├── 30-mapmode-sketch.png
│ ├── 31-mapmode.png
│ ├── 32-mapmode-dialog.png
│ ├── 33-mapmode.png
│ ├── 40-show-first-frame.png
│ ├── 41-bevels.png
│ ├── 42-batchs-bevels.png
│ ├── 50-base-config.png
│ ├── 51-add-offset.png
│ ├── 52-select-touching-profiles.png
│ ├── 53-create-miter-end.png
│ ├── 54-miter-end.png
│ ├── 60-startwith.png
│ ├── 61-bad-joint.png
│ ├── 62-endtrim-task.png
│ ├── 62-endtrim.png
│ ├── 63-select-trimmed-body-1.png
│ ├── 63-select-trimmed-body-2.png
│ ├── 64-select-cuttype-1.png
│ ├── 64-select-cuttype-2.png
│ ├── 64-select-trimming-boundaries-1.png
│ ├── 64-select-trimming-boundaries-2.png
│ ├── 70-part-container.png
│ ├── 71-part-container.png
│ ├── 72-fusion-done.png
│ ├── 72-fusion.png
│ ├── 80-body.png
│ ├── 81-basefeature.png
│ ├── 82-making-holes.png
│ └── 83-holes-made.png
└── tutorial.md
├── freecad
└── frameforge
│ ├── __init__.py
│ ├── _utils.py
│ ├── create_end_miter_tool.py
│ ├── create_profiles_tool.py
│ ├── create_trimmed_profiles_tool.py
│ ├── init_gui.py
│ ├── parametric_line.py
│ ├── profile.py
│ ├── resources
│ ├── icons
│ │ ├── box.svg
│ │ ├── corner-coped-type.svg
│ │ ├── corner-end-miter.svg
│ │ ├── corner-end-trim.svg
│ │ ├── corner-simple-type.svg
│ │ ├── corner.svg
│ │ ├── discretize.svg
│ │ ├── extendcurve.svg
│ │ ├── joincurve.svg
│ │ ├── line.svg
│ │ ├── list-add.svg
│ │ ├── list-remove.svg
│ │ ├── metalwb.svg
│ │ ├── overlap.svg
│ │ ├── parts_list.svg
│ │ ├── splitcurve.svg
│ │ ├── trim_extend.svg
│ │ └── warehouse_profiles.svg
│ ├── images
│ │ └── profiles
│ │ │ ├── Metal
│ │ │ ├── Equal_Leg_Angles.png
│ │ │ ├── Equal_Leg_Angles_Fillet.png
│ │ │ ├── Flat_Sections.png
│ │ │ ├── HEA.png
│ │ │ ├── HEA_Fillet.png
│ │ │ ├── HEB.png
│ │ │ ├── HEB_Fillet.png
│ │ │ ├── HEM.png
│ │ │ ├── HEM_Fillet.png
│ │ │ ├── IPE.png
│ │ │ ├── IPE_Fillet.png
│ │ │ ├── IPN.png
│ │ │ ├── IPN_Fillet.png
│ │ │ ├── Pipe.png
│ │ │ ├── Rectangular_Hollow.png
│ │ │ ├── Rectangular_Hollow_Fillet.png
│ │ │ ├── Round_Bar.png
│ │ │ ├── Square.png
│ │ │ ├── Square_Fillet.png
│ │ │ ├── Square_Hollow.png
│ │ │ ├── Square_Hollow_Fillet.png
│ │ │ ├── UPE.png
│ │ │ ├── UPE_Fillet.png
│ │ │ ├── UPN.png
│ │ │ ├── UPN_Fillet.png
│ │ │ ├── Unequal_Leg_Angles.png
│ │ │ └── Unequal_Leg_Angles_Fillet.png
│ │ │ └── Warehouse.png
│ ├── profiles
│ │ └── metal.json
│ └── ui
│ │ ├── create_profiles.ui
│ │ └── create_trimmed_profiles.ui
│ ├── translate_utils.py
│ ├── trimmed_profile.py
│ └── version.py
├── package.xml
├── prof_extractor.py
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | **.pyc
2 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(Namespace_SRCS
2 | freecad/frameforge/resources/icons/corner.svg
3 | freecad/frameforge/resources/icons/splitcurve.svg
4 | freecad/frameforge/resources/icons/warehouse_profiles.svg
5 | freecad/frameforge/resources/icons/trim_extend.svg
6 | freecad/frameforge/resources/icons/metalwb.svg
7 | freecad/frameforge/resources/icons/line.svg
8 | freecad/frameforge/resources/icons/corner-end-miter.svg
9 | freecad/frameforge/resources/icons/discretize.svg
10 | freecad/frameforge/resources/icons/joincurve.svg
11 | freecad/frameforge/resources/icons/overlap.svg
12 | freecad/frameforge/resources/icons/box.svg
13 | freecad/frameforge/resources/icons/parts_list.svg
14 | freecad/frameforge/resources/icons/corner-coped-type.svg
15 | freecad/frameforge/resources/icons/corner-simple-type.svg
16 | freecad/frameforge/resources/icons/corner-end-trim.svg
17 | freecad/frameforge/resources/icons/list-remove.svg
18 | freecad/frameforge/resources/icons/extendcurve.svg
19 | freecad/frameforge/resources/icons/list-add.svg
20 |
21 | freecad/frameforge/resources/images/profiles/Metal/HEB_Fillet.png
22 | freecad/frameforge/resources/images/profiles/Metal/Square_Hollow.png
23 | freecad/frameforge/resources/images/profiles/Metal/HEM_Fillet.png
24 | freecad/frameforge/resources/images/profiles/Metal/UPN_Fillet.png
25 | freecad/frameforge/resources/images/profiles/Metal/Round_Bar.png
26 | freecad/frameforge/resources/images/profiles/Metal/UPE.png
27 | freecad/frameforge/resources/images/profiles/Metal/HEA.png
28 | freecad/frameforge/resources/images/profiles/Metal/HEA_Fillet.png
29 | freecad/frameforge/resources/images/profiles/Metal/HEB.png
30 | freecad/frameforge/resources/images/profiles/Metal/IPN_Fillet.png
31 | freecad/frameforge/resources/images/profiles/Metal/IPN.png
32 | freecad/frameforge/resources/images/profiles/Metal/UPN.png
33 | freecad/frameforge/resources/images/profiles/Metal/Square_Fillet.png
34 | freecad/frameforge/resources/images/profiles/Metal/Unequal_Leg_Angles.png
35 | freecad/frameforge/resources/images/profiles/Metal/Flat_Sections.png
36 | freecad/frameforge/resources/images/profiles/Metal/IPE.png
37 | freecad/frameforge/resources/images/profiles/Metal/UPE_Fillet.png
38 | freecad/frameforge/resources/images/profiles/Metal/Unequal_Leg_Angles_Fillet.png
39 | freecad/frameforge/resources/images/profiles/Metal/Rectangular_Hollow_Fillet.png
40 | freecad/frameforge/resources/images/profiles/Metal/HEM.png
41 | freecad/frameforge/resources/images/profiles/Metal/Square_Hollow_Fillet.png
42 | freecad/frameforge/resources/images/profiles/Metal/Equal_Leg_Angles_Fillet.png
43 | freecad/frameforge/resources/images/profiles/Metal/Equal_Leg_Angles.png
44 | freecad/frameforge/resources/images/profiles/Metal/Rectangular_Hollow.png
45 | freecad/frameforge/resources/images/profiles/Metal/IPE_Fillet.png
46 | freecad/frameforge/resources/images/profiles/Metal/Pipe.png
47 | freecad/frameforge/resources/images/profiles/Metal/Square.png
48 | freecad/frameforge/resources/images/profiles/Warehouse.png
49 |
50 | freecad/frameforge/resources/ui/create_trimmed_profiles.ui
51 | freecad/frameforge/resources/ui/create_profiles.ui
52 |
53 | freecad/frameforge/resources/profiles/metal.json
54 |
55 | freecad/frameforge/version.py
56 | freecad/frameforge/translate_utils.py
57 | freecad/frameforge/create_trimmed_profiles_tool.py
58 | freecad/frameforge/profile.py
59 | freecad/frameforge/_utils.py
60 | freecad/frameforge/parametric_line.py
61 | freecad/frameforge/__init__.py
62 | freecad/frameforge/create_end_miter_tool.py
63 | freecad/frameforge/trimmed_profile.py
64 | freecad/frameforge/init_gui.py
65 | freecad/frameforge/create_profiles_tool.py
66 | )
67 |
68 | SOURCE_GROUP("" FILES ${Namespace_SRCS})
69 |
70 | ADD_CUSTOM_TARGET(SEARCHBAR ALL
71 | SOURCES ${Namespace_SRCS}
72 | )
73 |
74 | fc_copy_sources(SEARCHBAR "${CMAKE_BINARY_DIR}/Mod/FrameForge" ${Namespace_SRCS})
75 |
76 | INSTALL(
77 | FILES
78 | ${Namespace_SRCS}
79 | DESTINATION
80 | Mod/SearchBar
81 | )
82 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
167 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include freecad/frameforge/resources *
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FrameForge
2 |
3 | Frameforge is a FreeCAD workbench that aids in designing beams and frames, with cut, mitter joins and so on.
4 |
5 | ## Prerequisite
6 |
7 | - FreeCAD ≥ v0.21.x
8 |
9 | ## Installation
10 |
11 | Frameforge workbench can be installed via the [Addon Manager](https://wiki.freecad.org/Std_AddonMgr)
12 |
13 | ## Quick Start
14 |
15 | ### Create the skeleton
16 |
17 | Beams are mapped onto Edges or ParametricLine (from a Sketch for instance)
18 |
19 | For a start, we are going to create a simple frame.
20 |
21 | 1. In a new file, switch to the Frameforge workbench.
22 | 2. Create a [sketch](https://wiki.freecad.org/Sketcher_NewSketch)
23 | 3. A dialog will open asking you to 'Select orientation'. Choose the XY for instance.
24 | 3. Draw a simple square in the sketch... this will be our skeleton
25 |
26 | 
27 |
28 | 5. Close the Sketch edit mode.
29 |
30 | ### Create the frame
31 |
32 | 1. Launch the FrameForge Profile tool
33 |
34 | 
35 |
36 | 2. It opens a FrameForge dialog (with options)
37 |
38 | 
39 | 
40 |
41 | 3. Select a profile from the lists (Material / Family / Size).
42 | *Note*: Size can be adjusted just below the family, the tool has a lot of predefined profiles. Same for parameters.
43 |
44 | 
45 |
46 | 4. In the 3D View, select edges to apply the profile creation:
47 |
48 | 
49 |
50 | 5. Press OK in the Create Profile Task.
51 | **Result**: now there are four profiles!
52 |
53 | 
54 |
55 | 
56 |
57 | **Voila!** You have your first frame! For more information, follow the [tutorial](docs/tutorial.md)
58 |
59 | ## Maintainer
60 |
61 | Vivien HENRY
62 | vivien.henry@inductivebrain.fr
63 |
64 |
65 | ## Credits
66 |
67 | This workbench is based on [MetalWB](https://framagit.org/Veloma/freecad_metal_workbench)
68 |
69 | Special thanks to:
70 |
71 | - Vincent B
72 | - Quentin Plisson
73 | - rockn
74 | - Jonathan Wiedemann
75 |
76 | And others people that I don't know but they should be in this [thread](https://forum.freecad.org/viewtopic.php?style=5&t=72389)
77 |
78 |
79 | ## Changelog
80 |
81 | * v0.1.3
82 | - Fix #10, Non attached profile (move profile inside the sketch 's parent)
83 | - Fix #27, Link to object go out of the allowed scope
84 | - Implement #23 Allow profile creation with selection of a whole sketch
85 | - Allows to create a Part to group all the Profile
86 | - Profile Naming Option
87 |
88 | * v0.1.2
89 | - Fix recursive import
90 | * v0.1.1
91 | - remove f-string with quote and double quote
92 | * v0.1.0
93 | - Porting code from MetalWB
94 | - Improving UI
95 | - Split Corners into EndTrim and EndMiter
96 |
97 |
98 | ## LICENSE
99 |
100 | FrameForge is licensed under the [GPLv3](LICENSE)
101 |
--------------------------------------------------------------------------------
/docs/commands.md:
--------------------------------------------------------------------------------
1 | # Code Snippets
2 | There is no way to add a button, menu entry from python to a workbench which is added with c++. So here is a comparison how to do that with python and with c++.
3 |
4 | ## Adding a command:
5 | This can be done either with python or c++.
6 |
7 | ### 1. python
8 |
9 | ```python
10 | import FreeCAD as App
11 |
12 | class MyCommand(object):
13 | def IsActive(self):
14 | """
15 | availability of the command (eg.: check for existence of a document,...)
16 | if this function returns False, the menu/ buttons are ßdisabled (gray)
17 | """
18 | if App.ActiveDocument is None:
19 | return False
20 | else:
21 | return True
22 |
23 | def GetResources(self):
24 | """
25 | resources which are used by buttons and menu-items
26 | """
27 | return {'Pixmap': 'path_to_icon.svg', 'MenuText': 'my command', 'ToolTip': 'very short description'}
28 |
29 | def Activated(self):
30 | """
31 | the function to be handled, when a user starts the command
32 | """
33 | ```
34 | To register the command in FreeCAD:
35 |
36 | ```python
37 | import FreeCADGui as Gui
38 | Gui.addCommand('MyCommand', MyCommand())
39 | ```
40 |
41 | Adding a new toolbar/menu:
42 | ```python
43 | from FreeCADGui import Workbench
44 | class myWorkbench(Workbench):
45 | MenuText = "name_of_workbench"
46 | ToolTip = "short description of workbench"
47 | Icon = "path_to_icon.svg"
48 |
49 | def GetClassName(self):
50 | return "Gui::PythonWorkbench"
51 |
52 | def Initialize(self):
53 | self.appendToolbar("Gear", ["MyCommand"])
54 | self.appendMenu("Gear", ["MyCommand"])
55 | ```
56 |
57 | ### 2. C++
58 |
59 | ```c++
60 |
61 | #include
62 | #include
63 | #include
64 | #include
65 |
66 | using namespace std;
67 |
68 | DEF_STD_CMD_A(MyCommand)
69 |
70 | MyCommand::MyCommand()
71 | : Command("MyCommand")
72 | {
73 | sAppModule = "module";
74 | sGroup = QT_TR_NOOP("Mesh");
75 | sMenuText = QT_TR_NOOP("my command");
76 | sToolTipText = QT_TR_NOOP("very short description");
77 | sWhatsThis = "MyCommand";
78 | sStatusTip = sToolTipText;
79 | }
80 |
81 | void MyCommand::activated(int)
82 | {
83 | // the function to be handled, when a user starts the command
84 | }
85 |
86 | bool MyCommand::isActive(void)
87 | {
88 | // availability of the command (eg.: check for existence of a document,...)
89 | // if this function returns False, the menu/ buttons are ßdisabled (gray)
90 | return (hasActiveDocument() && !Gui::Control().activeDialog());
91 | }
92 | ```
93 | To register the command in FreeCAD:
94 |
95 | ```c++
96 | #include
97 |
98 | Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
99 | rcCmdMgr.addCommand(new MyCommand());
100 | ```
101 | Adding a item to a menu/toolbar:
102 |
103 | if your command is added with python you have to run this code:
104 | in src/module/Gui/AppModuleGui.cpp add to PyMOD_INIT_FUNC:
105 |
106 | ```c++
107 | // try to instantiate a python module
108 | try{
109 | Base::Interpreter().runStringObject("import MyCommands");
110 | } catch (Base::PyException &err){
111 | err.ReportException();
112 | }
113 | ```
114 |
115 | and add the name of the command to a tooltip/menu in src/module/Gui/Workbench.cpp Workbench::setupToolBars
116 |
117 |
118 | ```c++
119 | Gui::ToolBarItem* Workbench::setupToolBars() const
120 | {
121 | Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
122 | Gui::ToolBarItem* myToolbar = new Gui::ToolBarItem(root);
123 | myToolbar->setCommand("my_commands");
124 | *myToolbar << "MyCommand";
125 | return root;
126 | }
127 | ```
128 |
--------------------------------------------------------------------------------
/docs/images/00-create-sketch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/00-create-sketch.png
--------------------------------------------------------------------------------
/docs/images/01-select-orientation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/01-select-orientation.png
--------------------------------------------------------------------------------
/docs/images/02-create-frame-skeleton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/02-create-frame-skeleton.png
--------------------------------------------------------------------------------
/docs/images/10-profiles-task-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/10-profiles-task-2.png
--------------------------------------------------------------------------------
/docs/images/10-profiles-task.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/10-profiles-task.png
--------------------------------------------------------------------------------
/docs/images/10-profiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/10-profiles.png
--------------------------------------------------------------------------------
/docs/images/11-profiles-family.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/11-profiles-family.png
--------------------------------------------------------------------------------
/docs/images/13-edge-selection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/13-edge-selection.png
--------------------------------------------------------------------------------
/docs/images/14-profiles-done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/14-profiles-done.png
--------------------------------------------------------------------------------
/docs/images/14-zoom-on-profiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/14-zoom-on-profiles.png
--------------------------------------------------------------------------------
/docs/images/20-sketch-base-placement-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/20-sketch-base-placement-2.png
--------------------------------------------------------------------------------
/docs/images/20-sketch-base-placement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/20-sketch-base-placement.png
--------------------------------------------------------------------------------
/docs/images/21-stacked-frames.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/21-stacked-frames.png
--------------------------------------------------------------------------------
/docs/images/22-hide-profiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/22-hide-profiles.png
--------------------------------------------------------------------------------
/docs/images/23-select-vertexes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/23-select-vertexes.png
--------------------------------------------------------------------------------
/docs/images/24-create-parametric-line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/24-create-parametric-line.png
--------------------------------------------------------------------------------
/docs/images/25-parametric-line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/25-parametric-line.png
--------------------------------------------------------------------------------
/docs/images/26-cube-done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/26-cube-done.png
--------------------------------------------------------------------------------
/docs/images/30-mapmode-sketch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/30-mapmode-sketch.png
--------------------------------------------------------------------------------
/docs/images/31-mapmode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/31-mapmode.png
--------------------------------------------------------------------------------
/docs/images/32-mapmode-dialog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/32-mapmode-dialog.png
--------------------------------------------------------------------------------
/docs/images/33-mapmode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/33-mapmode.png
--------------------------------------------------------------------------------
/docs/images/40-show-first-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/40-show-first-frame.png
--------------------------------------------------------------------------------
/docs/images/41-bevels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/41-bevels.png
--------------------------------------------------------------------------------
/docs/images/42-batchs-bevels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/42-batchs-bevels.png
--------------------------------------------------------------------------------
/docs/images/50-base-config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/50-base-config.png
--------------------------------------------------------------------------------
/docs/images/51-add-offset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/51-add-offset.png
--------------------------------------------------------------------------------
/docs/images/52-select-touching-profiles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/52-select-touching-profiles.png
--------------------------------------------------------------------------------
/docs/images/53-create-miter-end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/53-create-miter-end.png
--------------------------------------------------------------------------------
/docs/images/54-miter-end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/54-miter-end.png
--------------------------------------------------------------------------------
/docs/images/60-startwith.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/60-startwith.png
--------------------------------------------------------------------------------
/docs/images/61-bad-joint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/61-bad-joint.png
--------------------------------------------------------------------------------
/docs/images/62-endtrim-task.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/62-endtrim-task.png
--------------------------------------------------------------------------------
/docs/images/62-endtrim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/62-endtrim.png
--------------------------------------------------------------------------------
/docs/images/63-select-trimmed-body-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/63-select-trimmed-body-1.png
--------------------------------------------------------------------------------
/docs/images/63-select-trimmed-body-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/63-select-trimmed-body-2.png
--------------------------------------------------------------------------------
/docs/images/64-select-cuttype-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/64-select-cuttype-1.png
--------------------------------------------------------------------------------
/docs/images/64-select-cuttype-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/64-select-cuttype-2.png
--------------------------------------------------------------------------------
/docs/images/64-select-trimming-boundaries-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/64-select-trimming-boundaries-1.png
--------------------------------------------------------------------------------
/docs/images/64-select-trimming-boundaries-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/64-select-trimming-boundaries-2.png
--------------------------------------------------------------------------------
/docs/images/70-part-container.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/70-part-container.png
--------------------------------------------------------------------------------
/docs/images/71-part-container.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/71-part-container.png
--------------------------------------------------------------------------------
/docs/images/72-fusion-done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/72-fusion-done.png
--------------------------------------------------------------------------------
/docs/images/72-fusion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/72-fusion.png
--------------------------------------------------------------------------------
/docs/images/80-body.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/80-body.png
--------------------------------------------------------------------------------
/docs/images/81-basefeature.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/81-basefeature.png
--------------------------------------------------------------------------------
/docs/images/82-making-holes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/82-making-holes.png
--------------------------------------------------------------------------------
/docs/images/83-holes-made.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukh/frameforge/c85108171a1b728e61d780cced3423aff41c6fa5/docs/images/83-holes-made.png
--------------------------------------------------------------------------------
/docs/tutorial.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # FrameForge Tutorial
4 |
5 | FrameForge is dedicated for creating Frames and Beams, and apply operations (miter cuts, trim cuts) on these profiles.
6 |
7 | ## Create the skeleton
8 |
9 | Beams are mapped onto Edges or ParametricLine (from a Sketch for instance)
10 |
11 | For a start, we are going to create a simple frame.
12 |
13 | 1. In a new file, switch to the Frameforge workbench.
14 |
15 | 2. Create a sketch, and select orientation (XY for instance)
16 |
17 | 
18 |
19 | 
20 |
21 |
22 | 3. Draw a simple square in the sketch... it will be our skeleton
23 |
24 | 
25 |
26 | 4. Close the Sketch edit mode.
27 |
28 | ## Create the frame
29 |
30 | 1. Launch the Profile tool.
31 |
32 | 
33 |
34 | 
35 | 
36 |
37 | 1. Select a profile from the lists (Material / Family / Size)
38 |
39 | 
40 |
41 |
42 | You can change the size just below the family, the tool has a lot of predefined profile, you can also change the parameters...
43 |
44 |
45 | 3. In the 3D View, select edges to apply the profile creation:
46 |
47 | 
48 |
49 | 1. And press OK in the Create Profile Task. Now, you have four profiles !
50 |
51 | 
52 |
53 | 
54 |
55 |
56 |
57 | **And voila ! You have your first frame !**
58 |
59 |
60 | ## Going 3D... Making a cube !
61 |
62 | We can build more complexe shapes, and there are severals ways of doing it.
63 |
64 | ### More Sketches !
65 |
66 | We can add more sketches into our project:
67 |
68 | 1. Create a new Sketch
69 | 2. Select the same orientation as the previous one (XY)
70 | 3. Draw a square the same size and placement as the previous one.
71 |
72 |
73 | 4. Now, change the position of the sketch:
74 |
75 | 
76 |
77 | 
78 |
79 | And the new sketch is 400mm on top of the first one !
80 |
81 | You can therefore use Create Profile Command again to create another square frame !
82 |
83 | 
84 |
85 | ### Parametric Line
86 |
87 | You can create parametrics lines for joining two vertices (points), these lines can be used with Warehouse Profile as well...
88 |
89 | 1. one can hide profiles objects with [Space Bar] (it allows to see the sketches)
90 |
91 | 
92 |
93 | 2. Selects vertices
94 |
95 | 
96 |
97 |
98 | 3. Create Parametric Line
99 |
100 | 
101 |
102 | 
103 |
104 |
105 | You can therefore use Create profile again to create the four vertical beams !
106 |
107 | 1. Open Create Profile, select the profile you want
108 | 2. Select the Parametric lines, click OK.
109 |
110 | 
111 |
112 |
113 |
114 | ### More Sketches / Part2 !
115 |
116 | There is another ways to add sketches, that allows to do more complicated stuff...
117 |
118 | Sometime you want add a sketch to a specific place, and link it to another sketch. (If you modify the first Sketch, then the second will follow, hopefully)
119 |
120 | This is not possible with the Position / Base Placement, that is an absolute position.
121 |
122 | We are going to "Map" the sketch to something else.
123 |
124 | 1. Create a new Sketch, and set orientation to: YZ
125 |
126 | I added a circle to the sketch so you can see where it is.. (just for reference !)
127 |
128 | 
129 |
130 | 2. Click on the map mode property:
131 |
132 | 
133 |
134 | 
135 |
136 |
137 | You can change the map mode, selecting faces, vertices and edges...
138 |
139 | 
140 |
141 | Here, our circle is in a new plan, the one at the top left of the screen...
142 |
143 | There are a lot of options here.
144 |
145 | You can then edit the sketch, and create more line and frames...
146 |
147 | ## Bevels and corners.
148 |
149 | As you can see, the junctions are not that good (yet !). The profiles are centered on the skeleton, and stops right at the end of the edges.
150 |
151 | We are going to make corners, and bevels. There are two methods for that.
152 |
153 |
154 | ### Via Bevels property
155 |
156 | It is my favorite for simple frame..
157 |
158 | Let's hide everything except the first frame we made...
159 |
160 | 
161 |
162 | 1. Select one of the profile, and in the property section, go for Bevel Start/End Cut 1/2
163 |
164 | 
165 |
166 | There are 4 entries (Start / End Cut1 Cut2)
167 |
168 | That allows you to create bevels in the two axis, at the start or end of the profile.
169 |
170 | Negative angles works, and must be used to compensate directions.
171 |
172 | You can batch-modify that, by selecting all the profiles....
173 |
174 | 
175 |
176 | **And Voila ! a square frame !**
177 |
178 |
179 | ### Via End Miter Command
180 |
181 | Let's show the other base frame ...
182 |
183 | 
184 |
185 | We first must add offsets to the existing profiles... (offsets adds up to the dimension of the edge !)
186 |
187 | 1. add Offset (One profile by one, Or selecting all the profiles and change the offset.)
188 |
189 | 
190 |
191 | 2. Unselect all objects, then select two touching Profiles. (**select faces in the 3D view, not objects in the tree view**)
192 |
193 | 
194 |
195 | 1. Click on the Create Miter End Command
196 |
197 | 
198 |
199 | **And voila !** You have two "TrimmedProfile"
200 |
201 | 
202 |
203 |
204 | ### Via End Trim Command
205 |
206 | Let's finish the 3 others corners of the second frame...
207 |
208 | 
209 |
210 | 
211 |
212 | When everything is showed again, you can see the vertical profiles are not cut as they should...
213 |
214 | Let's open again the corner manager, selecting "end trim"
215 |
216 | 
217 |
218 |
219 | 
220 |
221 | 1. Select the vertical profile first, add it to the trimmed object with the plus (+) button
222 |
223 | 
224 | 
225 |
226 | 2. Select the face of the profile you want to cut with.. (here, I add to move the view and select the bottom **face**)
227 |
228 | 
229 | 
230 |
231 | You can change the cut type: straight or following the other profile.
232 |
233 | 
234 | 
235 |
236 |
237 | And you also can add faces related to the other side of the trimmed profile.
238 |
239 | ## Organizing Objects
240 |
241 | That's the bad part.
242 |
243 | I find the tree view messy. Really messy.
244 |
245 | ### Part Container
246 |
247 | I often use Part container for grouping profiles, sketches, etc.
248 |
249 | 
250 |
251 | 
252 |
253 | You should drag only one profile to the container... I don't know why, but FreeCAD is not happy about a group drag.
254 |
255 | Sometime parts and profile get out of the Part Container.
256 |
257 |
258 |
259 | ### Fusion
260 |
261 | One can fuse profiles together.
262 |
263 | 
264 |
265 | 
266 |
267 | It allows to group objects.
268 |
269 |
270 | ## Using profiles in Part Design... ie, making holes !
271 |
272 | To use all of these profiles in PartDesign, for instance, to make holes... in it.. !
273 |
274 | you need to use a fusion of the profile, and create a body...
275 |
276 | 
277 |
278 | 1. Drag and drop the fusion into the body.
279 |
280 | 
281 |
282 | 2. Now, you have a standard Part design Body...
283 |
284 | You can map a sketch to any face, and use Part design to do whatever you want !
285 |
286 | 
287 |
288 | 
--------------------------------------------------------------------------------
/freecad/frameforge/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | RESSOURCESPATH = os.path.join(os.path.dirname(__file__), "resources")
4 |
5 | PROFILESPATH = os.path.join(RESSOURCESPATH, "profiles")
6 |
7 | ICONPATH = os.path.join(RESSOURCESPATH, "icons")
8 | PROFILEIMAGES_PATH = os.path.join(RESSOURCESPATH, "images", "profiles")
9 | UIPATH = os.path.join(RESSOURCESPATH, "ui")
10 | TRANSLATIONSPATH = os.path.join(RESSOURCESPATH, "translations")
--------------------------------------------------------------------------------
/freecad/frameforge/_utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | __title__ = "Curves workbench utilities"
4 | __author__ = "Christophe Grellier (Chris_G)"
5 | __license__ = "LGPL 2.1"
6 | __doc__ = "Curves workbench utilities common to all tools."
7 |
8 | import FreeCAD
9 | import Part
10 |
11 |
12 | def getSubShape(shape, shape_type, n):
13 | if shape_type == "Vertex" and len(shape.Vertexes) >= n:
14 | return shape.Vertexes[n - 1]
15 | elif shape_type == "Edge" and len(shape.Edges) >= n:
16 | return shape.Edges[n - 1]
17 | elif shape_type == "Face" and len(shape.Faces) >= n:
18 | return shape.Faces[n - 1]
19 | else:
20 | return None
21 |
22 |
23 | def getShape(obj, prop, shape_type):
24 | if hasattr(obj, prop) and obj.getPropertyByName(prop):
25 | prop_link = obj.getPropertyByName(prop)
26 | if obj.getTypeIdOfProperty(prop) == "App::PropertyLinkSub":
27 | if shape_type in prop_link[1][0]:
28 | # try: # FC 0.19+
29 | # return prop_link[0].getSubObject(prop_link[1][0])
30 | # except AttributeError: # FC 0.18 (stable)
31 | n = eval(obj.getPropertyByName(prop)[1][0].lstrip(shape_type))
32 | osh = obj.getPropertyByName(prop)[0].Shape
33 | sh = osh.copy()
34 | if sh and (not shape_type == "Vertex") and hasattr(obj.getPropertyByName(prop)[0], "getGlobalPlacement"):
35 | pl = obj.getPropertyByName(prop)[0].getGlobalPlacement()
36 | sh.Placement = pl
37 | return getSubShape(sh, shape_type, n)
38 |
39 | elif obj.getTypeIdOfProperty(prop) == "App::PropertyLinkSubList":
40 | res = []
41 | for tup in prop_link:
42 | for ss in tup[1]:
43 | if shape_type in ss:
44 | # try: # FC 0.19+
45 | # res.append(tup[0].getSubObject(ss))
46 | # except AttributeError: # FC 0.18 (stable)
47 | n = eval(ss.lstrip(shape_type))
48 | sh = tup[0].Shape.copy()
49 | if sh and (not shape_type == "Vertex") and hasattr(tup[0], "getGlobalPlacement"):
50 | pl = tup[0].getGlobalPlacement()
51 | sh.Placement = pl
52 | res.append(getSubShape(sh, shape_type, n))
53 | return res
54 | else:
55 | FreeCAD.Console.PrintError("CurvesWB._utils.getShape: wrong property type.\n")
56 | return None
57 | else:
58 | # FreeCAD.Console.PrintError("CurvesWB._utils.getShape: %r has no property %r\n"%(obj, prop))
59 | return None
60 |
61 |
--------------------------------------------------------------------------------
/freecad/frameforge/create_end_miter_tool.py:
--------------------------------------------------------------------------------
1 | import os, glob
2 | import json
3 |
4 | from PySide import QtCore, QtGui
5 |
6 | import FreeCADGui as Gui
7 | import FreeCAD as App
8 |
9 | import Part, ArchCommands
10 | import BOPTools.SplitAPI
11 |
12 | from freecad.frameforge.translate_utils import translate
13 | from freecad.frameforge import PROFILESPATH, PROFILEIMAGES_PATH, ICONPATH, UIPATH
14 |
15 | from freecad.frameforge.trimmed_profile import TrimmedProfile, ViewProviderTrimmedProfile
16 |
17 |
18 |
19 | class CreateEndMiterCommand():
20 | def GetResources(self):
21 | return {
22 | "Pixmap": os.path.join(ICONPATH, "corner-end-miter.svg"),
23 | "MenuText": translate("MetalWB", "Create Miter Ends"),
24 | "Accel": "M, C",
25 | "ToolTip": translate("MetalWB", "