[PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire(), connect(), precision()

A forum dedicated to the Draft, Arch and BIM workbenches development.
paullee
Posts: 2753
Joined: Wed May 04, 2016 3:58 pm

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire

Postby paullee » Thu Feb 28, 2019 3:49 pm

Ok, I think I have found the 2nd bug...

Currently, it seem you try to create an ArchWall and it fails... then when you recompute, the ArchWall appears!

The bug is in the Connect().... the v2 is recalculated everytime for each edge but it may be verrrrrrry slightly different from the previous v1... then the edge is not connected on 1st calculation... then when sketch is resolved again with its solver, with verrryy slight difference, the Connect() give you the 'same' v1 and previous v2, and you have contiunous edge...

Try another revised DraftGeomUtils.py attached .... the ArchWall should appears ... no randomness.
(I suspect there is still very corner case there will be strange result though :D - 3rd 'bug in DraftVecUtils.closest() ? :lol: ... )

Code: Select all

        ## TODO
        v2 = None

        for i in range(len(edges)):
            curr = edges[i]
            #print("debug: DraftGeomUtils.connect edge ",i," : ",curr.Vertexes[0].Point,curr.Vertexes[-1].Point)
            if i > 0:
                prev = edges[i-1]
            else:
                if closed:
                    prev = edges[-1]
                else:
                    prev = None
            if i < (len(edges)-1):
                next = edges[i+1]
            else:
                if closed: next = edges[0]
                else:
                    next = None
            if prev:
              ## TODO
              print("debug: DraftGeomUtils.connect prev - prev: ",prev.Vertexes[0].Point,prev.Vertexes[-1].Point)
              print("debug: DraftGeomUtils.connect prev - curr: ",curr.Vertexes[0].Point,curr.Vertexes[-1].Point)

              ## TODO
              if v2:
                v1 = v2

              else:
                i = findIntersection(curr,prev,True,True)
                print("debug: DraftGeomUtils.connect prev - intersection: ", i)
                if i:
                    v1 = i[DraftVecUtils.closest(curr.Vertexes[0].Point,i)]
                else:
                    v1 = curr.Vertexes[0].Point
            else:
                v1 = curr.Vertexes[0].Point
Screenshot from 2019-02-28 23-46-03.png
Screenshot from 2019-02-28 23-46-03.png (240.63 KiB) Viewed 526 times
Attachments
DraftGeomUtils.py
(109.33 KiB) Downloaded 13 times
Last edited by paullee on Thu Feb 28, 2019 4:13 pm, edited 2 times in total.
paullee
Posts: 2753
Joined: Wed May 04, 2016 3:58 pm

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire

Postby paullee » Thu Feb 28, 2019 4:02 pm

yorik wrote:
Hi @yorik, I am more or less sure most problem associated with ArchWall / DraftGeomUtils - offsetWire() + connect() are solved with the revised DraftGeomUtils.py.

(except still suspicious about DraftVecUtils.closest as said above :) )

Still, I am not sure why there is edges = Part.__sortEdges__(wire.Edges) in def offsetWire()...
  1. I once suspect if the edges are sorted again, would the 1st edge (for dvec has been calculated) be replaced by another edge then lead to error - e.g. 10 edges in a closed loop, the edge 8 become edge 1...
  2. Change it to edges = wire.Edges seems have no problems
3rd Version of DraftGeomUtils.py attached.

Would wait for you to have a look to confirm it is OK before I make a PR or need to review :)

Thanks.

Code: Select all

def offsetWire(wire,dvec,bind=False,occ=False):
    '''
    offsetWire(wire,vector,[bind]): offsets the given wire along the
    given vector. The vector will be applied at the first vertex of
    the wire. If bind is True (and the shape is open), the original
    wire and the offsetted one are bound by 2 edges, forming a face.
    '''

    #edges = Part.__sortEdges__(wire.Edges)
    edges = wire.Edges
Attachments
DraftGeomUtils.py
(109.33 KiB) Downloaded 14 times
Syres
Posts: 816
Joined: Thu Aug 09, 2018 11:14 am

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire

Postby Syres » Thu Feb 28, 2019 4:25 pm

