void intersectCurveSurf(SplineCurve *cv, SplineSurface *sf,
			 double epsge, 
			 vector<pair<double, Point> >& int_pts,
			 vector<int>& pretopology,
			 vector<pair<pair<double,Point>, 
			 pair<double,Point> > >& int_crvs)
 {
   SISLSurf* sislsf = GoSurf2SISL(*sf, false);
   SISLCurve* sislcv = Curve2SISL(*cv, false);
   int kntrack = 0;
   int trackflag = 0;  // Do not make tracks.
   SISLTrack **track =0;
   int knpt=0, kncrv=0;
   double *par1=0, *par2=0;
   int *pretop = 0;
   SISLIntcurve **vcrv = 0;
   int stat = 0;

   sh1858(sislsf, sislcv, 0.0, epsge, trackflag, &kntrack, &track,
	  &knpt, &par1, &par2, &pretop, &kncrv, &vcrv, &stat);
   ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);

   // Remember intersections points. 
   int ki;
   for (ki=0; ki<knpt; ki++)
     {
       int_pts.push_back(std::make_pair(par2[ki],
					Point(par1[2*ki],par1[2*ki+1])));
       pretopology.insert(pretopology.end(), pretop+4*ki+2, pretop+4*(ki+1));
       pretopology.insert(pretopology.end(), pretop+4*ki, pretop+4*ki+2);
     }

   // Remember intersection curves
   for (ki=0; ki<kncrv; ++ki)
     {
       int nmb_pt = vcrv[ki]->ipoint;
       Point par1 = Point(vcrv[ki]->epar1[0],vcrv[ki]->epar1[1]);
       Point par2 = Point(vcrv[ki]->epar1[2*(nmb_pt-1)],
			  vcrv[ki]->epar1[2*nmb_pt-1]);
       int_crvs.push_back(std::make_pair(std::make_pair(vcrv[ki]->epar2[0], 
							par1),
					 std::make_pair(vcrv[ki]->epar2[nmb_pt-1],
							par2)));
     }

   if (kncrv > 0)
     freeIntcrvlist(vcrv, kncrv);

   if (par1 != NULL) free(par1);
   if (par2 != NULL) free(par2);
   if (sislsf != NULL) freeSurf(sislsf);
   if (sislcv != NULL) freeCurve(sislcv);
   if (pretop != NULL) free(pretop);
 }
