Logo Search packages:      
Sourcecode: varkon version File versions  Download package

sur164.c

/********************************************************************/
/*                                                                  */
/*  This file is part of the VARKON Geometry Library.               */
/*  URL:  http://www.varkon.com                                     */
/*                                                                  */
/*  This library is free software; you can redistribute it and/or   */
/*  modify it under the terms of the GNU Library General Public     */
/*  License as published by the Free Software Foundation; either    */
/*  version 2 of the License, or (at your option) any later         */
/*  version.                                                        */
/*                                                                  */
/*  This library is distributed in the hope that it will be         */
/*  useful, but WITHOUT ANY WARRANTY; without even the implied      */
/*  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR         */
/*  PURPOSE.  See the GNU Library General Public License for more   */
/*  details.                                                        */
/*                                                                  */
/*  You should have received a copy of the GNU Library General      */
/*  Public License along with this library; if not, write to the    */
/*  Free Software Foundation, Inc., 675 Mass Ave, Cambridge,        */
/*  MA 02139, USA.                                                  */
/*                                                                  */
/*  (C)Microform AB 1984-1999, Gunnar Liden, gunnar@microform.se    */
/*                                                                  */
/********************************************************************/

#include "../../DB/include/DB.h"
#include "../include/GE.h"

/********************************************************************/
/*!                                                                 */
/*  Function: varkon_sur_curint                    File: sur164.c   */
/*  =============================================================   */
/*                                                                  */
/*  Purpose                                                         */
/*  -------                                                         */
/*                                                                  */
/*  The function calculates the intersect between a curve           */
/*  and a surface.                                                  */
/*                                                                  */
/*  Input is a surface, a curve and the requested solution number.  */
/*  Optionally may a start u,v point be input. In this case will    */
/*  the function first try to find the solution in the patch of     */
/*  the start UV point. If there is no solution then will the       */
/*  function try to find solutions in the surrounding patches.      */
/*  The input parameter (acc) defines the UV search area.           */
/*                                                                  */
/*  The UV search area will be the whole surface if no start        */
/*  UV point is defined. Note that this normally is a very          */
/*  heavy calculation !                                             */
/*                                                                  */
/*  Output is the intersect point for the requested solution number */
/*  The points will be ordered either according to R*3 distance     */
/*  to the given external R*3 point or in the u,v plane to the      */
/*  given U,V start point (if there is no start u,v point given     */
/*  will U= 1.0 and V= 1.0 be used).                                */
/*                                                                  */
/*  Note that this function not will end with an error if the       */
/*  requested solution number not exists and ocase > 1000.          */
/*  The output U,V point will only be (-1.0,-1.0) in this case.     */
/*  This is unlike all other geometry functions in surpac & geopac! */
/*  The reason for this option is that the surface/line intersect   */
/*  computation is so heavy. Using the MBS function N_INTERSECT     */
/*  first and then calculate the intersect if the solution exists   */
/*  is much too time-consuming.                                     */
/*                                                                  */
/*  Output from the function is also an array with all solutions.   */
/*  The solutions are ordered and there is also an option to        */
/*  select wanted solutions. For "ray-tracing" calculations are     */
/*  often only solutions in one shooting direction from the given   */
/*  point of interest. For rays which shall bounce on a surface is  */
/*  the surface normal direction of interest. A normal case is that */
/*  rays only shall bounce if the surface normal is in the same (or */
/*  opposite) direction of the shooting direction.                  */
/*                                                                  */
/*  TODO                                                            */
/*  ...  Extend curve ends                 !!!!!!                   */
/*       Facets not close to surface        !!!                     */
/*                                                                  */
/*                                                                  */
/* sur178 UV values must be mapped for NURBS !!!!!!                 */
/*                                                                  */
/*                                                                  */
/*  Author:   Gunnar Liden                                          */
/*                                                                  */
/*  Revisions                                                       */
/*                                                                  */
/*  1996-02-04   Originally written                                 */
/*  1996-06-13   Trimming                                           */
/*  1996-08-19   ocase > 1000 for N_INTERSECT                       */
/*  1996-10-11   Array size t_all, ... 4*INTMAX                     */
/*  1997-02-09   Elimination of compiler warnings                   */
/*  1998-02-09   Started to add NURBS ... probably finished ??      */
/*  1998-03-21   Dynamic allocation of PBOUND in sur919             */
/*  1999-11-28   Free source code modifications                     */
/*                                                                  */
/******************************************************************!*/


/* ------------- Short description of function -----------------*/
/*                                                              */
/*sdescr varkon_sur_curint     Intersect curve and surface      */
/*                                                              */
/*------------------------------------------------------------- */

