parameters: (self, obj, compGeoShp)
return_statement: return ARCS
docstring: pathGeomToCircularPointSet(self, obj, compGeoShp)...
      Convert a compound set of arcs/circles to a set of directionally-oriented arc end points
      and the corresponding center point.
docstring_summary: pathGeomToCircularPointSet(self, obj, compGeoShp)...
      Convert a compound set of arcs/circles to a set of directionally-oriented arc end points
      and the corresponding center point.
docstring_tokens: pathGeomToCircularPointSet ( self obj compGeoShp ) ... Convert a compound set of arcs / circles to a set of directionally - oriented arc end points and the corresponding center point .
function: def pathGeomToCircularPointSet(self, obj, compGeoShp):
      """pathGeomToCircularPointSet(self, obj, compGeoShp)...
      Convert a compound set of arcs/circles to a set of directionally-oriented arc end points
      and the corresponding center point."""
      # Extract intersection line segments for return value as []
      PathLog.debug("pathGeomToCircularPointSet()")
      ARCS = []
      stpOvrEI = []
      segEI = []
      isSame = False
      sameRad = None
      ec = len(compGeoShp.Edges)
  
      def gapDist(sp, ep):
          X = (ep[0] - sp[0]) ** 2
          Y = (ep[1] - sp[1]) ** 2
          return math.sqrt(X + Y)  # the 'z' value is zero in both points
  
      def dist_to_cent(item):
          # Sort incoming arcs by distance to center
          # item: edge type, direction flag, parts tuple
          # parts: start tuple, end tuple, center tuple
          s = item[2][0][0]
          p1 = FreeCAD.Vector(s[0], s[1], 0.0)
          e = item[2][0][2]
          p2 = FreeCAD.Vector(e[0], e[1], 0.0)
          return p1.sub(p2).Length
  
      if obj.CutPatternReversed:
          if self.CutClimb:
              self.CutClimb = False
          else:
              self.CutClimb = True
  
      # Separate arc data into Loops and Arcs
      for ei in range(0, ec):
          edg = compGeoShp.Edges[ei]
          if edg.Closed is True:
              stpOvrEI.append(("L", ei, False))
          else:
              if isSame is False:
                  segEI.append(ei)
                  isSame = True
                  pnt = FreeCAD.Vector(edg.Vertexes[0].X, edg.Vertexes[0].Y, 0.0)
                  sameRad = pnt.sub(self.tmpCOM).Length
              else:
                  # Check if arc is co-radial to current SEGS
                  pnt = FreeCAD.Vector(edg.Vertexes[0].X, edg.Vertexes[0].Y, 0.0)
                  if abs(sameRad - pnt.sub(self.tmpCOM).Length) > 0.00001:
                      isSame = False
  
                  if isSame is True:
                      segEI.append(ei)
                  else:
                      # Move co-radial arc segments
                      stpOvrEI.append(["A", segEI, False])
                      # Start new list of arc segments
                      segEI = [ei]
                      isSame = True
                      pnt = FreeCAD.Vector(edg.Vertexes[0].X, edg.Vertexes[0].Y, 0.0)
                      sameRad = pnt.sub(self.tmpCOM).Length
      # Process trailing `segEI` data, if available
      if isSame is True:
          stpOvrEI.append(["A", segEI, False])
  
      # Identify adjacent arcs with y=0 start/end points that connect
      for so in range(0, len(stpOvrEI)):
          SO = stpOvrEI[so]
          if SO[0] == "A":
              startOnAxis = []
              endOnAxis = []
              EI = SO[1]  # list of corresponding compGeoShp.Edges indexes
  
              # Identify startOnAxis and endOnAxis arcs
              for i in range(0, len(EI)):
                  ei = EI[i]  # edge index
                  E = compGeoShp.Edges[ei]  # edge object
                  if abs(self.tmpCOM.y - E.Vertexes[0].Y) < 0.00001:
                      startOnAxis.append((i, ei, E.Vertexes[0]))
                  elif abs(self.tmpCOM.y - E.Vertexes[1].Y) < 0.00001:
                      endOnAxis.append((i, ei, E.Vertexes[1]))
  
              # Look for connections between startOnAxis and endOnAxis arcs. Consolidate data when connected
              lenSOA = len(startOnAxis)
              lenEOA = len(endOnAxis)
              if lenSOA > 0 and lenEOA > 0:
                  for soa in range(0, lenSOA):
                      (iS, eiS, vS) = startOnAxis[soa]
                      for eoa in range(0, len(endOnAxis)):
                          (iE, eiE, vE) = endOnAxis[eoa]
                          dist = vE.X - vS.X
                          if abs(dist) < 0.00001:  # They connect on axis at same radius
                              SO[2] = (eiE, eiS)
                              break
                          elif dist > 0:
                              break  # stop searching
              # Eif
          # Eif
      # Efor
  
      # Construct arc data tuples for OCL
      dirFlg = 1
      if not self.CutClimb:  # True yields Climb when set to Conventional
          dirFlg = -1
  
      # Declare center point of circle pattern
      cp = (self.tmpCOM.x, self.tmpCOM.y, 0.0)
  
      # Cycle through stepOver data
      for so in range(0, len(stpOvrEI)):
          SO = stpOvrEI[so]
          if SO[0] == "L":  # L = Loop/Ring/Circle
              # PathLog.debug("SO[0] == 'Loop'")
              lei = SO[1]  # loop Edges index
              v1 = compGeoShp.Edges[lei].Vertexes[0]
  
              # space = obj.SampleInterval.Value / 10.0
              # space = 0.000001
              space = (
                  self.toolDiam * 0.005
              )  # If too small, OCL will fail to scan the loop
  
              # p1 = FreeCAD.Vector(v1.X, v1.Y, v1.Z)
              p1 = FreeCAD.Vector(
                  v1.X, v1.Y, 0.0
              )  # z=0.0 for waterline; z=v1.Z for 3D Surface
              rad = p1.sub(self.tmpCOM).Length
              spcRadRatio = space / rad
              if spcRadRatio < 1.0:
                  tolrncAng = math.asin(spcRadRatio)
              else:
                  tolrncAng = 0.99999998 * math.pi
              EX = self.tmpCOM.x + (rad * math.cos(tolrncAng))
              EY = v1.Y - space  # rad * math.sin(tolrncAng)
  
              sp = (v1.X, v1.Y, 0.0)
              ep = (EX, EY, 0.0)
              if dirFlg == 1:
                  arc = (sp, ep, cp)
              else:
                  arc = (
                      ep,
                      sp,
                      cp,
                  )  # OCL.Arc(firstPnt, lastPnt, centerPnt, dir=True(CCW direction))
              ARCS.append(("L", dirFlg, [arc]))
          elif SO[0] == "A":  # A = Arc
              # PathLog.debug("SO[0] == 'Arc'")
              PRTS = []
              EI = SO[1]  # list of corresponding Edges indexes
              CONN = SO[2]  # list of corresponding connected edges tuples (iE, iS)
              chkGap = False
              lst = None
  
              if CONN:  # Connected edges(arcs)
                  (iE, iS) = CONN
                  v1 = compGeoShp.Edges[iE].Vertexes[0]
                  v2 = compGeoShp.Edges[iS].Vertexes[1]
                  sp = (v1.X, v1.Y, 0.0)
                  ep = (v2.X, v2.Y, 0.0)
                  if dirFlg == 1:
                      arc = (sp, ep, cp)
                      lst = ep
                  else:
                      arc = (
                          ep,
                          sp,
                          cp,
                      )  # OCL.Arc(firstPnt, lastPnt, centerPnt, dir=True(CCW direction))
                      lst = sp
                  PRTS.append(arc)
                  # Pop connected edge index values from arc segments index list
                  iEi = EI.index(iE)
                  iSi = EI.index(iS)
                  if iEi > iSi:
                      EI.pop(iEi)
                      EI.pop(iSi)
                  else:
                      EI.pop(iSi)
                      EI.pop(iEi)
                  if len(EI) > 0:
                      PRTS.append("BRK")
                      chkGap = True
              cnt = 0
              for ei in EI:
                  if cnt > 0:
                      PRTS.append("BRK")
                      chkGap = True
                  v1 = compGeoShp.Edges[ei].Vertexes[0]
                  v2 = compGeoShp.Edges[ei].Vertexes[1]
                  sp = (v1.X, v1.Y, 0.0)
                  ep = (v2.X, v2.Y, 0.0)
                  if dirFlg == 1:
                      arc = (sp, ep, cp)
                      if chkGap:
                          gap = abs(
                              self.toolDiam - gapDist(lst, sp)
                          )  # abs(self.toolDiam - lst.sub(sp).Length)
                      lst = ep
                  else:
                      arc = (
                          ep,
                          sp,
                          cp,
                      )  # OCL.Arc(firstPnt, lastPnt, centerPnt, dir=True(CCW direction))
                      if chkGap:
                          gap = abs(
                              self.toolDiam - gapDist(lst, ep)
                          )  # abs(self.toolDiam - lst.sub(ep).Length)
                      lst = sp
                  if chkGap:
                      if gap < obj.GapThreshold.Value:
                          PRTS.pop()  # pop off 'BRK' marker
                          (
                              vA,
                              vB,
                              vC,
                          ) = (
                              PRTS.pop()
                          )  # pop off previous arc segment for combining with current
                          arc = (vA, arc[1], vC)
                          self.closedGap = True
                      else:
                          gap = round(gap, 6)
                          if gap < self.gaps[0]:
                              self.gaps.insert(0, gap)
                              self.gaps.pop()
                  PRTS.append(arc)
                  cnt += 1
  
              if dirFlg == -1:
                  PRTS.reverse()
  
              ARCS.append(("A", dirFlg, PRTS))
          # Eif
          if obj.CutPattern == "CircularZigZag":
              dirFlg = -1 * dirFlg
      # Efor
  
      ARCS.sort(key=dist_to_cent, reverse=obj.CutPatternReversed)
  
      return ARCS