paullee wrote:
Thu Feb 28, 2019 3:49 pm
Try another revised DraftGeomUtils.py attached .... the ArchWall should appears ... no randomness.
Yep, that's worked 100% of the time with the revised DraftGeomUtils.py and using new sketches as well as previously created ones. I'm going to be offline for about 36 hours but I think you're sorted or very nearly now anyway.
paullee
Posts: 2753
Joined: Wed May 04, 2016 3:58 pm

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire

Postby paullee » Thu Feb 28, 2019 8:28 pm

Thanks for testing... :)

Just find another old problem still exist - 3 edges in 1 sketch, 2 continuous wires: BUT sometimes 1 wall, sometimes 2 walls ?

Do not have much idea for this scenario ATM :D

https://forum.freecadweb.org/viewtopic. ... 10#p204530

Test file in that post: Test _ Arch Wall _ on Sketch_ bug question__ 21.fcstd

phpBB [video]
paullee
Posts: 2753
Joined: Wed May 04, 2016 3:58 pm

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire

Postby paullee » Tue Mar 12, 2019 6:05 pm

yorik wrote:
paullee wrote:
Thu Feb 28, 2019 4:02 pm
yorik wrote:
Hi @yorik, I am more or less sure most problem associated with ArchWall / DraftGeomUtils - offsetWire() + connect() are solved with the revised DraftGeomUtils.py.

(except still suspicious about DraftVecUtils.closest as said above :) )

Still, I am not sure why there is edges = Part.__sortEdges__(wire.Edges) in def offsetWire()...
  1. I once suspect if the edges are sorted again, would the 1st edge (for dvec has been calculated) be replaced by another edge then lead to error - e.g. 10 edges in a closed loop, the edge 8 become edge 1...
  2. Change it to edges = wire.Edges seems have no problems
3rd Version of DraftGeomUtils.py attached.

Would wait for you to have a look to confirm it is OK before I make a PR or need to review :)

Thanks.

Code: Select all

def offsetWire(wire,dvec,bind=False,occ=False):
    '''
    offsetWire(wire,vector,[bind]): offsets the given wire along the
    given vector. The vector will be applied at the first vertex of
    the wire. If bind is True (and the shape is open), the original
    wire and the offsetted one are bound by 2 edges, forming a face.
    '''

    #edges = Part.__sortEdges__(wire.Edges)
    edges = wire.Edges
Hi Yorik, see if you have a gap to check the intended bug fix above. Would like to sort out other issue if this is closed / discussed.

Thanks :)
User avatar
yorik
Site Admin
Posts: 12058
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire

Postby yorik » Wed Mar 13, 2019 4:34 pm

This is a complicated problem.. Indeed all the different edges sorting methods seem to screw things up from time to time.
But inherently, any OCC shape can be made of totally unordered subcomponents. So in a way or another, we will need to sort.

I think it would be best to try to fix Part.sortEdges...
paullee
Posts: 2753
Joined: Wed May 04, 2016 3:58 pm

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire() , connect()

Postby paullee » Wed Mar 13, 2019 11:59 pm

yorik wrote:
Wed Mar 13, 2019 4:34 pm
This is a complicated problem.. Indeed all the different edges sorting methods seem to screw things up from time to time.
But inherently, any OCC shape can be made of totally unordered subcomponents. So in a way or another, we will need to sort.

I think it would be best to try to fix Part.sortEdges...
Thanks! Could you also look at another two suspected bugs and proposed fixes about Connect() and Offsetwire() if they make sense before I make a PR? :)

(I just indicates the proposed changes by 'bracketing' them with "## TODO" in the DraftGeomUtils.py - seem much better to review in gitHub indeed)

paullee wrote:
Thu Feb 28, 2019 3:49 pm
Ok, I think I have found the 2nd bug...

Currently, it seem you try to create an ArchWall and it fails... then when you recompute, the ArchWall appears!

The bug is in the Connect().... the v2 is recalculated everytime for each edge but it may be verrrrrrry slightly different from the previous v1... then the edge is not connected on 1st calculation... then when sketch is resolved again with its solver, with verrryy slight difference, the Connect() give you the 'same' v1 and previous v2, and you have contiunous edge...