/*!-------------- Function calls (external) ------------------------*/
/*                                                                  */
/* varkon_ini_aplane       * Initialize APLANE                      */
/* varkon_comptol          * Retrieve computer tolerance            */
/* varkon_ctol             * Coordinate tolerance                   */
/* varkon_ntol             * Surface normal tolerance               */
/* varkon_idpoint          * Identical points criterion             */
/* varkon_idangle          * Identical angles criterion             */
/* varkon_sur_nopatch      * Retrieve number of patches             */
/* varkon_ini_pbound       * Initialize PBOUND                      */
/* varkon_sur_selpatseg    * Select patches                         */
/* varkon_sur_aplane       * Approximate surface w APLANE           */
/* varkon_bpl_extend       * Extrapolate a B-plane                  */
/* varkon_cur_intbplan     * Intersect curve/B-plane                */
/* varkon_bpl_barycen      * Barycentric coordinates                */
/* varkon_pat_segint       * Segment/patch intersect                */
/* varkon_cur_order_2      * Ordering of U values                   */
/* varkon_sur_uvmap        * Map UV point                           */
/* varkon_sur_uvmapr       * Map UV pt from NURBS to MBS            */
/* v3free                  * Free allocated memory                  */
/* varkon_erinit           * Initialize error message stack         */
/* varkon_erpush           * Error message to terminal              */
/*                                                                  */
/*-----------------------------------------------------------------!*/

/*!------------ Error messages and warnings ------------------------*/
/*                                                                  */
/* SU2613 = Requested solution no .. does not exist                 */
/* SU2623 = Requested solution number .. is not between 1 and SMAX  */
/* SU2943 = Called function .. failed in varkon_sur_curint          */
/* SU2813 = Start point u , v outside surface  varkon_sur_curint    */
/* SU2633 = Ordering case .. not implemented   varkon_sur_curint    */
/* SU2343 = Solution selection case .. not implemented              */
/* SU2993 = Severe program error ( ) in varkon_sur_curint           */
/*                                                                  */
/*-----------------------------------------------------------------!*/


/*!****************** Function **************************************/
/*                                                                  */
     DBstatus    varkon_sur_curint (

/*-------------- Argument declarations -----------------------------*/
/*                                                                  */
/* In:                                                              */
  DBSurf   *p_sur,       /* Surface                           (ptr) */
  DBPatch  *p_pat,       /* Alloc. area for topol. patch data (ptr) */
  DBCurve  *p_cur,       /* Curve                             (ptr) */
  DBSeg    *p_seg,       /* Curve segment data                (ptr) */
  DBVector *p_s_uvpt,    /* Start U,V point                   (ptr) */
                         /* p_s_uvpt.z_gm < 0: Not defined.         */
  DBint     ocase,       /* Point ordering case                     */
                         /* Eq. 1: Ordered according to R*3 distance*/
                         /* Eq. 2: Ordered according to UV  distance*/
                         /* (No error exit if 1000 is added)        */
  DBint     acc,         /* Computation accuracy (case)             */
                         /* Undefined p_s_uvpt => all surf. patches */
                         /* Defined   p_s_uvpt => One patch  search */
                         /* Eq. 1: All patches connect. to p_s_uvpt */
                         /* Defined p_s_uvpt => Nine patches search */
                         /* Eq. 2: Next layer of patches ...        */
  DBint     sol_no,      /* Requested solution number               */

/* Out:                                                             */
  DBint    *p_no_points, /* Total number of solution points   (ptr) */
  DBVector *p_cpt,       /* Intersect point in R*3 space      (ptr) */
  DBVector *p_cuvpt,     /* Intersect point in U,V space      (ptr) */
  DBfloat  *p_uvalue,    /* Intersect U curve parameter value (ptr) */
  DBfloat   u_out[],     /* All U   curve   solution pts. Ordered   */
  DBVector  uv_out[],    /* All U,V surface solution pts. Ordered   */
  DBVector  r3_out[] )   /* All R*3 solution pts. Ordered           */
/*                                                                  */
/*-----------------------------------------------------------------!*/

