[ Fixed ] [ Bug ] Draft_Offset problem with direction if precision=6

A forum dedicated to the Draft, Arch and BIM workbenches development.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
Roy_043
Veteran
Posts: 8452
Joined: Thu Dec 27, 2018 12:28 pm

[ Fixed ] [ Bug ] Draft_Offset problem with direction if precision=6

Post by Roy_043 »

The Draft_Offset command reports 'something wrong with firstDir' in certain cases if the Draft precision is 6 (which is the default value BTW). See image and attached file.

DraftVecUtils.equals relies on the Draft precision. So it may be better to switch to the isEqual method of the Vector class here. In the suggested code the tolerance is hard-coded. I do not know if that is OK.

Suggested code (see # Modified)

Code: Select all

    if not firstDir:
        # need to test against Part.Circle, not Part.ArcOfCircle
        if isinstance(e.Curve, (Part.Circle,Part.Ellipse)):
            v0 = e.tangentAt(e.FirstParameter).cross(norm)
        else:
            v0 = vec(e).cross(norm)
        # check against dvec provided for the offset direction
        # would not know if dvec is vector of width (Left/Right Align)
        # or width/2 (Center Align)
        v0.normalize()                           # Modified
        v1 = App.Vector(dvec).normalize()        # Modified
        if v0.isEqual(v1, 0.0001):               # Modified
            # "Left Offset" (Left Align or 'left offset' in Centre Align)
            firstDir = 1
            firstAlign = 'Left'
            alignListC.append('Left')
        elif v0.isEqual(v1.negative(), 0.0001):  # Modified
            # "Right Offset" (Right Align or 'right offset' in Centre Align)
            firstDir = -1
            firstAlign = 'Right'
            alignListC.append('Right')
        else:
            print(" something wrong with firstDir ")
            firstAlign = 'Left'
            alignListC.append('Left')
Original code:

Code: Select all

    if not firstDir:
        # need to test against Part.Circle, not Part.ArcOfCircle
        if isinstance(e.Curve, (Part.Circle,Part.Ellipse)):
            v0 = e.tangentAt(e.FirstParameter).cross(norm)
        else:
            v0 = vec(e).cross(norm)
        # check against dvec provided for the offset direction
        # would not know if dvec is vector of width (Left/Right Align)
        # or width/2 (Center Align)
        dvec0 = DraftVecUtils.scaleTo(v0, dvec.Length)
        if DraftVecUtils.equals(dvec0, dvec):
            # "Left Offset" (Left Align or 'left offset' in Centre Align)
            firstDir = 1
            firstAlign = 'Left'
            alignListC.append('Left')
        elif DraftVecUtils.equals(dvec0, dvec.negative()):
            # "Right Offset" (Right Align or 'right offset' in Centre Align)
            firstDir = -1
            firstAlign = 'Right'
            alignListC.append('Right')
        else:
            print(" something wrong with firstDir ")
            firstAlign = 'Left'
            alignListC.append('Left')

Code: Select all

OS: Windows 8.1 Version 6.3 (Build 9600)
Word size of FreeCAD: 64-bit
Version: 0.20.24893 (Git)
Build type: Release
Branch: master
Hash: 03855f793feaceeb4385c02f6520f3e1b6429c93
Python version: 3.8.6+
Qt version: 5.15.2
Coin version: 4.0.1
OCC version: 7.5.0
Locale: Dutch/Netherlands (nl_NL)
Attachments
offset.png
offset.png (6.06 KiB) Viewed 1895 times
offset.FCStd
(5.28 KiB) Downloaded 42 times
Last edited by Roy_043 on Wed Jun 30, 2021 12:49 pm, edited 1 time in total.
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ Bug ] Draft_Offset problem with direction if precision=6

Post by paullee »

Roy_043 wrote: Mon May 31, 2021 2:22 pm The Draft_Offset command reports 'something wrong with firstDir' in certain cases if the Draft precision is 6 (which is the default value BTW). See image and attached file.

DraftVecUtils.equals relies on the Draft precision. So it may be better to switch to the isEqual method of the Vector class here. In the suggested code the tolerance is hard-coded. I do not know if that is OK.
Thanks! Interesting finding! :)

Had once discussed with @yorik on precision level :
- https://github.com/FreeCAD/FreeCAD/pull/2029
- https://www.forum.freecadweb.org/viewto ... 64#p294655