Try another revised DraftGeomUtils.py attached .... the ArchWall should appears ... no randomness.
(I suspect there is still very corner case there will be strange result though :D - 3rd 'bug in DraftVecUtils.closest() ? :lol: ... )

Code: Select all

        ## TODO
        v2 = None

        for i in range(len(edges)):
            curr = edges[i]
            #print("debug: DraftGeomUtils.connect edge ",i," : ",curr.Vertexes[0].Point,curr.Vertexes[-1].Point)
            if i > 0:
                prev = edges[i-1]
            else:
                if closed:
                    prev = edges[-1]
                else:
                    prev = None
            if i < (len(edges)-1):
                next = edges[i+1]
            else:
                if closed: next = edges[0]
                else:
                    next = None
            if prev:
              ## TODO
              print("debug: DraftGeomUtils.connect prev - prev: ",prev.Vertexes[0].Point,prev.Vertexes[-1].Point)
              print("debug: DraftGeomUtils.connect prev - curr: ",curr.Vertexes[0].Point,curr.Vertexes[-1].Point)

              ## TODO
              if v2:
                v1 = v2

              else:
                i = findIntersection(curr,prev,True,True)
                print("debug: DraftGeomUtils.connect prev - intersection: ", i)
                if i:
                    v1 = i[DraftVecUtils.closest(curr.Vertexes[0].Point,i)]
                else:
                    v1 = curr.Vertexes[0].Point
            else:
                v1 = curr.Vertexes[0].Point
Screenshot from 2019-02-28 23-46-03.png
Screenshot from 2019-02-28 23-46-03.png (240.63 KiB) Viewed 404 times

paullee wrote:
Wed Feb 27, 2019 5:42 pm
Hi I have long (11.5.2017) annoyed by a problem in ArchWall creation... https://forum.freecadweb.org/viewtopic. ... =3&t=22379

I think I may have found a bug which stop a wire with curve properly build an offsetWire.

ScreenCapture 1 - ArchWall return

Code: Select all

DraftGeomUtils.connect: unable to connect edges
...
DraftGeomUtils: unable to bind wires
Error: Invalid base object
ScreenCapture 2 - ArchWall Created Succesfully - Fix applied

Possible Problem - Edges are 'offset' in wrong direction when 1st edge happen to be curve after sortEdge(), see below which shows edges of a 'slot' are not offset correctly

Code: Select all

('debug: DraftGeomUtils.connect prev - prev: ', Vector (-4100.0, -3000.0, 0.0), Vector (3900.0, -3000.0000000000005, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (3999.9999999999995, -3100.0000000000005, 0.0), Vector (4000.000000000001, 3099.9999999999986, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [Vector (4781.024967590664, -3000.0000000000005, 0.0), Vector (3218.9750324093357, -3000.0000000000005, 0.0)])
('debug: DraftGeomUtils.connect prev - prev: ', Vector (3999.9999999999995, -3100.0000000000005, 0.0), Vector (4000.000000000001, 3099.9999999999986, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (4100.000000000001, 2999.9999999999986, 0.0), Vector (-3900.0, 3000.0, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [Vector (3218.975032409336, 2999.9999999999986, 0.0), Vector (4781.024967590664, 2999.9999999999986, 0.0)])
('debug: DraftGeomUtils.connect prev - prev: ', Vector (4100.000000000001, 2999.9999999999986, 0.0), Vector (-3900.0, 3000.0, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (-4000.0, 3001.6662039607268, 0.0), Vector (-4000.0000000000005, -3001.6662039607268, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [Vector (-4099.999999999999, 3000.0, 0.0), Vector (-3899.999999999999, 3000.0, 0.0)])
('debug: DraftGeomUtils.connect prev - prev: ', Vector (-4000.0, 3001.6662039607268, 0.0), Vector (-4000.0000000000005, -3001.6662039607268, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (-4100.0, -3000.0, 0.0), Vector (3900.0, -3000.0000000000005, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [Vector (-3900.0, -3000.0, 0.0), Vector (-4100.0, -3000.0, 0.0)])
('debug: DraftGeomUtils.connect prev - prev: ', Vector (-3900.0000000000005, -3000.0, 0.0), Vector (4100.0, -3000.0000000000005, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (3999.9999999999995, -2900.0000000000005, 0.0), Vector (4000.000000000001, 2899.9999999999986, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [])
('debug: DraftGeomUtils.connect prev - prev: ', Vector (3999.9999999999995, -2900.0000000000005, 0.0), Vector (4000.000000000001, 2899.9999999999986, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (3900.000000000001, 2999.9999999999986, 0.0), Vector (-4100.0, 3000.0, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [])
('debug: DraftGeomUtils.connect prev - prev: ', Vector (3900.000000000001, 2999.9999999999986, 0.0), Vector (-4100.0, 3000.0, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (-4000.0, 3001.6662039607268, 0.0), Vector (-4000.0000000000005, -3001.6662039607268, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [Vector (-4099.999999999999, 3000.0, 0.0), Vector (-3899.999999999999, 3000.0, 0.0)])
('debug: DraftGeomUtils.connect prev - prev: ', Vector (-4000.0, 3001.6662039607268, 0.0), Vector (-4000.0000000000005, -3001.6662039607268, 0.0))
('debug: DraftGeomUtils.connect prev - curr: ', Vector (-3900.0000000000005, -3000.0, 0.0), Vector (4100.0, -3000.0000000000005, 0.0))
('debug: DraftGeomUtils.connect prev - intersection: ', [Vector (-3900.0, -3000.0, 0.0), Vector (-4100.0, -3000.0, 0.0)])
DraftGeomUtils.connect: unable to connect edges
(Circle (Radius : 2900, Position : (4000, -1.02318e-12, 0), Direction : (0, -0, 1)), ' ', Vector (3999.9999999999995, -2900.000000000001, 0.0), ' ', Vector (4000.0000000000014, 2899.999999999999, 0.0))
(<Line object>, ' ', Vector (3900.000000000001, 2999.9999999999986, 0.0), ' ', Vector (-4099.999999999999, 3000.0, 0.0))
(Circle (Radius : 3001.67, Position : (-4000, -2.27374e-13, 0), Direction : (0, 0, 1)), ' ', Vector (-4099.999999999999, 3000.0, 0.0), ' ', Vector (-4100.000000000001, -3000.0, 0.0))
(<Line object>, ' ', Vector (-3900.0, -3000.0, 0.0), ' ', Vector (4100.0, -3000.0000000000005, 0.0))
DraftGeomUtils: unable to bind wires
Error: Invalid base object
Proposed PR - DraftGeomUtils.py / OffsetWire()

Code: Select all

...
    ## Added
    e = edges[0]
    if isinstance(e.Curve,Part.Circle):
        firstVec = e.tangentAt(e.FirstParameter)
    else:
        firstVec = vec(e)
    ## Added

    for i in range(len(edges)):
        curredge = edges[i]
        delta = dvec
        if i != 0:
            if isinstance(curredge.Curve,Part.Circle):
                v = curredge.tangentAt(curredge.FirstParameter)
            else:
                v = vec(curredge)

            ## Revised
            #angle = DraftVecUtils.angle(vec(edges[0]),v,norm)
            angle = DraftVecUtils.angle(firstVec,v,norm)
...            
Any volunteers want to test?
Thanks.
Screenshot from 2019-02-28 01-17-32.png
Screenshot from 2019-02-28 01-17-32.png (216.56 KiB) Viewed 404 times
Screenshot from 2019-02-28 01-18-57.png
Screenshot from 2019-02-28 01-18-57.png (268.15 KiB) Viewed 404 times
Attachments
DraftGeomUtils.py
(109.33 KiB) Downloaded 13 times
paullee
Posts: 2753
Joined: Wed May 04, 2016 3:58 pm

Re: [PR - Bug Fix] ArchWall / DraftGeomUtils - offsetWire(), connect(), precision()

Postby paullee » Sun Mar 17, 2019 6:42 pm

Found another associated problem I made:-

I thought I need to set in Preference-Draft-Precision as high as possible to make the model internal data precise.

I find I had set it to '15' that findIntersection() would never consider some endpoints coincident (e.g. below with an arc and a line)

line + arc = find intersection
line : points
Vector (92446.00747599997, -76158.581203, 0.0)
Vector (42776.221810180155, -76158.581203, 0.0)

arc : points
Vector (33058.17102197231, -69707.58666665564, 0.0)
Vector (42776.221810180155, -76158.58120299998, 0.0)

intersections = DraftGeomUtils.findIntersection(edge1, edge2, True,True)
[]

Proposal : Cap the precision level so that findIntersection() works. Revised DraftGeomutils.py attached.

Making a PR for ease of review :)
Attachments
DraftGeomUtils.py
(109.88 KiB) Downloaded 12 times