Exemple #1
0
def checkPath(path, loopPointsList, pointXYZ, xyzStart=1):
  '''checks to see if the path intersects any topological loop on the surf'''
  pathThrough = False, False  # return a tuple... false is for failure
  for loopPts in loopPointsList:
    triangles = tstdata.trianglinizeLoop(loopPts)
    numberIntersects = 0
    #do intersection checks... carefully
    for triangle in triangles:
      lastPathPt = path[0][xyzStart:xyzStart + 3]  # init for loop
      for nextPathPtRad in path[1:]:
        nextPathPt = nextPathPtRad[xyzStart:xyzStart+3]
        triPts0 = pointXYZ[triangle[0]-1][1:]
        triPts1 = pointXYZ[triangle[1]-1][1:]
        triPts2 = pointXYZ[triangle[2]-1][1:]
        posPt, maxIt = False, 5000
        while False == posPt:
          posPt = geometry.linePlaneIntersectionNumeric(
              triPts0, triPts1, triPts2, lastPathPt, nextPathPt)
          if False == posPt:
            triPts0, triPts1, triPts2 = geometry.perturbTriangle(
                triPts0, triPts1, triPts2)
            maxIt -= 1
            if maxIt < 0:
              print "had to perturb points 5000 times", triPts0, triPts1,
              print triPts2, lastPathPt, nextPathPt, "giving up"
              sys.exit(1)
        if posPt is not False:
          if geometry.distL2(lastPathPt, nextPathPt) >= \
              geometry.distL2(lastPathPt, posPt) and \
              geometry.distL2(lastPathPt, nextPathPt) >= \
              geometry.distL2(nextPathPt, posPt):
            if geometry.intPointInsideTri(triPts0, triPts1, triPts2, posPt):
              numberIntersects += 1
        lastPathPt = nextPathPt  # for next loop
    #print numberIntersects  # for debugging...
    if 1 == numberIntersects % 2:  # if intersects odd number of times
      pathThrough = triangles, loopPts
      break  # no need to do more checks, one is good enough
  return pathThrough  # in case caller wants to do something with it.
def getIntersectingPts(
    startPt, endPt, longEdge, shortAxis1, shortAxis2, orst, maxIntersect):
  '''helper function that finds the intersecting points on a line,
  knows how to perturb line if intersecting points are odd
  newly added range search tree must be passed in'''
  divideByZeroProblems = False
  try:  # to catch divide by zero issues
    intersectingPts = []
    #intersectingTris = []  # don't need except for debugging
    result = orst.rangeQuery(
        startPt[shortAxis1]-longEdge, startPt[shortAxis1]+longEdge,
        startPt[shortAxis2]-longEdge, startPt[shortAxis2]+longEdge)
    #result[x][3] contains tri tuple indices, if all three there, do...
    checkResults = []
    for resultEntry in result:   # put triangle index into new struct, 3 copies
      for triIndex in resultEntry[3]:   # will be there if whole tri is inside
        checkResults.append(triIndex)
    checkResults.sort(key=operator.itemgetter(10))
    lastPt, ptCount = -1, 0
    for point in checkResults:
      if False == maxIntersect or len(intersectingPts) < maxIntersect:
        if point == lastPt:
          ptCount += 1
        else:
          lastPt, ptCount = point, 1
        if ptCount == 3:
          triTuple = point
          #now check to make sure at least one point of the triangle is on each
          #side of the x/y shortaxis1/2 planes
          short1BelowCt, short1AboveCt, short2BelowCt, short2AboveCt = \
              0, 0, 0, 0
          for pointInTri in triTuple[:3]:
            if pointInTri[shortAxis1] < startPt[shortAxis1]:
              short1BelowCt += 1
            elif pointInTri[shortAxis1] > startPt[shortAxis1]:
              short1AboveCt += 1
            else:  # weird equality case, increment both
              short1BelowCt += 1
              short1AboveCt += 1
            if pointInTri[shortAxis2] < startPt[shortAxis2]:
              short2BelowCt += 1
            elif pointInTri[shortAxis2] > startPt[shortAxis2]:
              short2AboveCt += 1
            else:  # weird equality case, increment both
              short2BelowCt += 1
              short2AboveCt += 1
          #now do check, only do rest if necessary
          if short1BelowCt > 0 and short1AboveCt > 0 and \
             short2BelowCt > 0 and short2AboveCt > 0:
            triPts0 = triTuple[0]
            triPts1 = triTuple[1]
            triPts2 = triTuple[2]
            posPt, maxIt = False, 5000
            while False == posPt:
              posPt = geometry.linePlaneIntersectionNumeric(
                  triPts0, triPts1, triPts2, startPt, endPt)
              if False == posPt:
                triPts0, triPts1, triPts2 = geometry.perturbTriangle(
                    triPts0, triPts1, triPts2)
                maxIt -= 1
                if maxIt < 0:
                  print "perturbed 5000 times", triPts0, triPts1, triPts2,
                  print startPt, endPt, "giving up"
                  sys.exit(1)
            if posPt is not False:
              if geometry.intPointInsideTriTuple(triTuple, posPt):
                intersectingPts.append(posPt)
                #intersectingTris.append([triPts0, triPts1, triPts2])
    #print "inter", len(intersectingPts), len(intersectingTris)
    #tstdebug.debugTris([startPt,endPt],
    #intersectingTris,intersectingPts,"debug."+
    #str(x)+"."+str(y)+"."+str(z)+".line.py")
  except ZeroDivisionError:  # caused by intPt = triangle vertex
    divideByZeroProblems = True
  if divideByZeroProblems or len(intersectingPts) % 2 == 1:
    return False
  else:
    return intersectingPts