{ /* Start of function */


/*!--------------- Internal variables ------------------------------*/
/*                                                                  */
  PBOUND *p_pbtable;     /* Patch boundary   table PBOUND           */
  PBOUND  pbrec;         /* Patch boundary record for initiation    */
  DBint   bnr;           /* Total number of records      in PBOUND  */

/*                                                                  */
/*-----------------------------------------------------------------!*/

  ISURCUR  curdat;       /* Surface/curve computation data          */
  DBint    rtype;        /* Computation case = SURCUR               */
  DBint    i_r;          /* Loop index record                       */
  DBfloat  comptol;      /* Computer   tolerance                    */
  DBfloat  ntol;         /* Surface normal tolerance                */
  DBfloat  ctol;         /* Coordinate tolerance                    */
  DBfloat  idpoint;      /* Identical point criterion               */
  DBfloat  idangle;      /* Identical angle criterion               */
  DBint    n_u;          /* Number of patches in U direction p_sur  */
  DBint    n_v;          /* Number of patches in V direction p_sur  */
  DBint    surtype;      /* Type CUB_SUR, RAT_SUR, or .....  p_sur  */
  DBfloat  s_lim[2][2];  /* Surface limitation U,V points    p_sur  */
                         /* (0,0): Start U  (0,1): Start V          */
                         /* (1,0): End   U  (1,1): End   V          */
  APLANE   asur[PLMAX];  /* Surface approximation table             */
  DBint    nasur;        /* Total number of records in asur         */
  APLANE   plrec;        /* Approximative patch to input surface    */
  DBint    sur_no;       /* Current surface for approximation       */
  DBint    i_fac;        /* Loop index facet in surface             */
  DBBplane sur_bpl;      /* B_PLANE (facet) from  surface           */
  DBint    nfac;         /* Number of intersect points in a facet   */
  DBfloat  u_fac[INTMAX];/* Ordered array of u solutions 1,., nint  */
  DBVector r_fac[INTMAX];/* Ordered array of R*3 solutions 1, nint  */
  DBint    n_all;        /* No of all approxim. solutions           */
  DBfloat  t_all[4*INTMAX];/* All approx. (not ordered) crv solut's */
  DBfloat  u_all[4*INTMAX];/* All approx. surface (U)       solut's */
  DBfloat  v_all[4*INTMAX];/* All approx. surface (V)       soluti' */
  DBint    i_sol;        /* Loop index solution point               */
  DBVector poi_fac;      /* Intersect point in B-plane              */
  DBfloat  alpha;        /* Barycentric coordinate for p1           */
  DBfloat  beta;         /* Barycentric coordinate for p2           */
  DBfloat  gamma;        /* Barycentric coordinate for p4           */
  EVALS    xyz_ps[SMAX]; /* All patch/segment     points Surface    */
  EVALC    xyz_psc[SMAX];/* All patch/segment     points Curve      */
  DBint    n_pspts;      /* Number of patch/segment points          */
  EVALS    xyz_in[SMAX]; /* All input  (solution) points Surface    */
  EVALC    xyz_inc[SMAX];/* All input  (solution) points Curve      */
  DBint    n_inpts;      /* Number of input  points                 */
  DBint    ocase_l;      /* Ordering case                           */
  DBVector refpt;        /* Comparison point (R*3 or U)             */
  EVALS    xyz_out[SMAX];/* All output (solution) points Surface    */
  EVALC    xyz_outc[SMAX];/* All output (solution) points Curve     */
  DBint    ord_outc[SMAX];/* The order of the output points         */
  DBint    n_outpts;     /* Number of output points                 */
  DBint    i_add;        /* Loop index additional intersect point   */
  DBint    i_s;          /* Loop index solution point               */
  DBfloat  u_mbs;        /* MBS    U parameter value                */
  DBfloat  v_mbs;        /* MBS    V parameter value                */
  DBfloat  u_map;        /* Mapped U parameter value                */
  DBfloat  v_map;        /* Mapped V parameter value                */
  DBfloat  u_nurb;       /* Global (NURBS) U parameter value        */
  DBfloat  v_nurb;       /* Global (NURBS) V parameter value        */
  DBint    status;       /* Error code from called function         */
  char     errbuf[80];   /* String for error message fctn erpush    */


#ifdef TILLFALLIG_TEST
   char   *p_gpat;       /* Allocated area geom.  patch data  (ptr) */
#endif



/*!-------------------- Flow chart ---------------------------------*/
/*                ______________________                            */
/*               !                      !                           */
/*               ! varkon_sur_curint    !                           */
/*               !      (sur164)        !                           */
/*               !______________________!                           */
/*       ___________________!_______________________________        */
/*  ____!_____         ______!______     _____!_____   _____!_____  */
/* !    1     !  2    !      3      !   !     4     ! !     5     ! */
/* !  Check   !       ! Computation !   ! Calculate ! ! Order and ! */
/* !  input,  !       !     data    !   !    all    ! !  delete   ! */
/* ! initiate !       !             !   !   points  ! ! equal pts ! */
/* !__________!       !_____________!   !___________! !___________! */
/*      !________                              !             !      */
/*  ____!___  ___!____                     ____!___      ____!___   */
/* !        !!        !                   !        !    !        !  */
/* ! varkon !! varkon !                   ! varkon !    ! varkon !  */
/* ! _ctol  !!        !                   !        !    !        !  */
/* ! _ntol  !!        !                   !        !    !        !  */
/* ! sur752 !!        !                   !        !    !        !  */
/* ! sur751 !!        !                   !        !    !        !  */
/* !________!!________!                   !________!    !________!  */
/*                                                                  */
/*-----------------------------------------------------------------!*/

/*--------------end-of-declarations---------------------------------*/

/*!New-Page--------------------------------------------------------!*/
/*!                                                                !*/

/*!                                                                 */
/* Algorithm                                                        */
/* =========                                                        */
/*                                                                 !*/

/*!                                                                 */
/* 1. Check of input data and initiations                           */
/* ______________________________________                           */
/*                                                                  */
/*                                                                 !*/

#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
  {
  fprintf(dbgfil(SURPAC),
  "sur164 Enter***varkon_sur_curint   ** \n");
  }
if ( dbglev(SURPAC) == 1 )
  {
  fprintf(dbgfil(SURPAC),
  "sur164 ocase %d\n",(int)ocase );
  fflush(dbgfil(SURPAC));
  }
#endif
 
#ifdef TILLFALLIG_TEST
if ((p_gpat=DBcreate_patches(CON_PAT,1)) ==NULL)
 { 
 sprintf(errbuf,
 "(allocg)%%varkon_nmgconsurf (sur204");
 return(varkon_erpush("SU2993",errbuf));
 }                                 
#endif

#ifdef DEBUG
   bnr     = I_UNDEF;
   nfac    = I_UNDEF;
   nasur   = I_UNDEF;
   n_inpts = I_UNDEF;
   u_mbs   = F_UNDEF;
   v_mbs   = F_UNDEF;
   u_map   = F_UNDEF;
   v_map   = F_UNDEF;
   u_nurb  = F_UNDEF;
   v_nurb  = F_UNDEF;
#endif


   rtype= SURCUR;  

/* Initialize patch boundary table pointer                          */
   p_pbtable = NULL;

/*!                                                                 */
/* Surface normal tolerance and coordinate tolerance.               */
/* Call of varkon_ntol (sur752) and varkon_ctol (sur751).           */
/*                                                                 !*/

   comptol   = varkon_comptol();
   ntol      = varkon_ntol();
   ctol      = varkon_ctol();
   idpoint   = varkon_idpoint();
   idangle   = varkon_idangle();


   for (i_s=1; i_s<=SMAX;     i_s= i_s+1) /* Initialize UV  solutions*/
     { 
     u_out [i_s-1]      = F_UNDEF;          
     uv_out[i_s-1].x_gm = F_UNDEF;          
     uv_out[i_s-1].y_gm = F_UNDEF;          
     uv_out[i_s-1].z_gm = F_UNDEF;           
     r3_out[i_s-1].x_gm = F_UNDEF;          
     r3_out[i_s-1].y_gm = F_UNDEF;          
     r3_out[i_s-1].z_gm = F_UNDEF;           
     }

   for ( i_sol = 1; i_sol <= 4*INTMAX; i_sol++ )
      {
      t_all[i_sol-1] = F_UNDEF;             
      u_all[i_sol-1] = F_UNDEF;             
      v_all[i_sol-1] = F_UNDEF;             
      }

   *p_uvalue = F_UNDEF;   


/*!                                                                 */
/* Partial check of p_s_uvpt (if < 1 )                              */
/*                                                                  */
/*                                                                 !*/

if ( p_s_uvpt->z_gm >= 0 )
{
  if ( p_s_uvpt->x_gm < 1.0 || p_s_uvpt->y_gm < 1 )
     {
#ifdef DEBUG
     if ( dbglev(SURPAC) == 1 )
       {
       fprintf(dbgfil(SURPAC),
       "sur164 Error start UV point %f %f is defined (z_gm= %f)\n",
            p_s_uvpt->x_gm,p_s_uvpt->y_gm,p_s_uvpt->z_gm);
       fflush(dbgfil(SURPAC));
       }
#endif
     sprintf(errbuf,"%6.2f %6.2f %%varkon_sur_curint   ", 
            p_s_uvpt->x_gm,p_s_uvpt->y_gm);
     varkon_erinit();
     return(varkon_erpush("SU2813",errbuf));
     }
} 

/* Map the UV start pt if defined. Call varkon_sur_uvmap (sur360)   */
/*   ..... p_s_uvpt seem not to be used ??? !!! 1998-02-08          */


   if  (   p_s_uvpt->z_gm >= 0.0 )
     {
     u_mbs = p_s_uvpt->x_gm - 1.0;   
     v_mbs = p_s_uvpt->y_gm - 1.0;   

      status=varkon_sur_uvmap
    (p_sur,p_pat,u_mbs, v_mbs, &u_map, &v_map);
    if (status<0) 
      {
      sprintf(errbuf,"sur360%%sur164");
      return(erpush("SU2943",errbuf));
        }
     }
   else
     {
     u_map = p_s_uvpt->x_gm;   
     v_map = p_s_uvpt->y_gm;   
     }


   if ( sol_no >= 1 && sol_no <= SMAX )
      {
      /* OK */
      }
   else
     {
     sprintf(errbuf,"%d %% %d varkon_sur_curint   ", (int)sol_no , SMAX );
       varkon_erinit();
      return(varkon_erpush("SU2623",errbuf));
     }

   if      ( ocase ==    1 || ocase ==    2 )
      ocase_l = ocase;
   else if ( ocase == 1001 || ocase == 1002 )
      ocase_l = ocase - 1000;
   else
     {
     sprintf(errbuf,"%d %%varkon_sur_curint   ", (int)ocase );
       varkon_erinit();
      return(varkon_erpush("SU2633",errbuf));
     }


/*!                                                                 */
/* Initialize table APLANE                                          */
/* Calls of varkon_ini_aplane (sur760).                             */
/*                                                                 !*/

   for (i_r=1; i_r<=PLMAX; i_r= i_r+1)
     {                               
     varkon_ini_aplane (&plrec);
     asur[i_r-1] = plrec;
     }

/*!                                                                 */
/* Retrieve number of patches and surface types.                    */
/* Calls of varkon_sur_nopatch (sur230).                            */
/* Check that the surfaces are of an acceptable type                */
/*                                                                 !*/

    status = varkon_sur_nopatch
    (p_sur, &n_u, &n_v, &surtype);
#ifdef DEBUG
    if(status<0)
    {
    sprintf(errbuf,"varkon_sur_nopatch%% sur164");
    return(varkon_erpush("SU2943",errbuf));
    }
#endif


if ( surtype     ==   CUB_SUR ||
     surtype     ==   RAT_SUR ||
     surtype     ==   MIX_SUR ||
     surtype     ==   CON_SUR ||
     surtype     ==  NURB_SUR ||
     surtype     ==   LFT_SUR )
 ;
 else
 {
 sprintf(errbuf, "(surface type)%% sur164"); 
 return(varkon_erpush("SU2993",errbuf));
 }




/*!                                                                 */
/* 2  Computation data                                              */
/* ____________________                                             */
/*                                                                  */
/*                                                                 !*/


/*!                                                                 */
/* Define tolerances, methods, etc for the intersect calculation.   */
/*                                                                 !*/

curdat.ctype    = rtype;          /* Type of calculation            */
curdat.method   = NEWTON;         /* Method to be used              */
curdat.nstart   = 10;             /* Number of restarts             */
curdat.maxiter  = 20;             /* Maximum number of restarts     */
curdat.s_method = 1;              /* Select/search method           */
                                  /* Eq. 1: BBOX'es only            */

/* Get sysyem tolerances      !!!!!! */

curdat.ctol     = ctol;           /* Coordinate     tolerance       */
curdat.ntol     = ntol;           /* Surface normal tolerance       */
curdat.idpoint  = idpoint;        /* Identical point criterion      */
curdat.idangle  = idangle;        /* Identical angle criterion      */
curdat.comptol  = comptol;        /* Computer accuracy tolerance    */
curdat.factol   = 0.500;          /* Facets (B-planes) tolerance    */
curdat.d_che    = 20.0;           /* Maximum check R*3 distance     */

                                  /* Density of the UV net:         */
curdat.u_add   =  5;              /* For surface 1 in U direction   */
curdat.v_add   =  5;              /* For surface 1 in V direction   */
                                  /* (Values 1, 2, 3, 4, .... )     */

                                  /* Patch limit pts (search area): */
curdat.us       = F_UNDEF;        /* U start surface                */
curdat.vs       = F_UNDEF;        /* V start surface                */
curdat.ue       = F_UNDEF;        /* U end   surface                */
curdat.ve       = F_UNDEF;        /* V end   surface                */

                                  /* Segment limits  (search area): */
curdat.usc      = F_UNDEF;        /* U start for curve              */
curdat.uec      = F_UNDEF;        /* U end   for curve              */

curdat.startuvpt.x_gm = F_UNDEF;  /* Start U,V point surface        */
curdat.startuvpt.y_gm = F_UNDEF; 
curdat.startuvpt.z_gm = F_UNDEF; 
curdat.startupt.x_gm  = F_UNDEF;  /* Start U   point curve          */
curdat.startupt.y_gm  = F_UNDEF; 
curdat.startupt.z_gm  = F_UNDEF; 


/*!                                                                 */
/* 3. Find the parts of the surface which may intersect the curve   */
/* ______________________________________________________________   */
/*                                                                  */
/* Select patches (boxes) which intersect the curve                 */
/* Call of varkon_sur_selpatseg (sur919).                           */
/*                                                                 !*/

s_lim[0][0] = 1.0;
s_lim[0][1] = 1.0;
s_lim[1][0] = (DBfloat)n_u;
s_lim[1][1] = (DBfloat)n_v;

    status = varkon_sur_selpatseg
(p_sur,p_pat,surtype, n_u, n_v, s_lim, 
 p_cur,p_seg,(IRUNON*)&curdat,&p_pbtable, &bnr );
if (status<0) 
  {
  if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
  sprintf(errbuf,"sur919%%sur164");
  return(varkon_erpush("SU2943",errbuf));
  }

  if (  bnr  == 0 )
    {
#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
{
fprintf(dbgfil(SURPAC),
"sur164 Curve does not intersect the (approximative BBOX) surface \n") ;
fflush(dbgfil(SURPAC));
}
#endif
    n_outpts  = 0;
    goto no_solut;
    }

#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
{
fprintf(dbgfil(SURPAC),
"sur164 Curve intersect %d patches (BBOXES) \n", (int)bnr) ;
fflush(dbgfil(SURPAC));
}
#endif

/*!                                                                 */
/* 4. Approximate the selected patches with triangular planes.      */
/* __________________________________________________________       */
/*                                                                  */
/*                                                                 !*/

sur_no = 1;
status=varkon_sur_aplane 
     (p_sur ,p_pat , p_pbtable, bnr, sur_no, asur , &nasur  );
   if (status<0) 
        {
        if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
        sprintf(errbuf,"sur178%%sur164 ");
        return(varkon_erpush("SU2943",errbuf));
        }

#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
{
fprintf(dbgfil(SURPAC),
"sur164 The surface is approximated with %d facets (triangular B-planes)\n", 
           (int)nasur ) ;
 fflush(dbgfil(SURPAC));
}
#endif

/*!                                                                 */
/* 5. Calculate approximative intersect points                      */
/* ____________________________________________                     */
/*                                                                  */
/*                                                                 !*/

  n_all = 0;

/*!                                                                 */
/* Loop all patches in surface   i_fac =1,2,...., nasur             */
/*                                                                 !*/

for (i_fac =1; i_fac <= nasur ;  ++i_fac ) /* Start loop facets     */
  {

/*!                                                                 */
/*   Get B-plane (facet) i_fac from table asur (approx. surface)    */
/*   Extrapolate plane with distance idpoint and calculate          */
/*   intersect between the (extended) plane and the curve.          */
/*   Call of varkon_bpl_extend  and varkon_cur_intbplan             */
/*   !!! Extend ska flyttas till sur721 !!!!!                       */
/*   !!! Kanske ändå inte. Planen måste göras överlappande till     */
/*   !!! omkringliggande patches för att inte missa skärningar      */
/*   !!! som ligger nära patch kanter                               */
/*   !!! Alternativt, när approximativ skärning inte finns, kan     */
/*   !!! man söka skärning med alla patchar (PBOUND) och då         */
/*   !!! utan start punkt i U,V patchen 1996-02-04                  */
/*                                                                 !*/

     sur_bpl = asur[i_fac-1].bpl; 

     status = varkon_bpl_extend 
     ( &sur_bpl , 100*idpoint, &sur_bpl ); 
     if(status<0)
     {
     if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
     sprintf(errbuf,"sur719%%sur164");
     return(varkon_erpush("SU2943",errbuf));
    }

     status = varkon_cur_intbplan
     (p_cur,p_seg,&sur_bpl , &nfac ,u_fac, r_fac );
#ifdef DEBUG
     if(status<0)
     {
     if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
     sprintf(errbuf,"sur721%%sur164");
     return(varkon_erpush("SU2943",errbuf));
    }
#endif

/*!                                                                 */
/*    Add global U values to arrays t_all, u_all, v_all and         */
/*    increase the total number of intersect points n_all.          */
/*                                                                 !*/

      if ( n_all + nfac > 4*INTMAX )
        {
        if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
{
fprintf(dbgfil(SURPAC),
"sur164 Error n_all %d + nfac %d > 4*INTMAX %d\n",(int)n_all,(int)nfac,4*INTMAX) ;
}
#endif
        sprintf(errbuf,"Increase 4*INTMAX%%sur164");
        return(varkon_erpush("SU2993",errbuf));
        }

      for ( i_sol = n_all; i_sol <= n_all+nfac-1; i_sol++ )
          {
          t_all[i_sol] = u_fac[i_sol-n_all];
          /* Interpolate with Barycentric coordinates for U,V in surface */
          poi_fac = r_fac[i_sol-n_all];
          status=varkon_bpl_barycen
         ( &sur_bpl, &poi_fac , &alpha, &beta, &gamma );
         if ( status < 0  )
           {
           if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
           sprintf(errbuf,"sur676%%sur164");
           return(varkon_erpush("SU2943",errbuf));
           }
          else
           {
           u_all[i_sol] = 
           alpha*asur[i_fac-1].u1bpl+ 
           beta *asur[i_fac-1].u2bpl+ 
           gamma*asur[i_fac-1].u4bpl; 
           v_all[i_sol] = 
           alpha*asur[i_fac-1].v1bpl+ 
           beta *asur[i_fac-1].v2bpl+ 
           gamma*asur[i_fac-1].v4bpl; 
          }
        
    }  /*  End loop solution points    */

      n_all = n_all + nfac;  /* Add solutions for current facet */

  }  /*  End loop facets    */

  if ( n_all == 0 )
    {
#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
{
fprintf(dbgfil(SURPAC),
"sur164 Curve does not intersect the (approximative facet) surface \n") ;
}
#endif
    n_outpts  = 0;
    goto no_solut;
    }

#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
{
fprintf(dbgfil(SURPAC),
"sur164 There are %d approximative curve/facet surface intersect points\n", 
                (int)n_all ) ;
}
if ( dbglev(SURPAC) == 1 )
{
for ( i_sol = 1; i_sol <= n_all;  i_sol++ )
{
fprintf(dbgfil(SURPAC),
"sur164 Pt i_sol %d n_all %d u_sol %7.3f v_sol %7.3f t_sol %7.3f\n", 
 (int)i_sol, (int)n_all, u_all[i_sol-1], v_all[i_sol-1], t_all[i_sol-1] );
if  ( i_sol == 1 ) /* No r_fac_all !!! */
{
fprintf(dbgfil(SURPAC),
"sur164 Pt i_sol %d n_all %d r_fac %15.8f %15.8f %15.8f\n", 
 (int)i_sol, (int)n_all, r_fac[i_sol-1].x_gm, r_fac[i_sol-1].y_gm, r_fac[i_sol-1].z_gm );
}
}
}
#endif

/*!                                                                 */

/*!                                                                 */
/* 6. Calculate the exact solution points                           */
/* ______________________________________                           */
/*                                                                  */
/*                                                                 !*/

/*!                                                                 */
/* Start loop all (approxim.) solutions i_sol= 1, 2, .... n_all     */
/*                                                                 !*/

   n_inpts = 0;          /* Number of input  points                 */

   for ( i_sol = 1; i_sol <= n_all; i_sol++ )
      {
/*!                                                                 */
/*    Current patch, segment and start points to ISURCUR            */
/*                                                                 !*/

      /* Curve segment limitations                                  */
      curdat.usc = floor(t_all[i_sol-1]+comptol);
      curdat.uec = floor(t_all[i_sol-1]+comptol) + 1.0 -comptol;

      /* Surface patch limitations                                  */
      for (i_r=1; i_r<= bnr ; i_r= i_r+1) /* Start loop pbound      */
        {                                 /*                        */
        pbrec = *(p_pbtable+i_r-1);       /* Current record         */
#ifdef DEBUG
if ( dbglev(SURPAC) == 2 )
  {
  fprintf(dbgfil(SURPAC),
  "sur164 Approximate solution point i_sol %d PBOUND record i_r %d\n", 
   (int)i_sol, (int)i_r);
  fprintf(dbgfil(SURPAC),
  "sur164 u_all %f v_all %f t_all %f \n",
   u_all[i_sol-1], v_all[i_sol-1], t_all[i_sol-1] );
  fprintf(dbgfil(SURPAC),
  "sur164 us %f vs %f ue %f ve %f\n",
   pbrec.us, pbrec.ue, pbrec.vs, pbrec.ve );
  }
#endif
        if (u_all[i_sol-1] >= pbrec.us - comptol &&
            u_all[i_sol-1] <= pbrec.ue + comptol &&
            v_all[i_sol-1] >= pbrec.vs - comptol &&
            v_all[i_sol-1] <= pbrec.ve + comptol   )
          {
          /* PBOUND patch found                                     */
          curdat.us = pbrec.us;  
          curdat.ue = pbrec.ue;  
          curdat.vs = pbrec.vs;  
          curdat.ve = pbrec.ve;   
          goto found;
          }
        }                                 /* End   loop pbound      */

#ifdef DEBUG  /* There must be a PBOUND patch  */
        if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
        sprintf(errbuf,"PBOUND not found%%varkon_sur_curint");
        return(varkon_erpush("SU2993",errbuf));
#endif        /* There must be a PBOUND patch  */

found:;

      curdat.startuvpt.x_gm = u_all[i_sol-1];  /* Start pt surface  */
      curdat.startuvpt.y_gm = v_all[i_sol-1]; 
      curdat.startuvpt.z_gm = 0.0;       
      curdat.startupt.x_gm  = t_all[i_sol-1];  /* Start pt curve    */
      curdat.startupt.y_gm  = 0.0;
      curdat.startupt.z_gm  = 0.0;
   
    status = varkon_pat_segint
(p_sur,p_pat,p_cur,p_seg,(IRUNON*)&curdat,&n_pspts,xyz_ps,xyz_psc);
if (status<0) 
  {
  if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
  {
  fprintf(dbgfil(SURPAC),
  "sur164 varkon_pat_seg_int (sur904) failed \n" );
  }
#endif
  sprintf(errbuf,"sur904%%sur164");
  return(varkon_erpush("SU2943",errbuf));
  }

      if  (  n_pspts > 0 )
        {
        for ( i_add = n_inpts; i_add <= n_inpts + n_pspts; i_add++ )
           {
           xyz_in[i_add]  = xyz_ps[i_add-n_inpts];
           xyz_inc[i_add] = xyz_psc[i_add-n_inpts];
           }
        }

      n_inpts = n_inpts + n_pspts; /* Number of input  points       */

#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
  {
  fprintf(dbgfil(SURPAC),
  "sur164 Result i_sol %d n_pspts (sur904) %d n_inpts (total) %d\n", 
        (int)i_sol, (int)n_pspts, (int)n_inpts );
  }
#endif
 

      }  /*  End loop solution points    */
/*!                                                                 */
/* End   loop all (approxim.) solutions i_sol= 1, 2, .... n_all     */
/*                                                                 !*/


/*!                                                                 */
/* Order solution points and delete equal solutions.                */
/* Call of varkon_cur_order (sur983)                                */
/*                                                                 !*/


   if      ( n_inpts  == 0  ) n_outpts = 0;         
   else if ( n_inpts  == 1  ) 
     {
     n_outpts = 1;
     xyz_outc[0] = xyz_inc[0];
     ord_outc[0] = 1;
     xyz_out[0] = xyz_in[0];
     }
   else if ( n_inpts  >  1 )
     {

     refpt.x_gm = 1.0;            
     refpt.y_gm = 0.0;              
     refpt.z_gm = 0.0;

     ocase_l    = 2;

status=varkon_cur_order_2
   (&refpt, xyz_inc, n_inpts , ocase_l, xyz_outc, ord_outc, &n_outpts);
   if (status<0) 
        {
        if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
#ifdef DEBUG
if ( dbglev(SURPAC) == 1 )
  {
  fprintf(dbgfil(SURPAC),
  "sur164 varkon_cur_order (sur983) failed \n" );
  }
#endif
        sprintf(errbuf,"sur983%%sur164");
        return(varkon_erpush("SU2943",errbuf));
        }

     for (i_s=1; i_s<=n_outpts; i_s= i_s+1) /* Reorder xyz_out         */
       { 
       xyz_out[i_s-1] = xyz_in[ord_outc[i_s-1]-1];
       }
     }       /* End n_inpts > 0 */


   *p_no_points= n_outpts;     /* Total number of solution points   */

   for (i_s=1; i_s<=n_outpts; i_s= i_s+1) /* Start loop all solutions*/
     { 
     u_out [i_s-1]      = xyz_outc[i_s-1].t_global;
     uv_out[i_s-1].x_gm = xyz_out [i_s-1].u;
     uv_out[i_s-1].y_gm = xyz_out [i_s-1].v;
     uv_out[i_s-1].z_gm = 0.0;               
     r3_out[i_s-1].x_gm = xyz_out [i_s-1].r_x;
     r3_out[i_s-1].y_gm = xyz_out [i_s-1].r_y;
     r3_out[i_s-1].z_gm = xyz_out [i_s-1].r_z;
     }


/*!                                                                 */
/* Map the UV points (for a NURBS surface).                         */
/* Calls of varkon_sur_uvmapr (sur362).                              */
/*                                                                 !*/


   for (i_s=1; i_s<=n_outpts; i_s= i_s+1) /* Start loop all solutions*/
     { 
     u_nurb = uv_out[i_s-1].x_gm;
     v_nurb = uv_out[i_s-1].y_gm;
       status=varkon_sur_uvmapr
     (p_sur,p_pat,u_nurb, v_nurb, &u_mbs,&v_mbs);
     if (status<0) 
       {
       if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
       sprintf(errbuf,"sur362%%sur164");
       return(erpush("SU2943",errbuf));
         }
       uv_out[i_s-1].x_gm = u_mbs + 1.0;
       uv_out[i_s-1].y_gm = v_mbs + 1.0;
     } /* End loop all solution points */



no_solut:; /* No solution */

   if ( sol_no <= n_outpts ) 
      {
      p_cpt->x_gm   = xyz_out[sol_no-1].r_x;
      p_cpt->y_gm   = xyz_out[sol_no-1].r_y;
      p_cpt->z_gm   = xyz_out[sol_no-1].r_z;

/* 1998-02-08 p_cuvpt->x_gm = xyz_out[sol_no-1].u; */
/* 1998-02-08 p_cuvpt->y_gm = xyz_out[sol_no-1].v; */
      p_cuvpt->x_gm = uv_out[sol_no-1].x_gm;
      p_cuvpt->y_gm = uv_out[sol_no-1].y_gm;
      p_cuvpt->z_gm = 0.0;               
      *p_uvalue     = xyz_outc[sol_no-1].t_global; 
      }
   else
      {
      p_cpt->x_gm   =   1.23456789;         
      p_cpt->y_gm   =   1.23456789;         
      p_cpt->z_gm   =   1.23456789;         

      p_cuvpt->x_gm =  -1.0;                
      p_cuvpt->y_gm =  -1.0;                
      p_cuvpt->z_gm =  -1.0;               
      *p_uvalue     =  -1.0;
      if ( ocase < 1000 )
        {
        if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");
        sprintf(errbuf,"%d %% %d ", (int)sol_no , (int)n_outpts );
       varkon_erinit();
       return(varkon_erpush("SU2283",errbuf));
        }
     } /* End no solution */

/* 6. Exit                                                          */

/*!                                                                 */
/* Free memory for patch boundary table. Call of v3free.            */
/*                                                                 !*/

#ifdef DEBUG
if ( dbglev(SURPAC) == 1 && p_pbtable != NULL )
{
fprintf(dbgfil(SURPAC),
"sur164 PBOUND memory is freed \n");
fflush(dbgfil(SURPAC));
}
#endif

  if ( p_pbtable != NULL ) v3free(p_pbtable, "sur164");


#ifdef DEBUG                             /* Debug printout          */
if ( dbglev(SURPAC) == 1 )
  {
   for (i_s=1; i_s<= *p_no_points; i_s= i_s+1) /* Start loop all solutions*/
     { 
     fprintf(dbgfil(SURPAC),
     "sur164 Solution %d u_out %f uv_out %f %f\n"
    , (int)i_s , u_out[i_s-1], uv_out[i_s-1].x_gm, uv_out[i_s-1].y_gm );
     fprintf(dbgfil(SURPAC),
     "sur164 Solution %d r3_out %f %f %f\n"
    , (int)i_s , r3_out[i_s-1].x_gm, r3_out[i_s-1].y_gm, r3_out[i_s-1].z_gm );
     }
  if ( *p_no_points > 0   )
  {
  fprintf(dbgfil(SURPAC),
  "sur164 Exit varkon_sur_curint     Output U %f UV pt %f %f Total no %d\n"
    ,*p_uvalue, p_cuvpt->x_gm , p_cuvpt->y_gm , (int)*p_no_points  );
  }
  else
  {
  fprintf(dbgfil(SURPAC),
  "sur164 Exit***varkon_sur_curint   ** No solution found (=%d)\n", 
                     (int)*p_no_points);
  }
  fflush(dbgfil(SURPAC)); /* From buffer to file */
  }
#endif


    return(SUCCED);

  } /* End of function */

/*********************************************************/

Generated by  Doxygen 1.6.0   Back to index