void intersectcurves(SplineCurve* cv1, SplineCurve* cv2, double epsge,
		     vector<std::pair<double,double> >& intersections)
  //************************************************************************
  // 
  // Intersect two spline curves. Collect intersection parameters.
  //
  //***********************************************************************
{

  // Make sisl curves and call sisl.
  SISLCurve *pc1 = Curve2SISL(*cv1, false);
  SISLCurve *pc2 = Curve2SISL(*cv2, false);

  int kntrack = 0;
  int trackflag = 0;  // Do not make tracks.
  SISLTrack **track =0;
  int knpt=0, kncrv=0;
  double *par1=0, *par2=0;
  int *pretop = 0;
  SISLIntcurve **intcrvs = 0;
  int stat = 0;
  sh1857(pc1, pc2, 0.0, epsge, trackflag, &kntrack, &track,
	 &knpt, &par1, &par2, &pretop, &kncrv, &intcrvs, &stat);

  ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);


  // Remember intersections points. The intersection curves are
  // skipped.
  int ki;
  for (ki=0; ki<knpt; ki++)
    {
      intersections.push_back(std::make_pair(par1[ki],par2[ki]));
    }

  if (kncrv > 0)
    freeIntcrvlist(intcrvs, kncrv);

  if (par1 != 0) free(par1);
  if (par2 != 0) free(par2);
  if (pretop != 0) free(pretop);
  if (pc1 != 0) freeCurve(pc1);
  if (pc2 != 0) freeCurve(pc2);
}
void intersectCurvePoint(const ParamCurve* crv, Point pnt, double epsge,
			 vector<double>& intersections, 
			 vector<pair<double, double> >& int_crvs)
  //************************************************************************
  // 
  // Intersect a curve with a point
  //
  //***********************************************************************
{
  // First make sure that the curve is a spline curve
    ParamCurve* tmpcrv = const_cast<ParamCurve*>(crv);
    SplineCurve* sc = tmpcrv->geometryCurve();
    if (sc == NULL)
        THROW("ParamCurve doesn't have a spline representation.");
    
  // Make sisl curve and call sisl.
  SISLCurve *pc = Curve2SISL(*sc, false);

  int knpt=0, kncrv=0;
  double *par=0;
  SISLIntcurve **vcrv = 0;
  int stat = 0;
  s1871(pc, pnt.begin(), pnt.size(), epsge, &knpt, &par, &kncrv, &vcrv, &stat);
  ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);


  // Remember intersections points. 
  if (knpt > 0)
    intersections.insert(intersections.end(), par, par+knpt);

  // Remember intersection curves
  for (int ki=0; ki<kncrv; ++ki)
    int_crvs.push_back(std::make_pair(vcrv[ki]->epar1[0], vcrv[ki]->epar1[vcrv[ki]->ipoint-1]));

  if (kncrv > 0)
    freeIntcrvlist(vcrv, kncrv);

  if (par != 0) free(par);
  if (pc) freeCurve(pc);

  delete sc;
}
void intersect2Dcurves(const ParamCurve* cv1, const ParamCurve* cv2, double epsge,
		       vector<pair<double,double> >& intersections,
		       vector<int>& pretopology,
		       vector<pair<pair<double,double>, pair<double,double> > >& int_crvs)
  //************************************************************************
  // 
  // Intersect two 2D spline curves. Collect intersection parameters
  // and pretopology information.
  //
  //***********************************************************************
{

  // First make sure that the curves are spline curves.
    ParamCurve* tmpcv1 = const_cast<ParamCurve*>(cv1);
    ParamCurve* tmpcv2 = const_cast<ParamCurve*>(cv2);
    SplineCurve* sc1 = tmpcv1->geometryCurve();
    SplineCurve* sc2 = tmpcv2->geometryCurve();
    if (sc1 == NULL || sc2 == NULL)
        THROW("ParamCurves doesn't have a spline representation.");

    MESSAGE_IF(cv1->dimension() != 2,
		"Dimension different from 2, pretopology not reliable.");

  // Make sisl curves and call sisl.
  SISLCurve *pc1 = Curve2SISL(*sc1, false);
  SISLCurve *pc2 = Curve2SISL(*sc2, false);

  int kntrack = 0;
  int trackflag = 0;  // Do not make tracks.
  SISLTrack **track =0;
  int knpt=0, kncrv=0;
  double *par1=0, *par2=0;
  int *pretop = 0;
  SISLIntcurve **vcrv = 0;
  int stat = 0;
  sh1857(pc1, pc2, 0.0, epsge, trackflag, &kntrack, &track,
	 &knpt, &par1, &par2, &pretop, &kncrv, &vcrv, &stat);

  ALWAYS_ERROR_IF(stat<0,"Error in intersection, code: " << stat);


  // Remember intersections points. 
  int ki;
  for (ki=0; ki<knpt; ki++)
    {
      intersections.push_back(std::make_pair(par1[ki],par2[ki]));
      pretopology.insert(pretopology.end(), pretop+4*ki, pretop+4*(ki+1));
    }

  // Remember intersection curves
  for (ki=0; ki<kncrv; ++ki)
    int_crvs.push_back(std::make_pair(std::make_pair(vcrv[ki]->epar1[0], vcrv[ki]->epar2[0]), 
				      std::make_pair(vcrv[ki]->epar1[vcrv[ki]->ipoint-1],
						     vcrv[ki]->epar2[vcrv[ki]->ipoint-1])));

  if (kncrv > 0)
    freeIntcrvlist(vcrv, kncrv);

  if (par1 != 0) free(par1);
  if (par2 != 0) free(par2);
  if (pc1 != 0) freeCurve(pc1);
  if (pc2 != 0) freeCurve(pc2);
  if (pretop != 0) free(pretop);

  delete sc1;
  delete sc2;
}