function_tokens: def pathGeomToCircularPointSet ( self , obj , compGeoShp ) : # Extract intersection line segments for return value as [] PathLog . debug ( "pathGeomToCircularPointSet()" ) ARCS = [ ] stpOvrEI = [ ] segEI = [ ] isSame = False sameRad = None ec = len ( compGeoShp . Edges ) def gapDist ( sp , ep ) : X = ( ep [ 0 ] - sp [ 0 ] ) ** 2 Y = ( ep [ 1 ] - sp [ 1 ] ) ** 2 return math . sqrt ( X + Y ) # the 'z' value is zero in both points def dist_to_cent ( item ) : # Sort incoming arcs by distance to center # item: edge type, direction flag, parts tuple # parts: start tuple, end tuple, center tuple s = item [ 2 ] [ 0 ] [ 0 ] p1 = FreeCAD . Vector ( s [ 0 ] , s [ 1 ] , 0.0 ) e = item [ 2 ] [ 0 ] [ 2 ] p2 = FreeCAD . Vector ( e [ 0 ] , e [ 1 ] , 0.0 ) return p1 . sub ( p2 ) . Length if obj . CutPatternReversed : if self . CutClimb : self . CutClimb = False else : self . CutClimb = True # Separate arc data into Loops and Arcs for ei in range ( 0 , ec ) : edg = compGeoShp . Edges [ ei ] if edg . Closed is True : stpOvrEI . append ( ( "L" , ei , False ) ) else : if isSame is False : segEI . append ( ei ) isSame = True pnt = FreeCAD . Vector ( edg . Vertexes [ 0 ] . X , edg . Vertexes [ 0 ] . Y , 0.0 ) sameRad = pnt . sub ( self . tmpCOM ) . Length else : # Check if arc is co-radial to current SEGS pnt = FreeCAD . Vector ( edg . Vertexes [ 0 ] . X , edg . Vertexes [ 0 ] . Y , 0.0 ) if abs ( sameRad - pnt . sub ( self . tmpCOM ) . Length ) > 0.00001 : isSame = False if isSame is True : segEI . append ( ei ) else : # Move co-radial arc segments stpOvrEI . append ( [ "A" , segEI , False ] ) # Start new list of arc segments segEI = [ ei ] isSame = True pnt = FreeCAD . Vector ( edg . Vertexes [ 0 ] . X , edg . Vertexes [ 0 ] . Y , 0.0 ) sameRad = pnt . sub ( self . tmpCOM ) . Length # Process trailing `segEI` data, if available if isSame is True : stpOvrEI . append ( [ "A" , segEI , False ] ) # Identify adjacent arcs with y=0 start/end points that connect for so in range ( 0 , len ( stpOvrEI ) ) : SO = stpOvrEI [ so ] if SO [ 0 ] == "A" : startOnAxis = [ ] endOnAxis = [ ] EI = SO [ 1 ] # list of corresponding compGeoShp.Edges indexes # Identify startOnAxis and endOnAxis arcs for i in range ( 0 , len ( EI ) ) : ei = EI [ i ] # edge index E = compGeoShp . Edges [ ei ] # edge object if abs ( self . tmpCOM . y - E . Vertexes [ 0 ] . Y ) < 0.00001 : startOnAxis . append ( ( i , ei , E . Vertexes [ 0 ] ) ) elif abs ( self . tmpCOM . y - E . Vertexes [ 1 ] . Y ) < 0.00001 : endOnAxis . append ( ( i , ei , E . Vertexes [ 1 ] ) ) # Look for connections between startOnAxis and endOnAxis arcs. Consolidate data when connected lenSOA = len ( startOnAxis ) lenEOA = len ( endOnAxis ) if lenSOA > 0 and lenEOA > 0 : for soa in range ( 0 , lenSOA ) : ( iS , eiS , vS ) = startOnAxis [ soa ] for eoa in range ( 0 , len ( endOnAxis ) ) : ( iE , eiE , vE ) = endOnAxis [ eoa ] dist = vE . X - vS . X if abs ( dist ) < 0.00001 : # They connect on axis at same radius SO [ 2 ] = ( eiE , eiS ) break elif dist > 0 : break # stop searching # Eif # Eif # Efor # Construct arc data tuples for OCL dirFlg = 1 if not self . CutClimb : # True yields Climb when set to Conventional dirFlg = - 1 # Declare center point of circle pattern cp = ( self . tmpCOM . x , self . tmpCOM . y , 0.0 ) # Cycle through stepOver data for so in range ( 0 , len ( stpOvrEI ) ) : SO = stpOvrEI [ so ] if SO [ 0 ] == "L" : # L = Loop/Ring/Circle # PathLog.debug("SO[0] == 'Loop'") lei = SO [ 1 ] # loop Edges index v1 = compGeoShp . Edges [ lei ] . Vertexes [ 0 ] # space = obj.SampleInterval.Value / 10.0 # space = 0.000001 space = ( self . toolDiam * 0.005 ) # If too small, OCL will fail to scan the loop # p1 = FreeCAD.Vector(v1.X, v1.Y, v1.Z) p1 = FreeCAD . Vector ( v1 . X , v1 . Y , 0.0 ) # z=0.0 for waterline; z=v1.Z for 3D Surface rad = p1 . sub ( self . tmpCOM ) . Length spcRadRatio = space / rad if spcRadRatio < 1.0 : tolrncAng = math . asin ( spcRadRatio ) else : tolrncAng = 0.99999998 * math . pi EX = self . tmpCOM . x + ( rad * math . cos ( tolrncAng ) ) EY = v1 . Y - space # rad * math.sin(tolrncAng) sp = ( v1 . X , v1 . Y , 0.0 ) ep = ( EX , EY , 0.0 ) if dirFlg == 1 : arc = ( sp , ep , cp ) else : arc = ( ep , sp , cp , ) # OCL.Arc(firstPnt, lastPnt, centerPnt, dir=True(CCW direction)) ARCS . append ( ( "L" , dirFlg , [ arc ] ) ) elif SO [ 0 ] == "A" : # A = Arc # PathLog.debug("SO[0] == 'Arc'") PRTS = [ ] EI = SO [ 1 ] # list of corresponding Edges indexes CONN = SO [ 2 ] # list of corresponding connected edges tuples (iE, iS) chkGap = False lst = None if CONN : # Connected edges(arcs) ( iE , iS ) = CONN v1 = compGeoShp . Edges [ iE ] . Vertexes [ 0 ] v2 = compGeoShp . Edges [ iS ] . Vertexes [ 1 ] sp = ( v1 . X , v1 . Y , 0.0 ) ep = ( v2 . X , v2 . Y , 0.0 ) if dirFlg == 1 : arc = ( sp , ep , cp ) lst = ep else : arc = ( ep , sp , cp , ) # OCL.Arc(firstPnt, lastPnt, centerPnt, dir=True(CCW direction)) lst = sp PRTS . append ( arc ) # Pop connected edge index values from arc segments index list iEi = EI . index ( iE ) iSi = EI . index ( iS ) if iEi > iSi : EI . pop ( iEi ) EI . pop ( iSi ) else : EI . pop ( iSi ) EI . pop ( iEi ) if len ( EI ) > 0 : PRTS . append ( "BRK" ) chkGap = True cnt = 0 for ei in EI : if cnt > 0 : PRTS . append ( "BRK" ) chkGap = True v1 = compGeoShp . Edges [ ei ] . Vertexes [ 0 ] v2 = compGeoShp . Edges [ ei ] . Vertexes [ 1 ] sp = ( v1 . X , v1 . Y , 0.0 ) ep = ( v2 . X , v2 . Y , 0.0 ) if dirFlg == 1 : arc = ( sp , ep , cp ) if chkGap : gap = abs ( self . toolDiam - gapDist ( lst , sp ) ) # abs(self.toolDiam - lst.sub(sp).Length) lst = ep else : arc = ( ep , sp , cp , ) # OCL.Arc(firstPnt, lastPnt, centerPnt, dir=True(CCW direction)) if chkGap : gap = abs ( self . toolDiam - gapDist ( lst , ep ) ) # abs(self.toolDiam - lst.sub(ep).Length) lst = sp if chkGap : if gap < obj . GapThreshold . Value : PRTS . pop ( ) # pop off 'BRK' marker ( vA , vB , vC , ) = ( PRTS . pop ( ) ) # pop off previous arc segment for combining with current arc = ( vA , arc [ 1 ] , vC ) self . closedGap = True else : gap = round ( gap , 6 ) if gap < self . gaps [ 0 ] : self . gaps . insert ( 0 , gap ) self . gaps . pop ( ) PRTS . append ( arc ) cnt += 1 if dirFlg == - 1 : PRTS . reverse ( ) ARCS . append ( ( "A" , dirFlg , PRTS ) ) # Eif if obj . CutPattern == "CircularZigZag" : dirFlg = - 1 * dirFlg # Efor ARCS . sort ( key = dist_to_cent , reverse = obj . CutPatternReversed ) return ARCS