[ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by paullee »

Test on Eigenwertnotfound's Gridtest model :

Model file (attached, 1st screencapture)

Test 1 : Used Part.getSortedCluster()
  1. Steps - Run below codes after file opened
  2. Result - 9 shapes created ( 2 'self-intersecting' wires )
    ( 2nd screencapture )
Test 2 : Used Part.Part.sortEdges()
  1. Steps - Codes remark out line 14, un-remark line 15; run revised codes after file opened
  2. Result - 3 shapes created ( 1 'self-intersecting' wire )
    ( 3rd screencapture )

Code: Select all

obj = FreeCAD.ActiveDocument.getObject('Sketch002')
skGeom = obj.GeometryFacadeList
skGeomEdges = []
skPlacement = obj.Placement  # Get Sketch's placement to restore later
basewires = []

for i in skGeom:
   if not i.Construction:
      # support Line, Arc, Circle for Sketch as Base at the moment
      if isinstance(i.Geometry, (Part.LineSegment, Part.Circle, Part.ArcOfCircle)):
         skGeomEdgesI = i.Geometry.toShape()
         skGeomEdges.append(skGeomEdgesI)

for cluster in Part.getSortedClusters(skGeomEdges):
#for cluster in Part.sortEdges(skGeomEdges):
   clusterTransformed = []
   for edge in cluster:
      edge.Placement = edge.Placement.multiply(skPlacement)  ## TODO add attribute to skip Transform...
      clusterTransformed.append(edge)
   # Only use cluster of edges rather than turning into wire
   basewires.append(clusterTransformed)

c = [App.Placement(App.Vector(200.0,0.0,0.0),App.Rotation(App.Vector(0.0,0.0,1.0),0.0))] 

print(basewires)
len(basewires)
for i in range(len(basewires)):
    w=Part.Wire(basewires[i])
    #w.Placement = c[i]
    w.Placement = c[0]
    Part.show(w)

archwall_gridtest.FCStd
(42.81 KiB) Downloaded 16 times
Screenshot from 2023-01-07 18-31-28.png
Screenshot from 2023-01-07 18-31-28.png (162.62 KiB) Viewed 807 times
Screenshot from 2023-01-07 18-27-56.png
Screenshot from 2023-01-07 18-27-56.png (168.21 KiB) Viewed 807 times
Screenshot from 2023-01-07 18-27-07.png
Screenshot from 2023-01-07 18-27-07.png (183.74 KiB) Viewed 807 times
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by paullee »

@Roy_043

Testing draftgeoutils.wires.isReallyClosed(). IMHO wires like below ( now return True ), should not be considered 'Closed', any comments ? :)

Code: Select all

>>> s=Gui.Selection.getSelection()[0]
>>> import draftgeoutils.wires
>>> draftgeoutils.wires.isReallyClosed(s.Shape)
True

Code: Select all

def isReallyClosed(wire):
...

    # If more than 1 edge, further test below
    e1 = wire.Edges[0]
    e2 = wire.Edges[length-1]

    if DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[1].Point):
        if length == 2:
            return DraftVecUtils.equals(e1.Vertexes[1].Point, e2.Vertexes[0].Point)
        else:
            return True

    if DraftVecUtils.equals(e1.Vertexes[1].Point, e2.Vertexes[0].Point):
        if length == 2:
            return DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[1].Point)
        else:
            return True

    if DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[0].Point):
        if length == 2:
            return DraftVecUtils.equals(e1.Vertexes[1].Point, e2.Vertexes[1].Point)
        else:
            return True

    if DraftVecUtils.equals(e1.Vertexes[1].Point, e2.Vertexes[1].Point):
        if length == 2:
            return DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[0].Point)
        else:
            return True


Screenshot from 2023-01-07 21-30-35.png
Screenshot from 2023-01-07 21-30-35.png (157.68 KiB) Viewed 749 times
User avatar
Roy_043
Veteran
Posts: 8450
Joined: Thu Dec 27, 2018 12:28 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by Roy_043 »

draftgeoutils.wires.isReallyClosed() is intended for wires (and sometimes faces). For those objects edges are ordered sequentially (I think...).
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by paullee »

Code: Select all

...
    if DraftVecUtils.equals(e1.Vertexes[1].Point, e2.Vertexes[0].Point):
        if length == 2:
            return DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[1].Point)
        else:
            return True
    if ...
    
But the series of 'if' test seems make test return 'true' even e.g. if the last edges is not 'sequential' right?

So wire like '6' return True, which is not the intention right ?

Thanks.
User avatar
Roy_043
Veteran
Posts: 8450
Joined: Thu Dec 27, 2018 12:28 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by Roy_043 »

If the 6-shape consists of 5 sequential edges, then you indeed get a false positive. We have also seen that an Xed rectangle can produce a single wire, which may also be problematic.
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by paullee »

Thanks. Now the '6' has last edge connected to 2nd vertex of 1st edge, and it return 'True', which is not the intention of isReallyClose().


BTW, what does it means by 'Xed rectangle' ? :roll:
User avatar
Roy_043
Veteran
Posts: 8450
Joined: Thu Dec 27, 2018 12:28 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by Roy_043 »

paullee wrote: Sat Jan 07, 2023 3:17 pm 'Xed rectangle'
A rectangle with 2 diagonals.
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by paullee »

OK thanks. Have an idea how to 'avoid' undesirable edges be 'connected', though a long shot.

Now, it seems isReallyClosed() needs updating, agreed ?


Hope there is further advice on the algorithm behind Part.getSortedCluster, Part.sortEdges() - either one needs to be kept in the ArchWall.py for some reason :)
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by paullee »

And another question - as already added in the isReallyClosed() at the beginning as remarks :)

Code: Select all

def isReallyClosed(wire):
    """Check if a wire is really closed."""
    # TODO yet to find out why not use wire.isClosed() direct,
    # in isReallyClosed(wire)
Or why need this Draft isReallyClosed() if wire.isClosed() exists ? Or this is made before the wire.isClosed() was made ? :roll:
paullee
Veteran
Posts: 5098
Joined: Wed May 04, 2016 3:58 pm

Re: [ ArchWall ] - Part.getSortedCluster, Part.sortEdges(), again

Post by paullee »

Another 'cornercase' ? 4-edges, self-intersecting, '8'-like.

Both considered as 'Closed' ( return True ) by :
- draftgeotuils.wires.isReallyClosed()
- wire.isClose()
:roll:


Test_ isReallClosed_ 01.FCStd
(11.32 KiB) Downloaded 14 times
Screenshot from 2023-01-08 00-05-39.png
Screenshot from 2023-01-08 00-05-39.png (227.02 KiB) Viewed 604 times
Screenshot from 2023-01-08 00-07-42.png
Screenshot from 2023-01-08 00-07-42.png (155.82 KiB) Viewed 604 times
Post Reply