Example #1
0
real SVertex::GetIsophoteDistance(real isovalue, int maxDistance) const
{
  if (_sourceVertex == NULL && _sourceEdge == NULL)
    return -1; // not handling the case of intersection SVertices yet

  if (!(getNature() & Nature::SILHOUETTE)) // only handle silhouette curves
    return -1;

  Vec3r startPoint = _Point3D;

  set<pair<WFace*,int> > possibleStartEdges;
  real currentNdotV;

  //  if (!(getNature() & Nature::SURFACE_INTERSECTION))
  //    printf("Isophote search Nature: %d\n", getNature());
  if (_sourceVertex != NULL)
    {
      currentNdotV = _sourceVertex->GetSurfaceNdotV();

      //      printf("Starting at vertex with n dot v = %f\n", currentNdotV);

      for(vector<WEdge*>::iterator it = _sourceVertex->GetEdges().begin(); it != _sourceVertex->GetEdges().end(); ++it)
	{
	  WFace * aface = (*it)->GetaFace();
	  WFace * bface = (*it)->GetbFace();
	  if (aface != NULL)
	    possibleStartEdges.insert( pair<WFace*,int>(aface, (aface->GetIndex(_sourceVertex)+1)%3));
	  if (bface != NULL)
	    possibleStartEdges.insert(pair<WFace*,int>(bface, (bface->GetIndex(_sourceVertex)+1)%3));
	}
    }
  else
    {
      currentNdotV = ComputeSurfaceNdotV(_sourceEdge, startPoint);

      WFace * faces[2] = { _sourceEdge->GetaFace(), _sourceEdge->GetbFace() };

      for(int i=0;i<2;i++)
	if (faces[i] != NULL)
	{
	  int v;
	  for(v=0;v<3;v++)
	    if (faces[i]->GetOEdge(v)->GetOwner() == _sourceEdge)
	      break;
	  assert(v<3);
	  
	  possibleStartEdges.insert(pair<WFace*,int>(faces[i], (v+1)%3));
	  possibleStartEdges.insert(pair<WFace*,int>(faces[i], (v+2)%3));
	}
    }

  if (currentNdotV > isovalue)
    return 0;

  if (currentNdotV < -0.001)
    return 0;

  Vec3r currentPoint;
  WEdge * currentEdge = NULL;
  WFace * currentFace = NULL;

  Vec3r lastPoint = startPoint;
  real lastNdotV = currentNdotV;

  for(set<pair<WFace*,int> >::iterator it = possibleStartEdges.begin(); it != possibleStartEdges.end(); ++it)
    {
      WFace * face = (*it).first;
      int e = (*it).second;
      if (AdvanceToEdge( face, startPoint, e, currentPoint))
	{
	  currentNdotV = ComputeSurfaceNdotV(face->GetOEdge(e)->GetOwner(), currentPoint);

	  //	  printf("\tlastNdotV = %f, currentNdotV = %f\n", lastNdotV, currentNdotV);

	  if (currentNdotV < lastNdotV)
	    continue;

	  currentEdge = face->GetOEdge(e)->GetOwner(); 
	  currentFace = face->GetBordingFace(e);

	  assert(GeomUtils::distPointSegment<Vec3r>( currentPoint, currentEdge->GetaVertex()->GetVertex(), currentEdge->GetbVertex()->GetVertex()) < 0.01);
	  break;
	}
    }

  if (currentEdge == NULL)
    return -1;

  // march over the surface
  int numSteps = 0;
  while (currentNdotV < isovalue && currentNdotV > -0.001 && numSteps < 100 && currentFace != NULL && ImageSpaceDistance(startPoint, currentPoint) < maxDistance)
    {
      numSteps ++;
      lastPoint = currentPoint;
      lastNdotV = currentNdotV;

      //      printf("advancing, current NdotV = %f\n", currentNdotV);

      bool result = false;
      int e;
      Vec3r nextPoint;
      for(e=0;e<3;e++)
	{
	  if (currentFace->GetOEdge(e)->GetOwner() == currentEdge)
	    continue;
	  result = AdvanceToEdge(currentFace, currentPoint, e, nextPoint);
	  //	  printf("\t advance result = %s\n", result ? "true" : "false");
	  if (result)
	    break;
	}
      
      assert(result);
      
      currentPoint = nextPoint;
      currentEdge = currentFace->GetOEdge(e)->GetOwner();
      currentNdotV = ComputeSurfaceNdotV(currentEdge, currentPoint);
      currentFace = currentFace->GetBordingFace(e);
    }

  Vec3r endpoint;

  if (currentNdotV > isovalue)
    {
      real t = (isovalue - lastNdotV)/(currentNdotV - lastNdotV);
      endpoint = (1-t) * lastPoint + t * currentPoint;
    }
  else
    if (currentNdotV < -0.001)
      {
	real t = -lastNdotV/(currentNdotV - lastNdotV);  // endpoint is the zero-crossing
	endpoint = (1-t)*lastPoint + t * currentPoint;
      }
    else
      endpoint = currentPoint;

  ViewMap * vm = ViewMap::getInstance();

  vm->addDebugPoint(DebugPoint::ISOPHOTE, endpoint, startPoint);

  real dist = ImageSpaceDistance(startPoint, endpoint);

  //  printf("\t result: dist = %f, lastNdotV = %f, currentNdotV = %f, numSteps = %d, currentFace = %08X\n", dist, lastNdotV, currentNdotV, numSteps, currentFace);

  return dist;
}