Varying line thickness for different parts in TechDraw
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
Varying line thickness for different parts in TechDraw
I would like to export SVG images looking like the attached image. I think I can handle everything semi-automatically with a custom python script (which parts are displayed, callout of parts, etc), in the TechDraw workbench. The only thing I don't know is possible or not is to display some parts in fat lines, others in thin lines. I can change individual lines thickness in TechDraw, probably also possible to do that from a python script (?), but the problem is I don't think TechDraw remembers which line comes from which part? For example if I want the L00 part to be displayed with fat lines, how can I know which lines I should change thickness?
A neat feature would be for TechDraw to use the display thickness from each part when the view is rendered, but I don't think such a feature exists at this time?
Any idea how I could do that?
Thanks for any hints!
A neat feature would be for TechDraw to use the display thickness from each part when the view is rendered, but I don't think such a feature exists at this time?
Any idea how I could do that?
Thanks for any hints!
- wandererfan
- Veteran
- Posts: 6309
- Joined: Tue Nov 06, 2012 5:42 pm
- Contact:
Re: Varying line thickness for different parts in TechDraw
Are the "parts"(L00) all in the same View? If so, then there is no easy way for the program to know what lines belong to which part. All the lines from all the source shapes are delivered in one big pile. If they are in different Views, then this is easy.
Off the top of my head, the only way to do this would be to take every edge in the source shape, project it onto the paper plane, then try to find a matching projected edge in the View. This would be very slow on a big model, and difficult to do since the lines in the view might be clipped if they are occluded by a face.
Re: Varying line thickness for different parts in TechDraw
All the parts are in the same viewwandererfan wrote: ↑Thu Oct 06, 2022 1:21 pm Are the "parts"(L00) all in the same View? If so, then there is no easy way for the program to know what lines belong to which part. All the lines from all the source shapes are delivered in one big pile. If they are in different Views, then this is easy.
Yes, some parts may occlude others, so I'm on the "difficult" side of thingswandererfan wrote: ↑Thu Oct 06, 2022 1:21 pm Off the top of my head, the only way to do this would be to take every edge in the source shape, project it onto the paper plane, then try to find a matching projected edge in the View. This would be very slow on a big model, and difficult to do since the lines in the view might be clipped if they are occluded by a face.
Thanks for your suggesion though! A variant of your technique would be to project the "fat" parts in one view, then project all the parts (thin and fat) in the final view. Then lines of the final view that are contained within a line of the "fat" view (colinear and within the extremities) should be rendered as fat lines. However, this would assume the "depth" of lines is retained in the 2D view (as a Z value?) otherwise this technique could not discriminate between two lines from different parts that end up superposed in the 2D view. Also, while it may be "easy" for straight lines, it becomes more complicated for curves (especially when they are partially occluded).
I also wonder if the feature could be properly (i.e. not like the hack described above) implemented in TechDraw. I guess it's OCCT that performs the projection and hidden line removal? Is there a place in FreeCAD code where it's still possible to know which projected line came from what part, or is it already lost when OCCT gives its result?
- wandererfan
- Veteran
- Posts: 6309
- Joined: Tue Nov 06, 2012 5:42 pm
- Contact:
Re: Varying line thickness for different parts in TechDraw
The way the code works is shape->OCCT-HLR->unorganized pile of edges.
If shape is a compound of many subshapes, according to the documentation, there might be a way to ask OCCT which edges in the pile came from which subshape. This is a bit of a special case though.
Re: Varying line thickness for different parts in TechDraw
OK, interesting. Sadly, I don't think I'll find the time to look at the code any time soon, but I'll keep that in mind. Thanks for the info!
Re: Varying line thickness for different parts in TechDraw
@wandererfan FYI, I've implemented the technique of matching lines with a drawing of the same part (rendered in a separate view that I delete afterwards). It kind of works, but as expected this is slow. I cache the result of each part rendering in a separate view, but it has to be rendered once for each part for each projection direction. Comparing lines is actually pretty fast, and can be further accelerated by partitioning the space (maybe in Hough space, by direction and distance from origin of each line). Also, curves are not handled by my implementation (yet). While this may be sufficient for my current needs, I'll consider exploring other options (like finding a way to get lines associated to each part from the OCCT projection).
For anyone interested, source code is here: https://gitea.youb.fr/youen/assembly_handbook (work in progress of course). It's an additional workbench, I'll try to make a small tutorial to explain how to use it (it has other features, like creating balloons for each part automatically, updating the arrows when parts are moved, and allowing to select parts to add/remove to the drawing from the 3D view)
For anyone interested, source code is here: https://gitea.youb.fr/youen/assembly_handbook (work in progress of course). It's an additional workbench, I'll try to make a small tutorial to explain how to use it (it has other features, like creating balloons for each part automatically, updating the arrows when parts are moved, and allowing to select parts to add/remove to the drawing from the 3D view)
Re: Varying line thickness for different parts in TechDraw
A trick that works to some extent to avoid false positive (line detected from a part while it's not) is to not use an exact projection direction. A very small offset from the principal directions or from isometric direction avoids to have perfect match from lines that are at a different depth.
Also, I found no way to project a 3D point to 2D view coordinates. So what I do is I use makeCosmeticVertex3d to create a vertex at the 3D position, and then read back the 2D coordinates of that vertex. However it's an additional performance hit, because it triggers a repaint of the view for each additional vertex created, and also when deleting it.
Another thing I'm not too sure about is how to convert 2D view coordinates to Qt coordinates (I use a custom QGraphicsItem as handle to drag/drop the balloon arrow end). It seems I just need to multiply by the view scale multiplied by 10, is this correct in all cases?
I've also noticed bugs with balloons: when reloading the document, visible balloons are not displayed until I select them. And hidden balloons have the text displayed until I set them hidden again. Not a big problem though.
Also, I found no way to project a 3D point to 2D view coordinates. So what I do is I use makeCosmeticVertex3d to create a vertex at the 3D position, and then read back the 2D coordinates of that vertex. However it's an additional performance hit, because it triggers a repaint of the view for each additional vertex created, and also when deleting it.
Another thing I'm not too sure about is how to convert 2D view coordinates to Qt coordinates (I use a custom QGraphicsItem as handle to drag/drop the balloon arrow end). It seems I just need to multiply by the view scale multiplied by 10, is this correct in all cases?
I've also noticed bugs with balloons: when reloading the document, visible balloons are not displayed until I select them. And hidden balloons have the text displayed until I set them hidden again. Not a big problem though.
- wandererfan
- Veteran
- Posts: 6309
- Joined: Tue Nov 06, 2012 5:42 pm
- Contact:
Re: Varying line thickness for different parts in TechDraw
I've just merged a PR that exposes the C++ method DrawViewPart::projectPoint to Python.
Code: Select all
>>> dvp = App.ActiveDocument.View
>>> vec3d = App.Vector(10.0, 10.0, 10.0)
>>> dvp.projectPoint(vec3d)
Vector (10.0, 10.0, 0.0)
>>> dvp.projectPoint(vec3d, True)
Vector (10.0, -10.0, 0.0)
>>>
If you are working within a View's coordinate system, this will work. If you are moving Views on the page, then you have to worry about +Y being down in Qt (and don't forget clockwise angles!). We deal with this by drawing in the (X, -Y) quadrant and flipping the y coordinate. This is why you'll see various "invert" and "mirror" methods in the code.youen wrote: ↑Wed Oct 19, 2022 9:28 am Another thing I'm not too sure about is how to convert 2D view coordinates to Qt coordinates (I use a custom QGraphicsItem as handle to drag/drop the balloon arrow end). It seems I just need to multiply by the view scale multiplied by 10, is this correct in all cases?
I haven't seen this one. Do you have step by step instructions for me?
Re: Varying line thickness for different parts in TechDraw
Great, thankswandererfan wrote: ↑Thu Oct 20, 2022 12:13 am I've just merged a PR that exposes the C++ method DrawViewPart::projectPoint to Python.
OK, good, thanks for the details!wandererfan wrote: ↑Thu Oct 20, 2022 12:13 am If you are working within a View's coordinate system, this will work. If you are moving Views on the page, then you have to worry about +Y being down in Qt (and don't forget clockwise angles!). We deal with this by drawing in the (X, -Y) quadrant and flipping the y coordinate. This is why you'll see various "invert" and "mirror" methods in the code.
I've made more tests, and the bugs need two conditions to happen: the view must have KeepUpdated = False, and the bug only happens on my Linux installation. It does not happen on Windows. Of course it may also be related to some settings I've changed, but at least it works on one of my installations.wandererfan wrote: ↑Thu Oct 20, 2022 12:13 amI haven't seen this one. Do you have step by step instructions for me?
I've attached the example file. On Linux, I start FreeCAD, open the file, double click on the TechDraw page, click the "Redraw Page" button, and then the cube appears but not the balloon. When I select the balloon in the document tree, it instantly appears on the TechDraw page.
Here are the details on the version I have on Linux :
Code: Select all
OS: Debian GNU/Linux 11 (bullseye) (MATE/lightdm-xsession)
Word size of FreeCAD: 64-bit
Version: 0.20.29177 (Git) AppImage
Build type: Release
Branch: (HEAD detached at 0.20)
Hash: 68e337670e227889217652ddac593c93b5e8dc94
Python 3.9.13, Qt 5.12.9, Coin 4.0.0, Vtk 9.1.0, OCC 7.5.3
Locale: French/France (fr_FR)
Installed mods:
* assembly_handbook
* sheetmetal 0.2.56
* fasteners 0.4.3
* Assembly4 0.12.3
- Attachments
-
- test.FCStd
- (17.97 KiB) Downloaded 7 times
- wandererfan
- Veteran
- Posts: 6309
- Joined: Tue Nov 06, 2012 5:42 pm
- Contact:
Re: Varying line thickness for different parts in TechDraw
If KeepUpdated on the Page is False, then the expected behaviour on load is that Views will not be drawn and only the frame will appear. If the frames are toggled off, then you won't see anything other than the template.
I don't get this behaviour, but maybe I didn't follow instructions correctly. It could be that selecting the Balloon triggers a recompute which triggers a redraw.When I select the balloon in the document tree, it instantly appears on the TechDraw page.