Seems that was 10 in my earlier study to avoid some problem. And @yorik set a max level of 10 and default to 6 in Preference, rather than hard-coding in code as I once suggested.

Are your sure it should be 4 to avoid problem in the Offset()? Not sure if other users not on Arch/BIM, but on some very tiny object will have problem?

I have a look at the code (probably copying / following what @yorik had as I just learned some python fundamental) and scaleTo() was used. Then, the magnitude of the 2 vectors (dvec0 and dvec) should not matter (as far as internal precision that is up to 16 or even greater?), but it is the 'direction' that are being compared. Not sure if 2 vectors are nomalised as suggested, would that make precision matter more? Happy to discuss and learn :)

Code: Select all

        dvec0 = DraftVecUtils.scaleTo(v0, dvec.Length)
        if DraftVecUtils.equals(dvec0, dvec):

BTW, I learned the DraftVectils.equals and used it. Any idea what is the difference with your isEqual() method? Thanks :)

Code: Select all

def equals(u, v):
    typecheck([(u, Vector), (v, Vector)], "equals")
    return isNull(u.sub(v))
User avatar
Roy_043
Veteran
Posts: 8452
Joined: Thu Dec 27, 2018 12:28 pm

Re: [ Bug ] Draft_Offset problem with direction if precision=6

Post by Roy_043 »

The internal precision (translated to the decimal format) is 15-16 significant numbers. The Draft precision is 6 decimals. When comparing vectors with a length of 1000mm with a draft precision of 6 you are dealing with 10 significant numbers.

The grid in the example is 100x100. And the object is close to the origin (leftmost point: 400,100). The command should not fail in this case. But it does if Draft precision is 6. You need to change the Draft precision to 5.

If you want to keep using DraftVecUtils.equals you should at least normalize the vectors first. If you do that then Draft precision can be 7.

But comparing with a lower precision makes sense since we are only interested in the side (Left or Right) the pointer is on.

If I test the suggested mod with a scaled down wire (factor: 0,0001, center: 0,0,0, leftmost point: 40µm,10µm) the command still works fine.
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ Bug ] Draft_Offset problem with direction if precision=6

Post by paullee »

Roy_043 wrote: Wed Jun 02, 2021 11:32 am The internal precision (translated to the decimal format) is 15-16 significant numbers. The Draft precision is 6 decimals. When comparing vectors with a length of 1000mm with a draft precision of 6 you are dealing with 10 significant numbers.

The grid in the example is 100x100. And the object is close to the origin (leftmost point: 400,100). The command should not fail in this case. But it does if Draft precision is 6. You need to change the Draft precision to 5.

If you want to keep using DraftVecUtils.equals you should at least normalize the vectors first. If you do that then Draft precision can be 7.

But comparing with a lower precision makes sense since we are only interested in the side (Left or Right) the pointer is on.

If I test the suggested mod with a scaled down wire (factor: 0,0001, center: 0,0,0, leftmost point: 40µm,10µm) the command still works fine.
Thanks for the mathematics!

Except below modification of 'App' to 'FreeCAD', it works as expected, thanks :D

Code: Select all

        #v1 = App.Vector(dvec).normalize()        # Modified
        v1 = FreeCAD.Vector(dvec).normalize()        # Further Modified
User avatar
Roy_043
Veteran
Posts: 8452
Joined: Thu Dec 27, 2018 12:28 pm

Re: [ Bug ] Draft_Offset problem with direction if precision=6

Post by Roy_043 »

paullee wrote: Wed Jun 02, 2021 5:48 pm Except below modification of 'App' to 'FreeCAD', it works as expected, thanks
That cannot be correct.

At the top of the file:

Code: Select all

import FreeCAD as App
Plus App.Vector occurs 5 further times in the file.
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ Bug ] Draft_Offset problem with direction if precision=6

Post by paullee »

Roy_043 wrote: Wed Jun 02, 2021 5:59 pm That cannot be correct.

At the top of the file:

Code: Select all

import FreeCAD as App
Plus App.Vector occurs 5 further times in the file.
Oh thanks, I am still using 0.19_pre git 23756. I fetch the latest upstream and see it now :)
User avatar
Roy_043
Veteran
Posts: 8452
Joined: Thu Dec 27, 2018 12:28 pm

Re: [ Fixed ] [ Bug ] Draft_Offset problem with direction if precision=6

Post by Roy_043 »

This PR has been merged.
Post Reply