//=========================================================================== // GoTools Core - SINTEF Geometry Tools Core library, version 2.0.1 // // Copyright (C) 2000-2007, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00039 #ifndef M_PI 00040 #define M_PI 3.1415926535897932384626433 00041 #endif 00042 #ifndef M_PI_2 00043 #define M_PI_2 1.57079632679489661923132 00044 #endif 00045 #ifndef DZERO 00046 #define DZERO (double)0.0 00047 #endif 00048 #ifndef PIHALF 00049 #define PIHALF (double)M_PI_2 00050 #endif 00051 #ifndef PI 00052 #define PI (double)M_PI 00053 #endif 00054 #ifndef TRUE 00055 #define TRUE 1 00056 #endif 00057 #ifndef FALSE 00058 #define FALSE 0 00059 #endif 00060 #ifndef SIMPLECASE 00061 #define SIMPLECASE (double)0.75 00062 #endif 00063 #ifndef ROTM 00064 #define ROTM (double)M_SQRT1_2 00065 #endif 00066 00067 #define SISL_NULL 0 00068 #define DOUBLE double 00069 #define INT int 00070 00071 #define VOIDP (void *) 00072 #define CONSTVOIDP (const void *) 00073 00074 #define MAXIMAL_RADIUS_OF_CURVATURE (double)10000.0 00075 #define ANGULAR_TOLERANCE (double)0.01 /* IN RADIANS */ 00076 #define REL_PAR_RES (double)0.000000000001 00077 #define REL_COMP_RES (double)0.000000000000001 00078 #define ONE_THIRD (double)0.333333333333333333333333 00079 #define ONE_FOURTH (double)0.25 00080 00081 #define newarray(a,b) \ 00082 ((a)>(SISL_NULL)?((b*)malloc((size_t)((a)*sizeof(b)))):(SISL_NULL)) 00083 #define new0array(a,b) \ 00084 ((a)>(SISL_NULL)?((b*)calloc((size_t)(a),(size_t)(sizeof(b)))):(SISL_NULL)) 00085 #define increasearray(a,b,c) (c*)realloc(VOIDP(a),(size_t)((b)*sizeof(c))) 00086 #define freearray(a) { (void)free(VOIDP a); a = SISL_NULL; } 00087 #define free0array(a) { (void)free(VOIDP a); a = SISL_NULL; } 00088 #define memcopy(a,b,c,d) \ 00089 VOIDP memcpy(VOIDP (a),CONSTVOIDP(b),(size_t)((c)*sizeof(d))) 00090 00091 /* Functions taking max/min of two arguments. */ 00092 00093 #ifndef max 00094 #define max(a,b) ((a) > (b) ? (a) : (b)) 00095 #endif 00096 00097 #ifndef min 00098 #define min(a,b) ((a) < (b) ? (a) : (b)) 00099 #endif 00100 00101 #ifndef MAX 00102 #define MAX max 00103 #endif 00104 #ifndef MIN 00105 #define MIN min 00106 #endif 00107 00108 /* Macros checking for equality/non-equality between two double numbers */ 00109 00110 #define DEQUAL(a,b) \ 00111 ( (fabs((a) - (b)) <= (REL_PAR_RES * MAX(MAX(fabs(a),fabs(b)),(double)1.0))) ? (1) : (0) ) 00112 00113 #define DNEQUAL(a,b) \ 00114 ( (fabs((a) - (b)) > (REL_PAR_RES * MAX(MAX(fabs(a),fabs(b)),(double)1.0))) ? (1) : (0) ) 00115 00116 #define ZEROLEN(a) \ 00117 ( (fabs(a) <= AEPSGE) ? (1) : (0) ) 00118 00119 // used by s1772 00120 #define SINGULAR 1.0e-16 00121 #define s1772_copy2(a,b,c) for (ki=0;ki<(c);ki++) (a)[ki]=(b)[ki] 00122 #define s1772_copy3(a,b,c,d) for (ki=0;ki<(d);ki++) (a)[ki]=(b)[ki]=(c)[ki] 00123 #define s1772_incr2(a,b,c) for (ki=0;ki<(c);ki++) (a)[ki]+=(b)[ki] 00124 #define s1772_decr2(a,b,c) for (ki=0;ki<(c);ki++) (a)[ki]-=(b)[ki] 00125 #define s1772_set_order(a) if((a)==1) {s_v=s_uu;order=0;} else {s_v=s_v1;order=1;} 00126 00127 // spesific defines for s1770_2D: 00128 #define SINGULAR 1.0e-16 00129 #define s1770_2D_copy2(a,b,c) for (ki=0;ki<(c);ki++) (a)[ki]=(b)[ki] 00130 #define s1770_2D_copy3(a,b,c,d) for (ki=0;ki<(d);ki++) (a)[ki]=(b)[ki]=(c)[ki] 00131 #define s1770_2D_incr2(a,b,c) for (ki=0;ki<(c);ki++) (a)[ki]+=(b)[ki] 00132 #define s1770_2D_decr2(a,b,c) for (ki=0;ki<(c);ki++) (a)[ki]-=(b)[ki] 00133 #define s1770_2D_set_order(a) {if((a)==1) order=0; else order=1;} 00134 00135 #define s1891_MAX_SIZE 50 00136 #define s1925_MAX_ARRAY_SIZE 50 00137 #define s1897_MAX_IK 50 00138 00139 #ifdef __BORLANDC__ 00140 # include <Values.h> 00141 # ifndef HUGE 00142 # define HUGE MAXDOUBLE 00143 # endif 00144 #endif 00145 00146 00147 enum { SI_ORD = 1, SI_SING, SI_TRIM, SI_TOUCH }; 00148 enum { SI_UNDEF, SI_IN, SI_OUT, SI_ON, SI_AT }; 00149 enum { SI_RIGHT=1, SI_LEFT=2 }; 00150 00151 00152 static int sh1762_xc = 0; 00153 static int sh1762_xmax = 0; 00154 typedef void (*sh1783_fevalProc)(SISLCurve *,int,double,int *,double[],int *); 00155 typedef void (*sh1784_fevalcProc)(SISLCurve *, int, double, int *, double [], int *); 00156 typedef void (*s1786_fevalcProc)(SISLCurve *,int,double,int *,double [],int *); 00157 00158 //=========================================================================== 00159 // SISL functions indirectly used by 'sisl_dependent' 00160 //=========================================================================== 00161 void sh6setcnsdir(SISLIntpt *pt1,SISLIntpt *pt2,int ipar,int *jstat); 00162 void s6degnorm(SISLSurf *ps1,int ider,double epar[],double eder[], 00163 double utang[],double vtang[],double enorm[],int *jstat); 00164 void sh6idrmcross(SISLObject *po1, SISLObject *po2, SISLIntdat **pintdat, 00165 SISLIntpt *vcross[], int incross, SISLIntpt *vpt[], 00166 int inpt, int *jstat); 00167 void sh6idfcross(SISLIntdat *pintdat, SISLIntpt *vcross[], int *jncross, 00168 int ipar1, int ipar2, int *jstat); 00169 void sh6idput (SISLObject * po1, SISLObject * po2, SISLIntdat ** rintdat, 00170 SISLIntdat * pintdat, int inr, double apar, 00171 SISLIntpt *** outintpt, int *npoint, int *jstat); 00172 void sh1992(SISLObject *po,int itype,double aepsge,int *jstat); 00173 void s9boundimp(double epnt1[],double epar1[],SISLSurf *psurf1,double eimpli[], 00174 int ideg,double apar,int idir,double aepsge, 00175 double gpnt1[],double gpar1[],int *jstat); 00176 void s1308(double ep[],int idim,double eimpli[],int ideg,double enorm[],int *jstat); 00177 void s1001 (SISLSurf * ps, double min1, double min2, 00178 double max1, double max2, 00179 SISLSurf ** rsnew, int *jstat); 00180 void s6crvcheck(SISLCurve *pc,int *jstat); 00181 void s1379(double ep[],double ev[],double epar[],int im,int idim, 00182 SISLCurve **rcurve,int *jstat); 00183 void s6twonorm(double evec[],double enorm1[],double enorm2[],int *jstat); 00184 void s9boundit(double epnt1[],double epnt2[],double epar1[],double epar2[], 00185 SISLSurf *psurf1,SISLSurf *psurf2,double apar,int idir,double aepsge, 00186 double gpnt1[],double gpnt2[],double gpar1[],double gpar2[],int *jstat); 00187 void s1602(double estapt[],double endpt[],int ik,int idim,double astpar, 00188 double *cendpar,SISLCurve **rc,int *jstat); 00189 void s1755 (double orknt[], int in, int ik, double extknt[], int *inh, int *jstat); 00190 void s1753 (double et[], double ecf[], int in, int ik, int idim, double etr[], 00191 double ecfr[], int inr, double ecc[], double ecw[], int *jstat); 00192 void s1754 (double *et, int in, int ik, int ikh, double **iknt, int *inh, int *jstat); 00193 void s1750(SISLCurve *pc,int ikh,SISLCurve **rc,int *jstat); 00194 void s1715(SISLCurve *pc1,SISLCurve *pc2,int iend1,int iend2,SISLCurve **rcnew,int *jstat); 00195 void s1710 (SISLCurve * pc1, double apar, SISLCurve ** rcnew1, 00196 SISLCurve ** rcnew2, int *jstat); 00197 void s1714 (SISLCurve * pc, double apar1, double apar2, SISLCurve ** rcnew1, 00198 SISLCurve ** rcnew2, int *jstat); 00199 void s1713(SISLCurve *pc,double abeg,double aend,SISLCurve **rcnew,int *jstat); 00200 void s1706(SISLCurve *pc); 00201 void pick_crv_sf(SISLObject *po1, SISLObject *po2,int ipar, 00202 SISLIntpt *pt1,SISLIntpt *pt2,SISLCurve **rcrv, int *jstat); 00203 SISLIntsurf *newIntsurf (SISLIntlist * pintlist); 00204 void s1425(SISLSurf *ps1,int ider1,int ider2,int iside1,int iside2,double epar[], 00205 int *ileft1,int *ileft2,double eder[],int *jstat); 00206 void s1422(SISLSurf *ps1,int ider,int iside1,int iside2,double epar[],int *ilfs, 00207 int *ilft,double eder[],double enorm[],int *jstat); 00208 void sh6evalint (SISLObject * ob1, SISLObject * ob2, double eimpli[], int ideg, 00209 SISLIntpt * pt, double aepsge, double *curve_3d[], 00210 double *curve_2d_1[], double *curve_2d_2[], int *jstat); 00211 void sh6idsplit (SISLIntdat ** pintdat, SISLIntpt * psource, int *jstat); 00212 void sh6gettophlp (SISLIntpt * pt, int pretop[4], int case_2d, int *jstat); 00213 void sh1779_at (SISLObject * po1, SISLObject * po2, SISLIntpt * pintpt, int *jstat); 00214 void sh1780_at (SISLObject * po1, SISLObject * po2, SISLIntpt * pintpt, int *jstat); 00215 void sh1781_at (SISLObject * po1, SISLObject * po2, SISLIntpt * pintpt, int *jstat); 00216 void sh_set_at (SISLObject * po1, SISLObject * po2, SISLIntdat * pintdat, int *jstat); 00217 void sh6idlis (SISLObject * po1, SISLObject * po2, SISLIntdat ** pintdat, 00218 double aepsge, int *jstat); 00219 void sh6idunite (SISLIntdat ** intdat, SISLIntpt ** pt1, SISLIntpt ** pt2, 00220 double weight, int *jstat); 00221 void sh6edgred (SISLObject * po1, SISLObject * po2, 00222 SISLIntdat * pintdat, int *jstat); 00223 void s9conmarch(SISLSurf *ps,double alevel,double epar[],int ndir[],int ipoint, 00224 double *gpar[],int *mpar[],int *jpoint,int *jstat); 00225 void s9surmarch(SISLSurf *ps1,SISLSurf *ps2,double epar[],int ndir[],int ipoint, 00226 double *gpar[],int *mpar[],int *jpoint,int *jstat); 00227 void shsing_s9dir(double cdiff[],double evals[],double evalq[]); 00228 void shsing_s9corr(double gd[], double coef[],double limit[]); 00229 void shsing(SISLSurf *psurf1,SISLSurf *psurf2,double limit[], 00230 double enext[], double gpos[],int *jstat); 00231 void s6findfac(double evecu[],double evecv[],double evecw[],double etang[], 00232 int idim,int isign,double *coef1,double *coef2,double *coef3,int *jstat); 00233 int s1789_s9knot(double et[], int ik, int in, double ax1, double ax2, 00234 int *jmy, int *jstat); 00235 void s1789_s9eval(double eders[],double enorms[],double etanc[], 00236 double ederc[],int idim, int *jstat); 00237 void s1789(SISLPoint *ppoint,SISLSurf *psurf,double aepsge, 00238 double epar1[],double epar2[],int *jstat); 00239 void s1786_s9relax(s1786_fevalcProc fevalc1,s1786_fevalcProc fevalc2, 00240 SISLCurve *pc1,SISLCurve *pc2, 00241 int ider,double aepsge,double ax1,int *jleft1,double eder1[], 00242 double anext,double *cx2,int *jleft2,double eder2[],int *jstat); 00243 void s1786(SISLCurve *pc1,SISLCurve *pc2,double aepsge,double epar1[], 00244 double epar2[],int *jstat); 00245 void s1785(SISLCurve *pcurve,SISLSurf *psurf,double aepsge, 00246 double epar1[],double epar2[],int icur,int *jstat); 00247 void s1880(int ipar1,int ipar2,int *jpt,SISLIntpt **vpoint,int *jlist, 00248 SISLIntlist **vlist,int *jpar,double **gpar1,double **gpar2, 00249 int *jcrv,SISLIntcurve ***wcrv,int *jstat); 00250 SISLIntlist *newIntlist (SISLIntpt * pfirst, SISLIntpt * plast, int itype); 00251 void s6decomp(double ea[],double gx[],double eb1[],double eb2[], 00252 double eb3[],int *jstat); 00253 void s1788(SISLSurf *ps1,SISLSurf *ps2,double aepsge,double epar[], 00254 double gpar1[],double gpar2[],int *jstat); 00255 void freeIntlist(SISLIntlist *plist); 00256 void s6idklist(SISLIntdat **pintdat,SISLIntlist *pintlist,int *jstat); 00257 SISLIntcurve *newIntcurve (int ipoint, int ipar1, int ipar2, 00258 double *epar1, double *epar2, int itype); 00259 void s1787(SISLSurf *ps,double alevel,double aepsge,double epar[], 00260 double gpar1[],double gpar2[],int *jstat); 00261 void s6idkpt(SISLIntdat **pintdat,SISLIntpt **pintpt,SISLIntpt **rtpt,SISLIntpt **rfpt, 00262 int *jstat); 00263 void s6idlis_s9psexamin(SISLSurf *ps1,double alevel, SISLIntdat **rintdat,int *jstat); 00264 void s6idlis_s9ssexamin(SISLSurf *ps1,SISLSurf *ps2, SISLIntdat **rintdat,int *jstat); 00265 void s6idlis(SISLObject *po1,SISLObject *po2,SISLIntdat **pintdat,int *jstat); 00266 void s1252_s6dir(double *cdiff,double acoef,double eval[],double astart, double aend); 00267 void s1252_s6corr(double *gdn,double acoef,double et[], int in,int ik,int *ileft,int *jdir); 00268 void s1252(SISLCurve *pcurve,double aepsge,double astart,double *cpos,int *jstat); 00269 void s1119(double *ecoef,double *et1,double *et2,int ik1,int in1,int ik2, 00270 int in2,int *jsimple,int *jind1,int *jind2,int *jstat); 00271 void s1162_s9mic(SISLObject *,SISLObject *,SISLIntdat **, SISLEdge *[],int *); 00272 void s1162_s9num(SISLObject *,int *,int *); 00273 void s1162_s9edge(SISLObject *[],SISLObject *[],int,int, SISLIntdat *, 00274 SISLEdge *[],int *); 00275 void s1162_s9con(SISLObject *,double *,double,SISLIntdat **,SISLEdge *[],int *, 00276 int *,int *); 00277 void s1162_s9update(SISLObject *,double *,double,SISLIntdat **, SISLEdge *[2], 00278 int *); 00279 void s1162_s9div(SISLObject *,double *,double,int,int,int, SISLObject *[], 00280 SISLIntdat **,SISLEdge *[2],int,int *); 00281 SISLIntpt *hp_copyIntpt (SISLIntpt * ppt); 00282 SISLIntpt *copyIntpt (SISLIntpt * ppt); 00283 void s6idcon_s9endturn(SISLIntdat *pintdat,SISLIntpt *pt); 00284 void s6idcon_s9turn(SISLIntpt *pt); 00285 void s6idcon(SISLIntdat **pintdat,SISLIntpt **pintpt1,SISLIntpt **pintpt2,int *jstat); 00286 void s6idput(SISLIntdat **rintdat,SISLIntdat *pintdat,int inr,double apar,int *jstat); 00287 void s1192_s9mbox(double ecoef[], int in1,int in2,double aepsge, 00288 double *cmax, double *cmin,int *jmax,int *jmin); 00289 void s1192(SISLObject *po,double aepsge,int *jstat); 00290 void s1190(SISLObject *po1, double *cmax, double aepsge,int *jstat); 00291 void s6idnpt(SISLIntdat **pintdat,SISLIntpt **pintpt,int itest,int *jstat); 00292 SISLIntpt *newIntpt (int ipar, double *epar, double adist); 00293 void s1161(SISLObject *po1,double *cmax,double aepsge,SISLIntdat **pintdat,int *jstat); 00294 void s1921(SISLSurf *ps1,double edir[],int idim,double aepsco,double aepsge, 00295 int *jpt,double **gpar,int *jcrv,SISLIntcurve ***wcurve,int *jstat); 00296 void s1954(SISLSurf *psurf,double epoint[],int idim,double aepsco,double aepsge, 00297 int *jpt,double **gpar,int *jcrv,SISLIntcurve ***wcurve,int *jstat); 00298 void s1893 (SISLCurve * orig, double earray[], int dimp1, int narr, int der1, 00299 int der2, SISLCurve ** ncurve, int *jstat); 00300 void s1370 (SISLCurve * pcurv, double earray[], int idim, int inarr, 00301 int ratflag, SISLCurve ** rcurv, int *jstat); 00302 void sh6sepcrv_s9circle(double apt1[], double apt2[], double apt3[], 00303 double aepsge, double ecentre[], double eaxis[], 00304 double *crad, int *jstat); 00305 void sh6sepcrv (SISLCurve *pc1, SISLCurve *pc2, double aepsge, double ecentre[], 00306 double *crad, int *jstat); 00307 void sh1831(SISLCurve *pc1, SISLCurve *pc2, int isign, double epoint[], 00308 double enorm[], double aepsge, int *jstat); 00309 void sh1830(SISLObject *po1,SISLObject *po2,double aepsge,int *jstat); 00310 void 00311 sh1871(SISLCurve *pc1, double *pt1, int idim, double aepsco, double aepsge, 00312 int trackflag, int *jtrack, SISLTrack *** wtrack, 00313 int *jpt,double **gpar1,int **pretop,int *jcrv, 00314 SISLIntcurve ***wcurve,int *jstat); 00315 void s1376(double et[],int in,int ik,double **gt,int *jkn,int *jkk,int *jstat); 00316 void s1378 (SISLSurf * psurf, double econic[], int ideg, int idim, 00317 SISLSurf ** rsurf, int *jstat); 00318 void s1927 (double *w1, int nur, int ik, int *ed, double *w2, int nrc, 00319 double *w3, int nlr, double *ex[], double *ey, int *jstat); 00320 void s1926 (double *w1, int nur, int ik, int *ed, double *w2, int nrc, 00321 double *w3, int nlr, int *jstat); 00322 void s1897 (double et[], int ik, double ax, int left, int deriv, 00323 double ebiatx[], int *jstat); 00324 void s1925 (double etau[], double epoint[], int inbpnt, int eder[], 00325 double et[], double ebcoef[], int in, int ik, int iright, int dim, 00326 double ew1[], int nur, int ed[], double ew2[], int inrc, double ew3[], 00327 int inlr, int *jstat); 00328 void s1891 (double etau[], double epoint[], int idim, int inbpnt, int iright, 00329 int eder[], int iopen, double et[], double *ebcoef[], int *in, 00330 int ik, int inlr, int inrc, int *jstat); 00331 void s1890 (double oknots[], int oik, int oin, double *par[], int *der[], int *jstat); 00332 void s1894 (double oknots[], int oik, int oin, int der1, int der2, double earray[], 00333 int dimp1, int narr, double *nknots[], int *nik, int *nin, int *jstat); 00334 void s1896 (SISLSurf * osurf, double earray[], int dimp1, int narr, int ders1[], 00335 int dert1[], int ders2[], int dert2[], SISLSurf ** nsurf, int *jstat); 00336 void s1320 (SISLSurf * psurf, double earray[], int inarr, 00337 int ratflag, SISLSurf ** rsurf, int *jstat); 00338 void s1322(double epoint[],double edirec[],double aradiu,int idim, 00339 int inumb,double carray[],int *jstat); 00340 void s1321(double ecentr[],double aradiu,int idim,int inumb, double carray[],int *jstat); 00341 00342 void sh6splitgeom_s9circle(double apt1[], double apt2[], double apt3[], 00343 double aepsge, double ecentre[], double eaxis[], 00344 double *crad, int *jstat); 00345 void sh6splitgeom (SISLSurf *ps1, SISLSurf *ps2, double aepsge, double ecentre[], 00346 double eaxis[], double *cdist, double *crad, int *jstat); 00347 void sh6findsplit (SISLSurf *ps1, SISLSurf *ps2, double aepsge, int *jstat); 00348 void sh1834_s9mat3d(double emat[],double edir1[],double edir2[]); 00349 void sh1834_s9mat2d(double emat[],double edir[]); 00350 void sh1834(SISLObject *po1,SISLObject *po2,double aepsge,int idim, 00351 double edir1[],double edir2[],int *jstat); 00352 void sh1839(SISLObject *po1,SISLObject *po2,double aepsge,int *jstat); 00353 int sh6isconnect(SISLIntpt *pt0, SISLIntpt *pt1, SISLIntpt *pt2); 00354 void sh6floop(SISLIntpt *vedgept[],int inum,int *jpt,int *jstat); 00355 void sh6closevert(SISLCurve *pcurve,SISLSurf *psurf,double *cpar1, double epar2[]); 00356 void sh6cvvert(SISLCurve *pc1, SISLCurve *pc2, double *cpar1, double *cpar2); 00357 void s1711(SISLSurf *ps,int ipar,double apar,SISLSurf **rsnew1, 00358 SISLSurf **rsnew2,int *jstat); 00359 void s6idcpt(SISLIntdat *pintdat,SISLIntpt *pintpt,SISLIntpt **rintpt); 00360 void sh6insert(SISLIntdat **pintdat,SISLIntpt *pt1,SISLIntpt *pt2, 00361 SISLIntpt **ptnew,int *jstat); 00362 void sh6idget (SISLObject * po1, SISLObject * po2, int ipar, double apar, 00363 SISLIntdat * pintdat, SISLIntdat ** rintdat, double aepsge, 00364 int *jstat); 00365 void s1700(int imy,int ik,int in,int iv, 00366 int *jpl,int *jfi,int *jla,double *et,double apar, 00367 double *galfa,int *jstat); 00368 void s1231(SISLCurve *pc1,double apar, 00369 SISLCurve **rcnew1,SISLCurve **rcnew2,int *jstat); 00370 void s1174_s9dir(double *cdiff1, double *cdiff2,double evals[]); 00371 void s1174_s9corr(double gd[], double acoef1,double acoef2,double astart1, 00372 double aend1,double astart2, double aend2); 00373 void s1174(SISLSurf *psurf,double estart[], double eend[], double enext[], 00374 double gpos[],int *jstat); 00375 void s9simple_knot(SISLSurf* surf, int idiv, double epar[], 00376 int *fixflag, int *jstat); 00377 double s1792(double et[],int ik,int in); 00378 int s1772_s6local_pretop(double dist,double diff[],double normal[], 00379 double f[],double f_t[],double f_tt[], 00380 double s[],double s_u[],double s_v[], 00381 double s_uu[],double s_uv[],double s_vv[], 00382 int dim, int*jstat); 00383 void s1772_s6sekant1(SISLCurve *pcurve,SISLSurf *psurf, 00384 double par_val[], double delta, double *dist, double aepsge, 00385 double astart1,double estart2[],double aend1,double eend2[], 00386 double c0[], double s0[], double norm[], int *jstat); 00387 void s1772_s9dir(double *dist,double diff[],double delta[], 00388 double f[],double f_t[],double f_tt[], 00389 double g[],double g_u[],double g_v[], 00390 double g_uu[],double g_uv[],double g_vv[], 00391 int dim,int second,int* jstat); 00392 void s1772_s9corr(double gd[],double acoef[],double astart1,double aend1, 00393 double astart2[],double aend2[],int *corr); 00394 void s1772(SISLCurve *pcurve,SISLSurf *psurf,double aepsge, 00395 double astart1,double estart2[],double aend1,double eend2[], 00396 double anext1,double enext2[],double *cpos1,double gpos2[], int *jstat); 00397 void s1172_s9dir(double *cdiff,double evals[]); 00398 void s1172_s9corr(double *cd, double acoef,double astart,double aend); 00399 void s1172(SISLCurve *pcurve,double astart, 00400 double aend, double anext, double *cpos,int *jstat); 00401 int sh6nmbhelp(SISLIntpt *pt,int *jstat); 00402 int s1791(double et[],int ik,int in); 00403 void sh6setdir(SISLIntpt *pt1,SISLIntpt *pt2,int *jstat); 00404 void sh1784 (SISLCurve * pcurve, SISLSurf * psurf, double aepsge, 00405 double epar[], int icur, int idirc, double elast[], 00406 double enext[], int *jstat); 00407 void sh1779 (SISLObject * po1, SISLObject * po2, double aepsge, 00408 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, int *jstat); 00409 void sh1787 (SISLObject * po1, SISLObject * po2, double aepsge, 00410 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, 00411 int *jstat); 00412 void sh1786 (SISLObject * po1, SISLObject * po2, double aepsge, 00413 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, int *jstat); 00414 void s1307(double ep[],int idim,double egeo[],int *jstat); 00415 void sh1992_s9mbox(double ecoef[],int icoef1,int icoef2,int idim, 00416 double aeps1,double aeps2,double e2max[], 00417 double e2min[],int *jstat); 00418 void sh1992_s9mbox2(double ecoef[],int icoef1,int icoef2,double aeps1, 00419 double aeps2,double e2max[],double e2min[]); 00420 void sh1992_s9mbox3(double ecoef[],int icoef1,int icoef2,double aeps1, 00421 double aeps2,double e2max[],double e2min[]); 00422 void s6newbox(SISLbox *pbox,int inum,int itype, double aepsge,int *jstat); 00423 int s6existbox(SISLbox *pbox,int itype,double aepsge); 00424 SISLbox * newbox (int idim); 00425 void sh1992cu(SISLCurve *pc,int itype,double aepsge,int *jstat); 00426 void sh1783_s9relax(sh1783_fevalProc fevalc1,sh1783_fevalProc fevalc2, 00427 SISLCurve * pc1, SISLCurve * pc2,int ider, double aepsge, 00428 double ax1, int *jleft1, double eder1[],double anext, 00429 double *cx2, int *jleft2, double eder2[], int *jstat); 00430 void sh1783 (SISLCurve * pc1, SISLCurve * pc2, double aepsge, double epar[], 00431 int idir1, int idir2, double elast[], double enext[], int *jstat); 00432 void sh1780 (SISLObject * po1, SISLObject * po2, double aepsge, 00433 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, 00434 int *jstat); 00435 void sh6settop(SISLIntpt *pt,int ilist,int left1,int right1,int left2, 00436 int right2,int *jstat); 00437 void shevalc(SISLCurve *pc1,int ider,double ax,double aepsge,int *ileft, 00438 double eder[],int *jstat); 00439 void sh6getgeom(SISLObject *ob, int obnr, SISLIntpt *pt, 00440 double **geom, double **norm, double aepsge, int *jstat); 00441 void sh6gettop(SISLIntpt *pt,int ilist,int *left1,int *right1, 00442 int *left2,int *right2,int *jstat); 00443 void sh1781 (SISLObject * po1, SISLObject * po2, double aepsge, 00444 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, 00445 int *jstat); 00446 void s6idint(SISLObject *po1,SISLObject *po2,SISLIntdat *pintdat,SISLIntpt **rpt, 00447 int iob); 00448 void shmkhlppts (SISLObject * po1, SISLObject * po2, double aepsge, 00449 SISLIntdat ** rintdat, SISLEdge * vedge[], int *jnewpt, 00450 int *jstat); 00451 void sh6tohelp(SISLIntpt *pt,int *jstat); 00452 double s1173_s9del(double *eco, double *eco1, double *eco2, int idim); 00453 void s1173_s9dir(double *cdist, double *cdiff1, double *cdiff2, 00454 double gdiff[], double evalp[], double evals[], double aepsge); 00455 void s1173_s9corr(double gd[], double acoef1,double acoef2,double astart1, 00456 double aend1,double astart2, double aend2); 00457 void s1173(SISLPoint *ppoint, SISLSurf *psurf, double aepsge,double estart[], 00458 double eend[], double enext[], double gpos[],int *jstat); 00459 void s1773_s9dir(double *cdist,double *cdiff1,double *cdiff2, 00460 double PS[],double eval1[],double eval2[], 00461 double aepsge, int idim,int *jstat); 00462 void s1773_s9corr(double gd[],double acoef1,double acoef2, 00463 double astart1,double aend1,double astart2,double aend2); 00464 void s1773(SISLPoint *ppoint,SISLSurf *psurf,double aepsge, 00465 double estart[],double eend[],double enext[],double gpos[],int *jstat); 00466 void sh6ptobj(double *point, SISLObject *obj, double aepsge, 00467 double start[], double result[], int *jstat); 00468 void sh6idnewunite (SISLObject *po1, SISLObject *po2, SISLIntdat ** intdat, 00469 SISLIntpt ** pt1, SISLIntpt ** pt2, double weight, 00470 double aepsge, int *jstat); 00471 void sh6trimlist (SISLIntpt * pt, SISLIntpt *** ptlist, int *no_of_points, 00472 int *no_alloc); 00473 void sh6red (SISLObject * po1, SISLObject * po2, 00474 SISLIntdat * pintdat, int *jstat); 00475 void sh6idcon (SISLIntdat ** pintdat, SISLIntpt ** pintpt1, 00476 SISLIntpt ** pintpt2, int *jstat); 00477 void sh6insertpt (SISLIntpt * pt1, SISLIntpt * pt2, SISLIntpt * ptnew, int *jstat); 00478 int sh6nmbmain(SISLIntpt *pt,int *jstat); 00479 void sh6connect (SISLIntpt * pt1, SISLIntpt * pt2, int *jstat); 00480 void sh6disconnect(SISLIntpt *pt1,SISLIntpt *pt2,int *jstat); 00481 void sh6idkpt (SISLIntdat ** pintdat, SISLIntpt ** pintpt, int join, int *jstat); 00482 void sh_div_crv (SISLCurve * pc, int which_end, double aepsge, 00483 SISLCurve ** rcnew, int *jstat); 00484 void sh_div_surf (SISLSurf * ps, int which_end_1, int which_end_2, 00485 double aepsge, SISLSurf ** rsnew, int *jstat); 00486 void sh6comedg (SISLObject * po1, SISLObject * po2, SISLIntpt *pt1, 00487 SISLIntpt *pt2, int *jstat); 00488 void sh6isinside (SISLObject * po1, SISLObject * po2, SISLIntpt *intpt, int *jstat); 00489 void freeTrimpar(SISLTrimpar *trimpar); 00490 void freeIntpt(SISLIntpt *ppt); 00491 void s6deCasteljau(double C[], double a, double b, double t, int k, double D[], int* jstat); 00492 void s6sratder(double eder[],int idim,int ider1,int ider2,double gder[],int *jstat); 00493 void s1424(SISLSurf *ps1,int ider1,int ider2,double epar[], 00494 int *ileft1,int *ileft2,double eder[],int *jstat); 00495 void s6hermite_bezier(SISLSurf* s,double a[],double b[],int idim, double c[],int* jstat); 00496 void s6identify(SISLSurf* s,double a[], double b[], double level_val, 00497 double eps1,double eps2,int* jstat); 00498 SISLIntdat *newIntdat (void); 00499 void sh_1d_div_sh9idnpt(SISLSurf* surf, SISLPoint* point, SISLIntdat **pintdat, 00500 SISLIntpt **pintpt, int itest, double aepsge, int *jstat); 00501 void sh_1d_div (SISLObject *po1, SISLObject *po2, double aepsge, 00502 SISLIntdat **pintdat, SISLEdge * vedge[], int *jstat); 00503 void s1797(SISLSurf *ps1,SISLCurve *pc1,double aepsge,double aang,int *jstat); 00504 void s1795(SISLSurf *ps1,SISLSurf *ps2,double aepsge,double aang,int *jstat); 00505 void s1796(SISLCurve *pc1,SISLCurve *pc2,double aepsge,double aang,int *jstat); 00506 double s6dplane(double eq1[],double eq2[],double eq3[],double epoint[], 00507 int idim,int *jstat); 00508 double s6dline(double estart[],double eend[],double epoint[], 00509 int idim,int *jstat); 00510 void s1990_s9smooth(double ecoef1[],int in1,int in2,int idim, 00511 double aepsge,double ecoef2[],int *jstat); 00512 void s1990_s9edg(double et[],double etan[],double esen[],double aepsge, 00513 double *cang,int idim,int *jstat); 00514 void s1990(SISLSurf *ps,double aepsge,int *jstat); 00515 void sh1994(SISLSurf *s1,double aepsge,int *jstat); 00516 SISLdir *newdir(int); 00517 void s1991(SISLCurve *pc,double aepsge,int *jstat); 00518 void sh1993(SISLCurve *c1,double aepsge,int *jstat); 00519 void s1741(SISLObject *po1,SISLObject *po2,double aepsge,int *jstat); 00520 void sh6edgpoint (SISLEdge * vedge[], SISLIntpt *** wintpt, int *jnum,int *jstat); 00521 void sh1762_s9mic (SISLObject *, SISLObject *, SISLIntdat **, SISLEdge **[], int *); 00522 void sh1762_s9num (SISLObject *, SISLObject *, int *, int *); 00523 void sh1762_s9div (SISLObject *, SISLObject *, double, int, int, SISLObject *[], SISLEdge *[], SISLIntdat **, int *); 00524 void sh1762_s9subdivpt (SISLObject *, SISLObject *, double, int, int, SISLEdge *[], SISLIntdat **, int *, SISLIntpt **, double[], int *); 00525 void sh1762_s9update (SISLObject *, SISLObject *, double, SISLIntdat **, SISLEdge **[], int *); 00526 void sh1762_s9con (SISLObject *, SISLObject *, double, SISLIntdat **, SISLEdge *[], int *); 00527 void sh1762_s9intercept (SISLObject *, SISLObject *, double, int, SISLIntpt *[], int *); 00528 void sh1762_s9coincide (SISLObject *, SISLObject *, double, int, SISLIntpt *[], int *); 00529 void sh1762_s9toucharea (SISLObject *, SISLObject *, double, int, SISLIntpt *[], int *); 00530 void sh1762_s9edgsscon (SISLEdge *[], SISLSurf *, SISLSurf *, SISLIntdat *, int, double, int *); 00531 void sh1762_s9edgpscon (SISLEdge *, double, SISLSurf *, int, SISLIntdat *, double, int *); 00532 void sh1762_s9simple (SISLObject *, SISLObject *, SISLEdge *[], int *); 00533 void sh1762_s9ptiter (SISLObject *, SISLObject *, double, SISLIntdat **, SISLEdge *[], int *); 00534 int sh1762_is_taboo(SISLSurf *, SISLSurf *, SISLIntpt *, int, int *); 00535 void sh1762 (SISLObject * po1, SISLObject * po2, double aepsge, 00536 SISLIntdat ** pintdat, SISLEdge * vedge[], int *jstat); 00537 double sh1762_sflength(SISLSurf *, int, int *); 00538 void sh6tomain(SISLIntpt *pt,int *jstat); 00539 void s6fndintvl(double *et,int ik,int in,int *ileft, 00540 double ax1,double ax2,int mu_max,int *jstat); 00541 int sh6getprev(SISLIntpt *pt1,SISLIntpt *pt2); 00542 void sh6getlist(SISLIntpt *pt1,SISLIntpt *pt2,int *index1,int *index2,int *jstat); 00543 void sh6getother(SISLIntpt *pt,SISLIntpt *pt1,SISLIntpt **pt2,int *jstat); 00544 void sh6getnhbrs(SISLIntpt *pt,SISLIntpt **pt1,SISLIntpt **pt2,int *jstat); 00545 int sh6ismain(SISLIntpt *pt); 00546 SISLIntpt* sh6getnext(SISLIntpt *pt,int index); 00547 int sh6ishelp(SISLIntpt *pt); 00548 SISLIntpt * sh6getmain (SISLIntpt * pt); 00549 void sh6idalledg (SISLObject * pob1, SISLObject * pob2, SISLIntdat * pintdat, 00550 SISLEdge * wedge[], int *jstat); 00551 void freePtedge(SISLPtedge *p1); 00552 void freeEdge(SISLEdge *pedge); 00553 void s1435(SISLSurf *ps1,int iedge,SISLCurve **rcedge,double *cpar,int *jstat); 00554 SISLPtedge *newPtedge (SISLIntpt * ppt); 00555 void s6idedg(SISLObject *po1,SISLObject *po2,int iobj,int ipar,double apar, 00556 SISLIntdat *pintdat,SISLPtedge **rptedge,int *jnum,int *jstat); 00557 int s6knotmult(double et[],int ik,int in,int *ileft,double ax,int *jstat); 00558 void test_cyclic_knots(double et[],int in,int ik,int *jstat); 00559 double s1325(double aradiu,double angle); 00560 void sh1782 (SISLObject * po1, SISLObject * po2, double aepsge, 00561 SISLIntdat * pintdat, int ipar, double apar, 00562 SISLIntdat ** rintdat, int *jnewpt, int *jstat); 00563 void sh1782_s9sf_pt (SISLObject *, SISLObject *, double, SISLIntdat **, 00564 SISLIntpt **, int, int, int *); 00565 void sh1782_s9sf_cu (SISLObject *, SISLObject *, double, SISLIntdat **, 00566 SISLIntpt **, int, int, int *); 00567 void sh1782_s9sf_sf (SISLObject *, SISLObject *, double, SISLIntdat **, 00568 SISLIntpt **, int, int, int *); 00569 void s1438(SISLCurve *pc,int iedge,SISLPoint **rpedge,double *cpar,int *jstat); 00570 SISLEdge *newEdge (int iedge); 00571 void sh1790(SISLObject *po1,SISLObject *po2,int itype, double aepsge,int *jstat); 00572 void sh6idnpt(SISLIntdat **pintdat,SISLIntpt **pintpt,int itest,int *jstat); 00573 SISLIntpt * hp_newIntpt (int ipar, double *epar, double adist, int itype, 00574 int ileft1, int iright1, int ileft2, int iright2, 00575 int size_1, int size_2, double egeom1[], double egeom2[]); 00576 void make_cv_kreg (SISLCurve * pc, SISLCurve ** rcnew, int *jstat); 00577 void s1605(SISLCurve *pc,double aepsge,double **gpoint,int *jnbpnt,int *jstat); 00578 double s1309(double epnt[],double edir[],double eimpli[],int ideg,int *jstat); 00579 void s1436(SISLSurf *ps1,double apar,SISLCurve **rcurve,int *jstat); 00580 void s1712 (SISLCurve * pc, double abeg, double aend, SISLCurve ** rcnew, int *jstat); 00581 void s1437(SISLSurf *ps1,double apar,SISLCurve **rcurve,int *jstat); 00582 void s9clipimp(double epar1[],double epar2[],SISLSurf *psurf1,double eimpli[], 00583 int ideg,double euval[],double evval[],double aepsge, 00584 double gpnt1[],double gpar1[],int *jstat); 00585 void s1305(double epar1[],double epar2[],double eval1[],double eval2[], 00586 int *jbound,double gpar[],int *jstat); 00587 void s1331(double ep[],double eimpli[],int ideg,int ider, 00588 double gder[],double gnorm[],int *jstat); 00589 double s9adsimp(double epnt1[],double epar1[],double eimpli[],int ideg,double egd1[], 00590 double epgd1[],double etang[],double eptan[],double astep,int *jstat); 00591 void s9iterimp(double epoint[],double epnt1[],double epar1[],SISLSurf *psurf1, 00592 double eimpli[],int ideg,double astep,double aepsge, 00593 double gpnt1[],double gpar1[],int *jstat); 00594 void s1313(SISLSurf *ps1,double eimpli[],int ideg,double aepsco,double aepsge, 00595 double amax,SISLIntcurve *pintcr,int icur,int igraph,int *jstat); 00596 void s1313_s9constline(SISLSurf *,double [],int,double, 00597 SISLIntcurve *,int,int,int *); 00598 void s1306(double ep[],double eparp[],double eimpli[],int ideg, 00599 double egeo3d[],double egeop[],int *jstat); 00600 void s1771(SISLPoint *ppoint,SISLCurve *pcurve,double aepsge, 00601 double astart,double aend,double anext,double *cpos,int *jstat); 00602 void s6ratder(double eder[],int idim,int ider,double gder[],int *jstat); 00603 double s1771_s9del(double *,double *,double *,int); 00604 void s1771_s9point(SISLCurve *,double [],double [],double [],double,double, 00605 int,double *,double *,double,double *,double,int,int *); 00606 void s6lusolp(double ea[],double eb[],int nl[],int im,int *jstat); 00607 void s6lufacp(double ea[],int nl[],int im,int *jstat); 00608 void s1227(SISLCurve *pc1,int ider,double ax,int *ileft,double eder[],int *jstat); 00609 void refine_all (SISLIntdat ** pintdat, SISLObject * po1, SISLObject * po2, 00610 double eimpli[], int ideg, double aepsge, int *jstat); 00611 void sh6degen(SISLObject * po1, SISLObject * po2, SISLIntdat ** pintdat, 00612 double aepsge, int *jstat); 00613 void sh6degen_geom(SISLObject *,SISLObject *,double [],double [], int *); 00614 void freePoint(SISLPoint *ppoint); 00615 // SISLPoint *newPoint (double *ecoef, int idim, int icopy); 00616 void s1329(SISLSurf *psold,double epoint[],double enorm[],int idim, 00617 SISLSurf **rsnew,int *jstat); 00618 void make_sf_kreg (SISLSurf * ps, SISLSurf ** rsnew, int *jstat); 00619 void s6err(const char *rut,int jstat,int ipos); 00620 void s1310_s9constline(SISLSurf *ps1,SISLSurf *ps2,SISLIntcurve *pintcr, 00621 double aepsge,int icur,int igraph,int *jstat); 00622 void s1359(double egeo[],double aepsge,int idim,int inbinf, 00623 int ipar,double epar[],SISLCurve **rcurve,int *jstat); 00624 void s6line(double epoint[]); 00625 void s6move(double epoint[]); 00626 void s9clipit(double epar11[],double epar12[],double epar21[],double epar22[], 00627 SISLSurf *psurf1,SISLSurf *psurf2,double euval[],double evval[], 00628 double esval[], double etval[],double aepsge,double gpnt1[], 00629 double gpnt2[], double gpar1[],double gpar2[],int *jstat); 00630 void s1330(double epar11[],double epar12[],double epar21[],double epar22[], 00631 double eval11[],double eval12[],double eval21[],double eval22[], 00632 int *jbound,double gpar1[],double gpar2[],int *jstat); 00633 double s6ang(double evec1[],double evec2[],int idim); 00634 void s1361(double epnt1[],double epnt2[],int idim, 00635 double gmidd[],double gmtang[],int *jstat); 00636 double s9adstep(double epnt1[],double epar1[],double epnt2[],double epar2[], 00637 double egd1[],double epgd1[],double egd2[],double epgd2[], 00638 double etang[],double eptan1[],double eptan2[],double astep,int *jstat); 00639 double s1311(double arad,double aepsge,double amax,int *jstat); 00640 double s6dist(double [],double [],int); 00641 void s9iterate(double epoint[],double epnt1[],double epnt2[],double epar1[], 00642 double epar2[],SISLSurf *psurf1,SISLSurf *psurf2,double astep, 00643 double aepsge,double gpnt1[],double gpnt2[],double gpar1[], 00644 double gpar2[],int *jstat); 00645 00646 void s1304(double ep[],double eq[],double eparp[],double eparq[],double egeo3d[], 00647 double egeop[],double egeoq[],int *jstat); 00648 // void freeIntdat(SISLIntdat *pintdat); 00649 // void freeObject(SISLObject *); 00650 void hp_s1880(SISLObject *,SISLObject *,int,int,int,SISLIntdat *,int *, 00651 double **,double **,int **,int *,SISLIntcurve ***, 00652 int *,SISLIntsurf ***,int *); 00653 void make_tracks(SISLObject *,SISLObject *,int,double [],int,SISLIntlist **, 00654 int *,SISLTrack ***,double,int *); 00655 void int_join_per(SISLIntdat **,SISLObject *,SISLObject *,double [], 00656 int,double,int *); 00657 // void sh1761 (SISLObject * po1, SISLObject * po2, double aepsge, 00658 // SISLIntdat ** pintdat, int *jstat); 00659 double s6norm(double e1[],int idim,double e2[],int *jstat); 00660 void s6diff(double e1[],double e2[],int idim,double e3[]); 00661 void s1219(double *et,int ik,int in,int *ileft,double ax,int *jstat); 00662 void s6strider(double [],int,int,double [],int *); 00663 void s6crss(double e1[],double e2[],double e3[]) 00664 { 00665 e3[0] = e1[1]*e2[2] - e1[2]*e2[1]; 00666 e3[1] = e1[2]*e2[0] - e1[0]*e2[2]; 00667 e3[2] = e1[0]*e2[1] - e1[1]*e2[0]; 00668 } 00669 double s6length(double e1[],int idim,int *jstat); 00670 void s6chpar(double ecoef1[],int in1,int in2,int idim,double ecoef2[]); 00671 00672 void s1770_s9corr(double [],double,double,double,double,double,double); 00673 void s1770_s9dir(double *,double *,double *,double [],double [],double [],int); 00674 void sh1851(SISLSurf * ps1, double epoint[], double enorm[], int idim, 00675 double aepsco, double aepsge,int trackflag, int *jtrack, 00676 SISLTrack *** wtrack,int *jpt, double **gpar, int **pretop, 00677 int *jcrv, SISLIntcurve *** wcurve, int *jsurf, 00678 SISLIntsurf ***wsurf, int *jstat); 00679 void sh1859 (SISLSurf * ps1, SISLSurf * ps2, double aepsco, double aepsge, 00680 int trackflag, int *jtrack, SISLTrack *** wtrack, 00681 int *jpt, double **gpar1, double **gpar2, int **pretop, 00682 int *jcrv, SISLIntcurve *** wcurve, int *jsurf, 00683 SISLIntsurf *** wsurf, int *jstat); 00684 00685 void freeIntsurf(SISLIntsurf *); 00686 00687 void s1770_2D_s9corr(double [],double[],double,double,double,double,int*); 00688 void s1770_2D_s9dir(double *dist,double diff[],double delta[], 00689 double c1[],double c1_t[],double c1_tt[], 00690 double c2[],double c2_t[],double c2_tt[], 00691 int dim, int second, double* det, int* jstat); 00692 void s1770_2D_s6sekant1(SISLCurve *pcurve1,SISLCurve *pcurve2, 00693 double par_val[], double delta, double *dist, double aepsge, 00694 double astart1,double astart2,double aend1,double aend2, 00695 double c1[], double c2[], double norm[], 00696 int *jstat); 00697 int s1770_2D_s6local_pretop(double dist,double diff[],double normal[], 00698 double c1[],double c1_t[],double c1_tt[], 00699 double c2[],double c2_t[],double c2_tt[], 00700 int dim, int*jstat); 00701 00702 void s1770_2D(SISLCurve *pcurve1,SISLCurve *pcurve2,double aepsge, 00703 double astart1,double astart2,double aend1,double aend2, 00704 double anext1,double anext2,double *cpos1,double *cpos2,int *jstat); 00705 00706 void s1221(SISLCurve *pc1,int ider,double ax,int *ileft,double eder[],int *jstat); 00707 void sh1992su(SISLSurf *ps,int itype,double aepsge,int *jstat); 00708 00709 00710 //=========================================================================== 00711 // IMPLEMENTATIONS COMMENCE HERE 00712 //=========================================================================== 00713 00714 //=========================================================================== 00715 void sh6setcnsdir(SISLIntpt *pt1,SISLIntpt *pt2,int ipar,int *jstat) 00716 //=========================================================================== 00717 { 00718 int kstat; /* error flag. */ 00719 int index1,index2; /* dummy indices. */ 00720 00721 *jstat = 0; 00722 /* Legal value on ipar ? */ 00723 if (ipar < 0 || ipar > 3) goto err0; 00724 00725 /* Check if pt1 and pt2 are already connected. */ 00726 00727 sh6getlist(pt1,pt2,&index1,&index2,&kstat); 00728 if(kstat < 0) goto err2; 00729 if(kstat > 1) goto err1; /* Not connected. */ 00730 /* 00731 if(pt1->iinter == SI_ORD) pt1->iinter = SI_SING; 00732 else if(pt1->iinter == -SI_ORD) pt1->iinter = -SI_SING; 00733 00734 if(pt2->iinter == SI_ORD) pt2->iinter = SI_SING; 00735 else if(pt2->iinter == -SI_ORD) pt2->iinter = -SI_SING; 00736 */ 00737 /* Set constant direction between pt1 and pt2. */ 00738 pt1->curve_dir[index1] |= (1<<(ipar+1)); 00739 pt2->curve_dir[index2] |= (1<<(ipar+1)); 00740 00741 goto out; 00742 00743 /* Wrong value on ipar. */ 00744 err0: 00745 00746 *jstat = -3; 00747 s6err("sh6setcnsdir",*jstat,0); 00748 goto out; 00749 00750 /* Points are not connected. */ 00751 err1: 00752 00753 *jstat = -1; 00754 s6err("sh6setcnsdir",*jstat,0); 00755 goto out; 00756 00757 /* Error in subfuction. */ 00758 err2: 00759 00760 *jstat = -2; 00761 s6err("sh6setcnsdir",*jstat,0); 00762 goto out; 00763 00764 out : 00765 return; 00766 } 00767 00768 00769 //=========================================================================== 00770 void s6degnorm(SISLSurf *ps1,int ider,double epar[],double eder[], 00771 double utang[],double vtang[],double enorm[],int *jstat) 00772 //=========================================================================== 00773 { 00774 int kstat=0; /* Local status variable. */ 00775 int kpos=0; /* Position of error. */ 00776 int kdim; /* Dimension of the space in which the surface lies. */ 00777 int ki; /* Control variables in for loop */ 00778 double *et1,*et2; /* Local pointer to knot vectors. */ 00779 int in1,in2; /* Number of points in ps1 in the 2 direcs. */ 00780 int ik1,ik2; /* Degree of ps1 in the 2 direcs. */ 00781 double upar,vpar; /* Parameter values. */ 00782 double *xu,*xv; /* Pointers to first derivatives. */ 00783 double *xuu,*xuv,*xvv; /* Pointers to second derivatives. */ 00784 double len; /* Vector length. */ 00785 int ius,ivs,is; /* Flags. u=min => ius = 1, u=max => ius = -1. */ 00786 int endu,endv; /* Flags for whether u or v are extreme. */ 00787 int iu,iv; /* Which first derivs are zero? */ 00788 int iuu,iuv,ivv; /* Which second derivs are zero? */ 00789 double vec[3]; /* Temporary vector. */ 00790 double vec1[3],vec2[3]; /* Temporary vectors. */ 00791 double normal[3]; /* Temporary normal. */ 00792 int usuccess; /* Flag if u tangent found. */ 00793 int vsuccess; /* Flag if v tangent found. */ 00794 00795 00796 /* Set up local variables. */ 00797 00798 kdim = ps1 -> idim; 00799 et1 = ps1 -> et1; 00800 et2 = ps1 -> et2; 00801 in1 = ps1 -> in1; 00802 in2 = ps1 -> in2; 00803 ik1 = ps1 -> ik1; 00804 ik2 = ps1 -> ik2; 00805 00806 /* Check input. */ 00807 00808 if(kdim != 3) goto err101; 00809 if(ider < 2) goto err101; 00810 00811 00812 upar = epar[0]; 00813 vpar = epar[1]; 00814 00815 xu = eder + kdim; 00816 xuu = xu + kdim; 00817 xv = xuu + kdim; 00818 xuv = xv + kdim; 00819 xvv = xuv + kdim + kdim; 00820 00821 /* Find out whether (u,v) is at a corner, edge or in the 00822 middle of the surface ps1. */ 00823 00824 ius = 0; 00825 ivs = 0; 00826 is = 0; 00827 00828 if(upar == et1[ik1-1]) 00829 { 00830 endu = TRUE; 00831 ius = 1; 00832 } 00833 else if(upar == et1[in1]) 00834 { 00835 endu = TRUE; 00836 ius = -1; 00837 } 00838 else 00839 { 00840 endu = FALSE; 00841 } 00842 00843 if(vpar == et2[ik2-1]) 00844 { 00845 endv = TRUE; 00846 ivs = 1; 00847 } 00848 else if(vpar == et2[in2]) 00849 { 00850 endv = TRUE; 00851 ivs = -1; 00852 } 00853 else 00854 { 00855 endv = FALSE; 00856 } 00857 00858 if(endu && endv) is = ius * ivs; 00859 00860 if(!endu && !endv) goto err101; 00861 00862 /* For each derivative, set flag to 0 or 1 according to 00863 whether the length is 0 or non-zero. */ 00864 00865 len = s6length(xu,kdim,&iu); 00866 len = s6length(xv,kdim,&iv); 00867 len = s6length(xuu,kdim,&iuu); 00868 len = s6length(xuv,kdim,&iuv); 00869 len = s6length(xvv,kdim,&ivv); 00870 00871 00872 /* Calculate tangent in u using higher derivatives. */ 00873 00874 usuccess = FALSE; 00875 00876 if(iu == 0) 00877 { 00878 if(endu && iuu == 1) 00879 { 00880 len = s6norm(xuu,kdim,vec,&kstat); 00881 for(ki=0; ki<kdim; ki++) vec[ki]*=ius; 00882 usuccess = TRUE; 00883 } 00884 else if(endv && iuv == 1) 00885 { 00886 len = s6norm(xuv,kdim,vec,&kstat); 00887 for(ki=0; ki<kdim; ki++) vec[ki]*=ivs; 00888 usuccess = TRUE; 00889 } 00890 } 00891 else 00892 { 00893 len = s6norm(xu,kdim,vec,&kstat); 00894 usuccess = TRUE; 00895 } 00896 00897 00898 if(usuccess) 00899 { 00900 /* u tangent found. Return result. */ 00901 00902 for(ki=0; ki<kdim; ki++) utang[ki] = vec[ki]; 00903 } 00904 else 00905 { 00906 /* No u tangent found. Return zero and flag. */ 00907 00908 for(ki=0; ki<kdim; ki++) utang[ki] = (double)0.0; 00909 } 00910 00911 /* Calculate tangent in v using higher derivatives. */ 00912 00913 vsuccess = FALSE; 00914 00915 if(iv == 0) 00916 { 00917 if(endu && iuv == 1) 00918 { 00919 len = s6norm(xuv,kdim,vec,&kstat); 00920 for(ki=0; ki<kdim; ki++) vec[ki]*=ius; 00921 vsuccess = TRUE; 00922 } 00923 else if(endv && ivv == 1) 00924 { 00925 len = s6norm(xvv,kdim,vec,&kstat); 00926 for(ki=0; ki<kdim; ki++) vec[ki]*=ivs; 00927 vsuccess = TRUE; 00928 } 00929 } 00930 else 00931 { 00932 len = s6norm(xv,kdim,vec,&kstat); 00933 vsuccess = TRUE; 00934 } 00935 00936 00937 if(vsuccess) 00938 { 00939 /* v tangent found. Return result. */ 00940 00941 for(ki=0; ki<kdim; ki++) vtang[ki] = vec[ki]; 00942 } 00943 else 00944 { 00945 /* No v tangent found. Return zero and flag. */ 00946 00947 for(ki=0; ki<kdim; ki++) vtang[ki] = (double)0.0; 00948 } 00949 00950 00951 /* Calculate normal using higher derivatives. */ 00952 00953 if(iu == 0) 00954 { 00955 if(iv == 0) 00956 { 00957 if(endu && iuu == 1 && iuv == 1) 00958 { 00959 s6crss(xuu,xuv,vec); 00960 len = s6norm(vec,kdim,normal,&kstat); 00961 if(kstat == 1) goto normfound; 00962 } 00963 if(endv && iuv == 1 && ivv == 1) 00964 { 00965 s6crss(xuv,xvv,vec); 00966 len = s6norm(vec,kdim,normal,&kstat); 00967 if(kstat == 1) goto normfound; 00968 } 00969 if(endu && endv && iuu == 1 && ivv == 1) 00970 { 00971 s6crss(xuu,xvv,vec); 00972 for(ki=0; ki<kdim; ki++) vec[ki]*=is; 00973 len = s6norm(vec,kdim,normal,&kstat); 00974 if(kstat == 1) goto normfound; 00975 } 00976 } 00977 else 00978 { 00979 if(endu && iuu == 1) 00980 { 00981 s6crss(xuu,xv,vec); 00982 for(ki=0; ki<kdim; ki++) vec[ki]*=ius; 00983 len = s6norm(vec,kdim,normal,&kstat); 00984 if(kstat == 1) goto normfound; 00985 } 00986 if(endv && iuv == 1) 00987 { 00988 s6crss(xuv,xv,vec); 00989 for(ki=0; ki<kdim; ki++) vec[ki]*=ivs; 00990 len = s6norm(vec,kdim,normal,&kstat); 00991 if(kstat == 1) goto normfound; 00992 } 00993 } 00994 } 00995 else 00996 { 00997 if(iv == 0) 00998 { 00999 if(endu && iuv == 1) 01000 { 01001 s6crss(xu,xuv,vec); 01002 for(ki=0; ki<kdim; ki++) vec[ki]*=ius; 01003 len = s6norm(vec,kdim,normal,&kstat); 01004 if(kstat == 1) goto normfound; 01005 } 01006 if(endv && iuv == 1) 01007 { 01008 s6crss(xuv,xv,vec); 01009 for(ki=0; ki<kdim; ki++) vec[ki]*=ivs; 01010 len = s6norm(vec,kdim,normal,&kstat); 01011 if(kstat == 1) goto normfound; 01012 } 01013 } 01014 else 01015 { 01016 if(endu && (iuu == 1 || iuv == 1)) 01017 { 01018 s6crss(xuu,xv,vec1); 01019 s6crss(xu,xuv,vec2); 01020 for(ki=0; ki<kdim; ki++) vec[ki]=vec1[ki]+vec2[ki]; 01021 for(ki=0; ki<kdim; ki++) vec[ki]*=ius; 01022 len = s6norm(vec,kdim,normal,&kstat); 01023 if(kstat == 1) goto normfound; 01024 } 01025 if(endv && (iuv == 1 || ivv == 1)) 01026 { 01027 s6crss(xuv,xv,vec1); 01028 s6crss(xu,xvv,vec2); 01029 for(ki=0; ki<kdim; ki++) vec[ki]=vec1[ki]+vec2[ki]; 01030 for(ki=0; ki<kdim; ki++) vec[ki]*=ivs; 01031 len = s6norm(vec,kdim,normal,&kstat); 01032 if(kstat == 1) goto normfound; 01033 } 01034 } 01035 } 01036 01037 /* No normal found. Return zero and flag. */ 01038 01039 for(ki=0; ki<kdim; ki++) enorm[ki] = (double)0.0; 01040 01041 /* Set diagnostics flag. */ 01042 if(usuccess) 01043 { 01044 if(vsuccess) *jstat = 1; 01045 else *jstat = 2; 01046 } 01047 else 01048 { 01049 if(vsuccess) *jstat = 3; 01050 else *jstat = 4; 01051 } 01052 goto out; 01053 01054 /* Normal found and hence tangents found. Return result. */ 01055 01056 normfound: 01057 01058 for(ki=0; ki<kdim; ki++) enorm[ki] = normal[ki]; 01059 *jstat = 0; 01060 goto out; 01061 01062 01063 /* Error in input. */ 01064 01065 err101: *jstat = -101; 01066 s6err("s6degnorm",*jstat,kpos); 01067 goto out; 01068 01069 01070 out: 01071 01072 return; 01073 } 01074 01075 01076 01077 //=========================================================================== 01078 void sh6idrmcross(SISLObject *po1, SISLObject *po2, SISLIntdat **pintdat, 01079 SISLIntpt *vcross[], int incross, SISLIntpt *vpt[], 01080 int inpt, int *jstat) 01081 //=========================================================================== 01082 { 01083 int kstat; /* Status variable. */ 01084 int ki,kj,kl; /* Counters. */ 01085 int kdim; /* Dimension of geometry space. */ 01086 int kleft1 = 0; /* Parameters used in evaluator. */ 01087 int kleft2 = 0; 01088 int kdir1,kdir2; /* Parameter directions. */ 01089 int kpar; /* Number of parameter directions. */ 01090 int k1par = po1->iobj; /* Number of par. dir. in first object. */ 01091 int kmin; /* Number of minimum parameter point. */ 01092 double tmin; /* Length of minimum parameter point as vector. */ 01093 double thelp; /* Help parameter. Length of vector. */ 01094 double sder1[27]; /* Position, derivative etc. of object 1. */ 01095 double sder2[27]; /* Position, derivative etc. of object 2. */ 01096 double stang1[3]; /* Tangent in first parameter dir., deg. surf. */ 01097 double stang2[3]; /* Tangent in second parameter dir., deg. surf. */ 01098 double snorm[3]; /* Normal of degenerated surface. */ 01099 01100 *jstat = 0; 01101 01102 /* Test input. */ 01103 01104 if (incross != 4) goto err138; 01105 01106 if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT) 01107 { 01108 *jstat = 0; 01109 goto out; 01110 } 01111 01112 if (po1->iobj == SISLSURFACE) 01113 { 01114 /* Check if the intersection points have got one parameter in 01115 common. */ 01116 01117 for (kj=0; kj<2; kj++) 01118 { 01119 for (ki=1; ki<incross; ki++) 01120 if (DNEQUAL(vcross[ki]->epar[kj],vcross[0]->epar[kj])) break; 01121 if (ki == incross) break; /* Common parameter direction. */ 01122 } 01123 01124 if (kj == 2) 01125 { 01126 /* No common parameter direction, i.e. no cross intersection 01127 to remove. */ 01128 01129 *jstat = 0; 01130 goto out; 01131 } 01132 01133 /* Set the parameter direction that is not constant. */ 01134 01135 kdir1 = 1 - kj; 01136 } 01137 01138 if (po2->iobj == SISLSURFACE) 01139 { 01140 /* Check if the intersection points have got one parameter in 01141 common. */ 01142 01143 for (kj=po1->iobj, kpar=vcross[0]->ipar; kj<kpar; kj++) 01144 { 01145 for (ki=1; ki<incross; ki++) 01146 if (DNEQUAL(vcross[ki]->epar[kj],vcross[0]->epar[kj])) break; 01147 if (ki == incross) break; /* Common parameter direction. */ 01148 } 01149 01150 if (kj == kpar) 01151 { 01152 /* No common parameter direction, i.e. no cross intersection 01153 to remove. */ 01154 01155 *jstat = 0; 01156 goto out; 01157 } 01158 01159 /* Set the parameter direction that is not constant. */ 01160 01161 kdir2 = kpar - 1 - kj; 01162 } 01163 01164 /* Find the minimum parameter point in which to evaluate. */ 01165 01166 kmin = 0; 01167 tmin = s6length(vcross[0]->epar,vcross[0]->ipar,&kstat); 01168 01169 for (kj=1; kj<incross; kj++) 01170 { 01171 thelp = s6length(vcross[kj]->epar,vcross[kj]->ipar,&kstat); 01172 if (thelp < tmin) 01173 { 01174 tmin = thelp; 01175 kmin = kj; 01176 } 01177 } 01178 01179 /* Compute derivatives. */ 01180 01181 if (po1->iobj == SISLCURVE) 01182 { 01183 kdir1 = 0; 01184 kdim = po1->c1->idim; 01185 s1221(po1->c1,1,vcross[kmin]->epar[kdir1],&kleft1,sder1,&kstat); 01186 if (kstat < 0) goto error; 01187 } 01188 else if (po1->iobj == SISLSURFACE) 01189 { 01190 kdim = po1->s1->idim; 01191 s1424(po1->s1,2,2,vcross[kmin]->epar,&kleft1,&kleft2,sder1, 01192 &kstat); 01193 if (kstat < 0) goto error; 01194 s6crss(sder1+kdim, sder1+2*kdim, snorm); 01195 01196 /* Check if the surface is degenerated in the wanted parameter 01197 direction. */ 01198 01199 if (s6length(sder1+(1+kdir1)*kdim,kdim,&kstat) <= REL_COMP_RES) 01200 { 01201 /* Compute partial derivatives as a limit. */ 01202 01203 s6degnorm(po1->s1,2,vcross[kmin]->epar,sder1,stang1,stang2, 01204 snorm,&kstat); 01205 if (kstat < 0) goto error; 01206 01207 memcopy(sder1+kdim,stang1,kdim,DOUBLE); 01208 memcopy(sder1+2*kdim,stang2,kdim,DOUBLE); 01209 } 01210 } 01211 01212 /* Compute derivatives. */ 01213 01214 if (po2->iobj == SISLCURVE) 01215 { 01216 kdir2 = 0; 01217 s1221(po2->c1,1,vcross[kmin]->epar[k1par+kdir2],&kleft1,sder2,&kstat); 01218 if (kstat < 0) goto error; 01219 } 01220 else if (po2->iobj == SISLSURFACE) 01221 { 01222 s1424(po2->s1,2,2,vcross[kmin]->epar+k1par,&kleft1,&kleft2,sder2, 01223 &kstat); 01224 if (kstat < 0) goto error; 01225 s6crss(sder2+kdim, sder2+2*kdim, snorm); 01226 01227 /* Check if the surface is degenerated in the wanted parameter 01228 direction. */ 01229 01230 if (s6length(sder2+(1+kdir2)*kdim,kdim,&kstat) <= REL_COMP_RES) 01231 { 01232 /* Compute partial derivatives as a limit. */ 01233 01234 s6degnorm(po2->s1,2,vcross[kmin]->epar+k1par,sder2,stang1,stang2, 01235 snorm,&kstat); 01236 if (kstat < 0) goto error; 01237 01238 memcopy(sder2+kdim,stang1,kdim,DOUBLE); 01239 memcopy(sder2+2*kdim,stang2,kdim,DOUBLE); 01240 } 01241 } 01242 01243 if (s6ang(sder1+(kdir1+1)*kdim,sder2+(kdir2+1)*kdim,kdim) > ANGULAR_TOLERANCE 01244 && !(s6length(sder1+(kdir1+1)*kdim,kdim,&kstat) < REL_COMP_RES && 01245 s6length(sder2+(kdir2+1)*kdim,kdim,&kstat) < REL_COMP_RES)) 01246 { 01247 *jstat = 0; 01248 goto out; 01249 } 01250 01251 /* Check if the parameter directions of the objects are the same. */ 01252 01253 if (s6scpr(sder1+(kdir1+1)*kdim,sder2+(kdir2+1)*kdim,kdim) >= 0) 01254 { 01255 /* Remove the pair of intersection point that do not have the 01256 same "parameter direction" in both objects. */ 01257 01258 for (ki=0; ki<incross; ki++) 01259 { 01260 for (kj=1; kj<incross; kj++) 01261 { 01262 if (DNEQUAL(vcross[ki]->epar[kdir1],vcross[kj]->epar[kdir1]) && 01263 DNEQUAL(vcross[ki]->epar[k1par+kdir2], 01264 vcross[kj]->epar[k1par+kdir2])) 01265 { 01266 /* A pair is found. Check if the pair should be removed. */ 01267 01268 if ((vcross[ki]->epar[kdir1] - vcross[kj]->epar[kdir1]) * 01269 (vcross[ki]->epar[k1par+kdir2] - 01270 vcross[kj]->epar[k1par+kdir2]) < 0) 01271 { 01272 /* Remove the points. First make sure that vpt will 01273 not point to killed points. */ 01274 01275 for (kl=0; kl<inpt; kl++) 01276 if (vpt[kl] == vcross[ki] || vpt[kl] == vcross[kj]) 01277 vpt[kl] = SISL_NULL; 01278 01279 sh6idkpt(pintdat,&vcross[ki],1,&kstat); 01280 if (kstat < 0) goto error; 01281 01282 sh6idkpt(pintdat,&vcross[kj],1,&kstat); 01283 if (kstat < 0) goto error; 01284 01285 *jstat = 1; 01286 break; 01287 } 01288 } 01289 } 01290 if (kj < incross) 01291 break; /* The cross intersection is removed */ 01292 } 01293 01294 if (*jstat == 1) goto out; /* Points removed. */ 01295 } 01296 else 01297 { 01298 /* Remove the pair of intersection point that have the 01299 same "parameter direction" in both objects. */ 01300 01301 for (ki=0; ki<incross; ki++) 01302 { 01303 for (kj=1; kj<incross; kj++) 01304 { 01305 if (DNEQUAL(vcross[ki]->epar[kdir1],vcross[kj]->epar[kdir1]) && 01306 DNEQUAL(vcross[ki]->epar[k1par+kdir2], 01307 vcross[kj]->epar[k1par+kdir2])) 01308 { 01309 /* A pair is found. Check if the pair should be removed. */ 01310 01311 if ((vcross[ki]->epar[kdir1] - vcross[kj]->epar[kdir1]) * 01312 (vcross[ki]->epar[k1par+kdir2] - 01313 vcross[kj]->epar[k1par+kdir2]) > 0) 01314 { 01315 /* Remove the points. First make sure that vpt will 01316 not point to killed points. */ 01317 01318 for (kl=0; kl<inpt; kl++) 01319 if (vpt[kl] == vcross[ki] || vpt[kl] == vcross[kj]) 01320 vpt[kl] = SISL_NULL; 01321 01322 sh6idkpt(pintdat,&vcross[ki],1,&kstat); 01323 if (kstat < 0) goto error; 01324 01325 sh6idkpt(pintdat,&vcross[kj],1,&kstat); 01326 if (kstat < 0) goto error; 01327 01328 *jstat = 1; 01329 break; 01330 } 01331 } 01332 } 01333 if (kj < incross) 01334 break; /* The cross intersection is removed */ 01335 } 01336 01337 if (*jstat == 1) goto out; /* Points removed. */ 01338 } 01339 01340 /* No points are removed. Set status. */ 01341 01342 *jstat = 0; 01343 goto out; 01344 01345 01346 /* Wrong number of intersection points. */ 01347 01348 err138 : *jstat = -138; 01349 goto out; 01350 01351 /* Error in lower level routine. */ 01352 01353 error : *jstat = kstat; 01354 goto out; 01355 01356 out : 01357 return; 01358 } 01359 01360 01361 //=========================================================================== 01362 void sh6idfcross(SISLIntdat *pintdat, SISLIntpt *vcross[], int *jncross, 01363 int ipar1, int ipar2, int *jstat) 01364 //=========================================================================== 01365 { 01366 int ki,kj; /* Counters. */ 01367 int kpt; /* Index of last intersection point found. */ 01368 int kpar1; /* Start index of current parameter set. */ 01369 int kpar2; /* Number of parameter in current set. */ 01370 double tdist; /* Distance between parameter points. */ 01371 SISLIntpt *pt; /* Current intersection point. */ 01372 SISLIntpt *qnext; /* Next point to find. */ 01373 01374 01375 /* Test if there is 4 points in pintdat. */ 01376 01377 if (pintdat->ipoint < 4) 01378 { 01379 /* No possibility of cross intersections. */ 01380 01381 *jstat = 0; 01382 return; 01383 } 01384 01385 /* Test if a set of cross intersections is found. */ 01386 01387 if (*jncross == 4) 01388 { 01389 /* Test if the second parameter set of the last intersection point 01390 found is equal to that of the first point. */ 01391 01392 tdist = s6dist(vcross[0]->epar+ipar1,vcross[3]->epar+ipar1,ipar2); 01393 if (DEQUAL(tdist+(double)1.0,(double)1.0)) 01394 /* The set of points is found. */ 01395 01396 *jstat = 1; 01397 else 01398 *jstat = 0; 01399 01400 return; 01401 } 01402 01403 /* Prepare for a search for the next point in the set. */ 01404 01405 kpt = (*jncross) - 1; 01406 pt = vcross[kpt]; 01407 kpar1 = (kpt % 2 == 0) ? 0 : ipar1; 01408 kpar2 = (kpt % 2 == 0) ? ipar1 : ipar2; 01409 01410 /* Traverse the intersection points to find a point that has got 01411 one parameter set equal to the current one. */ 01412 01413 for (ki=0; ki<pintdat->ipoint; ki++) 01414 { 01415 qnext = pintdat->vpoint[ki]; 01416 01417 /* Check if the point is found already. */ 01418 01419 for (kj=0; kj<=kpt; kj++) 01420 if (qnext == vcross[kj]) break; 01421 if (kj <= kpt) continue; 01422 01423 /* Check if the next point belongs to the wanted set. */ 01424 01425 tdist = s6dist(qnext->epar+kpar1,pt->epar+kpar1,kpar2); 01426 if (DEQUAL(tdist+(double)1.0,(double)1.0)) 01427 { 01428 /* A point is found. */ 01429 01430 kpt++; 01431 vcross[kpt] = qnext; 01432 (*jncross)++; 01433 01434 /* Find next point. */ 01435 01436 sh6idfcross(pintdat,vcross,jncross,ipar1,ipar2,jstat); 01437 if (*jstat == 1) return; /* The entire set is found. */ 01438 01439 (*jncross)--; 01440 kpt--; 01441 } 01442 } 01443 01444 /* No set of cross intersections exist. */ 01445 01446 *jstat = 0; 01447 return; 01448 } 01449 01450 01451 //=========================================================================== 01452 void sh6idput (SISLObject * po1, SISLObject * po2, SISLIntdat ** rintdat, 01453 SISLIntdat * pintdat, int inr, double apar, 01454 SISLIntpt *** outintpt, int *npoint, int *jstat) 01455 //=========================================================================== 01456 { 01457 int kstat; /* Local status variable. */ 01458 int kpos = 0; /* Position of error. */ 01459 int ki, kj; /* Counters */ 01460 int keep_first; /* Flag, which object is not enhanced */ 01461 int kant; /* Number of parameters in new points. */ 01462 int ind1, ind2; /* Indexes (not used) */ 01463 int no; /* No. of doubles to copy into geo_aux */ 01464 double *scoef = SISL_NULL; /* Pointer to array copying into geo_aux*/ 01465 double *spar = SISL_NULL; /* Storing uppdated parametervalues. */ 01466 SISLIntpt **uintpt = SISL_NULL; /* Help array while getting connections */ 01467 int iinter; 01468 double *nullp = SISL_NULL; 01469 /* VSK. Remove cross intersections. ---------------------------- */ 01470 int kcross = 1; /* Indicates existence of cross intersections. */ 01471 int kncross = 0; /* Number of cross intersections. */ 01472 int kpt; /* Index in uintpt. */ 01473 SISLIntpt *ucross[4]; /* Cross intersections. */ 01474 01475 *npoint = 0; 01476 01477 /* Find out which object the parameter belongs to */ 01478 if (inr < po1->iobj) 01479 keep_first = 0; 01480 else 01481 keep_first = 1; 01482 01483 /* Do we have an intdat structure? */ 01484 if (pintdat == SISL_NULL) 01485 { 01486 *jstat = 0; 01487 goto out; 01488 } 01489 01490 /* Computing number of new parameter direction. */ 01491 kant = pintdat->vpoint[0]->ipar + 1; 01492 01493 01494 if (inr < 0 || inr >= kant) 01495 goto err191; 01496 01497 *npoint = pintdat->ipoint; 01498 01499 /* Allocate an array for intersection points. */ 01500 if ((uintpt = newarray (pintdat->ipoint, SISLIntpt *)) == SISL_NULL) 01501 goto err101; 01502 01503 /* Allocate an array for parametervalues. */ 01504 if ((spar = newarray (kant, double)) == SISL_NULL) 01505 goto err101; 01506 01507 01508 /* Enhance all intersection points. */ 01509 for (ki = 0; ki < pintdat->ipoint; ki++) 01510 { 01511 /* Insert the missing parameter value. */ 01512 01513 for (kj = 0; kj < inr; kj++) 01514 spar[kj] = pintdat->vpoint[ki]->epar[kj]; 01515 spar[kj] = apar; 01516 for (kj++; kj < kant; kj++) 01517 spar[kj] = pintdat->vpoint[ki]->epar[kj - 1]; 01518 01519 iinter = pintdat->vpoint[ki]->iinter; 01520 01521 uintpt[ki] = hp_newIntpt (kant, spar, pintdat->vpoint[ki]->adist, 01522 iinter, 01523 pintdat->vpoint[ki]->left_obj_1[0], 01524 pintdat->vpoint[ki]->right_obj_1[0], 01525 pintdat->vpoint[ki]->left_obj_2[0], 01526 pintdat->vpoint[ki]->right_obj_2[0], 01527 (keep_first ? pintdat->vpoint[ki]->size_1 : 0), 01528 (keep_first ? 0 : pintdat->vpoint[ki]->size_2), 01529 (keep_first ? pintdat->vpoint[ki]->geo_data_1 : nullp), 01530 (keep_first ? nullp : pintdat->vpoint[ki]->geo_data_2)); 01531 01532 if (uintpt[ki] == SISL_NULL) 01533 goto err101; 01534 01535 /* Store info from lower level object */ 01536 if (keep_first) 01537 { 01538 /* Store second object geometry in geo_aux */ 01539 no = pintdat->vpoint[ki]->size_2; 01540 scoef = pintdat->vpoint[ki]->geo_data_2; 01541 } 01542 else 01543 { 01544 /* Store first object geometry in geo_aux */ 01545 no = pintdat->vpoint[ki]->size_1; 01546 scoef = pintdat->vpoint[ki]->geo_data_1; 01547 } 01548 /* if (no > 0) 01549 memcopy (uintpt[ki]->geo_aux, scoef, (no < 6) ? no : 6, DOUBLE); */ 01550 01551 01552 01553 } 01554 01555 01556 01557 /* Insert all new intersection points in rintdat. */ 01558 for (ki = 0; ki < pintdat->ipoint; ki++) 01559 { 01560 sh6idnpt (rintdat, &uintpt[ki], 1, &kstat); 01561 if (kstat < 0) 01562 goto error; 01563 } 01564 01565 /* Transform the connections. */ 01566 for (ki = 0; ki < pintdat->ipoint; ki++) 01567 { 01568 for (kj = ki + 1; kj < pintdat->ipoint; kj++) 01569 { 01570 sh6getlist (pintdat->vpoint[ki], pintdat->vpoint[kj], 01571 &ind1, &ind2, &kstat); 01572 if (kstat < 0) 01573 goto error; 01574 if (kstat == 0) 01575 { 01576 sh6idcon (rintdat, &uintpt[ki], &uintpt[kj], &kstat); 01577 if (kstat < 0) 01578 goto error; 01579 } 01580 } 01581 01582 if (sh6ismain (pintdat->vpoint[ki]) && 01583 sh6nmbmain (pintdat->vpoint[ki], &kstat)) 01584 { 01585 sh6tomain (uintpt[ki], &kstat); 01586 if (kstat < 0) 01587 goto error; 01588 } 01589 } 01590 01591 if (po1->iobj > SISLPOINT && po2->iobj > SISLPOINT) 01592 { 01593 /* There is a possibility for cross intersections. Check the 01594 intersection data. */ 01595 01596 kpt = 0; 01597 while (kpt < (*npoint)) 01598 { 01599 kncross = 0; 01600 ucross[kncross] = uintpt[kpt]; 01601 kncross = 1; 01602 01603 /* Fetch cross intersections. */ 01604 01605 sh6idfcross(*rintdat,ucross,&kncross,po1->iobj,po2->iobj,&kstat); 01606 kcross = kstat; 01607 01608 if (kcross) 01609 { 01610 /* Remove cross intersections. */ 01611 01612 sh6idrmcross(po1, po2, rintdat, ucross, kncross, uintpt, 01613 *npoint, &kstat); 01614 if (kstat < 0) goto error; 01615 01616 if (kstat) 01617 { 01618 /* Points have been removed. Update uintpt. */ 01619 01620 for (kj=0; kj<*npoint; kj++) 01621 if (uintpt[kj] == SISL_NULL) 01622 { 01623 uintpt[kj] = uintpt[(*npoint)-1]; 01624 kj--; 01625 (*npoint)--; 01626 } 01627 } 01628 else kpt++; 01629 } 01630 else kpt++; 01631 } 01632 } 01633 01634 *jstat = 0; 01635 goto out; 01636 01637 01638 /* Error in inserted parameter number. */ 01639 01640 err191:*jstat = -191; 01641 s6err ("sh6idput", *jstat, kpos); 01642 goto out; 01643 01644 01645 /* Error in space allocation. */ 01646 01647 err101:*jstat = -101; 01648 s6err ("sh6idput", *jstat, kpos); 01649 goto out; 01650 01651 /* Error in sub function. */ 01652 01653 error:*jstat = kstat; 01654 s6err ("sh6idput", *jstat, kpos); 01655 goto out; 01656 01657 out:*outintpt = uintpt; 01658 if (spar != SISL_NULL) 01659 freearray (spar); 01660 } 01661 01662 01663 //=========================================================================== 01664 void sh1992(SISLObject *po,int itype,double aepsge,int *jstat) 01665 //=========================================================================== 01666 { 01667 int kstat = 0; /* Status variable. */ 01668 int kdim; /* Dimension of geometry space. */ 01669 int ktype = itype % 10; /* Kind of box. */ 01670 int knum; /* Number of sides of box. */ 01671 int k2; /* Other box type. */ 01672 int kbez = 0; /* Indicates if Bezier case. */ 01673 double teps_inner; /* Tolerance with which to expand in the inner. */ 01674 double teps_edge; /* Tolerance with which to expand at the edge. */ 01675 01676 /* Set correct tolerances. */ 01677 01678 teps_inner = (ktype == 0) ? DZERO : (double)0.5*aepsge; 01679 teps_edge = (ktype == 2) ? -teps_inner : teps_inner; 01680 01681 if (po -> iobj == SISLPOINT) 01682 { 01683 if (po->p1->pbox == SISL_NULL) 01684 if ((po->p1->pbox = newbox(po->p1->idim)) == SISL_NULL) goto err101; 01685 01686 if (s6existbox(po->p1->pbox,ktype,aepsge) < 1) 01687 { 01688 kdim = po->p1->idim; 01689 if (itype < 10 && kdim == 3) knum = 9; 01690 else if (itype < 10 && kdim == 2) knum = 4; 01691 else knum = kdim; 01692 01693 /* The box do not exist already. For a point we always 01694 use non-expanded boxes. */ 01695 01696 /* Create the box. */ 01697 01698 s6newbox(po->p1->pbox,knum,ktype,aepsge,&kstat); 01699 if (kstat < 0) goto error; 01700 01701 teps_inner = teps_edge = DZERO; 01702 01703 k2 = (ktype == 0) ? 0 : ((ktype == 1) ? 2 : 1); 01704 if (ktype > 0 && s6existbox(po->p1->pbox,k2,aepsge)) 01705 { 01706 memcopy(po->p1->pbox->e2min[ktype],po->p1->pbox->e2min[k2], 01707 (1+(kdim!=1))*knum,double); 01708 memcopy(po->p1->pbox->e2max[ktype],po->p1->pbox->e2max[k2], 01709 (1+(kdim!=1))*knum,double); 01710 } 01711 else 01712 { 01713 /* Make the requested box. */ 01714 01715 if (knum == 9) 01716 sh1992_s9mbox3(po->p1->ecoef,1,1,teps_inner,teps_edge, 01717 po->p1->pbox->e2max[ktype],po->p1->pbox->e2min[ktype]); 01718 else if (knum == 4) 01719 sh1992_s9mbox2(po->p1->ecoef,1,1,teps_inner,teps_edge, 01720 po->p1->pbox->e2max[ktype],po->p1->pbox->e2min[ktype]); 01721 else 01722 { 01723 sh1992_s9mbox(po->p1->ecoef,1,1,kdim,teps_inner,teps_edge, 01724 po->p1->pbox->e2max[ktype],po->p1->pbox->e2min[ktype], 01725 &kstat); 01726 if (kstat < 0) goto error; 01727 } 01728 } 01729 } 01730 } 01731 else if (po -> iobj == SISLCURVE) 01732 { 01733 if (po->c1->pbox == SISL_NULL) 01734 if ((po->c1->pbox = newbox(po->c1->idim)) == SISL_NULL) goto err101; 01735 01736 if (s6existbox(po->c1->pbox,ktype,aepsge) < 1) 01737 { 01738 kdim = po->c1->idim; 01739 if (itype < 10 && kdim == 3) knum = 9; 01740 else if (itype < 10 && kdim == 2) knum = 4; 01741 else knum = kdim; 01742 01743 /* The box do not exist already. In the Bezier case, 01744 it is not necessary to expand in the inner of the curve. */ 01745 01746 /* Create the box. */ 01747 01748 s6newbox(po->c1->pbox,knum,ktype,aepsge,&kstat); 01749 if (kstat < 0) goto error; 01750 01751 if (po->c1->ik == po->c1->in) 01752 { 01753 teps_inner = DZERO; 01754 kbez = 1; 01755 } 01756 01757 /* Make the requested box. First allocate scratch for 01758 box arrays. */ 01759 01760 if (knum == 9) 01761 sh1992_s9mbox3(po->c1->ecoef,po->c1->in,1,teps_inner,teps_edge, 01762 po->c1->pbox->e2max[ktype],po->c1->pbox->e2min[ktype]); 01763 else if (knum == 4) 01764 sh1992_s9mbox2(po->c1->ecoef,po->c1->in,1,teps_inner,teps_edge, 01765 po->c1->pbox->e2max[ktype],po->c1->pbox->e2min[ktype]); 01766 else 01767 { 01768 sh1992_s9mbox(po->c1->ecoef,po->c1->in,1,kdim,teps_inner, 01769 teps_edge,po->c1->pbox->e2max[ktype], 01770 po->c1->pbox->e2min[ktype],&kstat); 01771 if (kstat < 0) goto error; 01772 } 01773 } 01774 } 01775 else if (po -> iobj == SISLSURFACE) 01776 { 01777 if (po->s1->pbox == SISL_NULL) 01778 if ((po->s1->pbox = newbox(po->s1->idim)) == SISL_NULL) goto err101; 01779 01780 if (s6existbox(po->s1->pbox,ktype,aepsge) < 1) 01781 { 01782 kdim = po->s1->idim; 01783 if (itype < 10 && kdim == 3) knum = 9; 01784 else if (itype < 10 && kdim == 2) knum = 4; 01785 else knum = kdim; 01786 01787 /* The box do not exist already. In the Bezier case, it 01788 is not necessary to expand in the inner of the surface. */ 01789 01790 /* Create the box. */ 01791 01792 s6newbox(po->s1->pbox,knum,ktype,aepsge,&kstat); 01793 if (kstat < 0) goto error; 01794 01795 if (po->s1->ik1 == po->s1->in1 && po->s1->ik2 == po->s1->in2) 01796 { 01797 teps_inner = DZERO; 01798 kbez = 1; 01799 } 01800 01801 /* Make the requested box. First allocate scratch for 01802 box arrays. */ 01803 01804 if (knum == 9) 01805 sh1992_s9mbox3(po->s1->ecoef,po->s1->in1,po->s1->in2,teps_inner, 01806 teps_edge,po->s1->pbox->e2max[ktype], 01807 po->s1->pbox->e2min[ktype]); 01808 else if (knum == 4) 01809 sh1992_s9mbox2(po->s1->ecoef,po->s1->in1,po->s1->in2,teps_inner, 01810 teps_edge,po->s1->pbox->e2max[ktype], 01811 po->s1->pbox->e2min[ktype]); 01812 else 01813 { 01814 sh1992_s9mbox(po->s1->ecoef,po->s1->in1,po->s1->in2,kdim, 01815 teps_inner,teps_edge,po->s1->pbox->e2max[ktype], 01816 po->s1->pbox->e2min[ktype],&kstat); 01817 if (kstat < 0) goto error; 01818 } 01819 } 01820 } 01821 01822 *jstat = kbez; 01823 goto out; 01824 01825 /* Error in space allocation. */ 01826 01827 err101 : *jstat = -101; 01828 goto out; 01829 01830 /* Error in lower level routine. */ 01831 01832 error : *jstat = kstat; 01833 goto out; 01834 01835 out: 01836 return; 01837 } 01838 01839 01840 //=========================================================================== 01841 void s9boundimp(double epnt1[],double epar1[],SISLSurf *psurf1,double eimpli[], 01842 int ideg,double apar,int idir,double aepsge, 01843 double gpnt1[],double gpar1[],int *jstat) 01844 //=========================================================================== 01845 { 01846 int kcont; /* Indicator telling if iteration is not finished */ 01847 int kder = 2; /* Derivative indicator */ 01848 int klfu=0; /* Pointer into knot vector */ 01849 int klfv=0; /* Pointer into knot vector */ 01850 int kstat; /* Status variable */ 01851 int knbit=0; /* Counter for number of iterations */ 01852 int kmaxit = 100; /* Maximal number of iterations allowed */ 01853 int kpos=0; /* Position indicator ofr errors */ 01854 int ksize; /* Number of doubles for storage of derivateves 01855 and normal vector */ 01856 int ksizem3; /* ksize - 3 */ 01857 double *sp,*spu,*spv,*spn; /* Pointers into gpnt1 */ 01858 double ta11,ta12,tb1; /* Variables used in equation systems */ 01859 double tdu,tdv; /* Increments of u and v parameter directions */ 01860 double tdist; /* Distance between two points in iteration */ 01861 double tcurdst; /* Distance between points in both surfaces */ 01862 double sder[3]; /* Derivatives of comb. of impl. surf and par.surf*/ 01863 double sproj[3]; /* Projection direction */ 01864 01865 01866 /* If ideg=1,2 or 1001 then only derivatives up to second order 01867 are calculated, then 18 doubles for derivatives and 3 for the 01868 normal vector are to be used for calculation of points in the 01869 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 01870 derivatives up to the third are to be calculated, 01871 thus 30 +3 a total of 33 doubles are to be calculated */ 01872 01873 if (ideg==1003 || ideg==1004 || ideg==1005) 01874 { 01875 kder = 3; 01876 ksize = 33; 01877 } 01878 else 01879 { 01880 ksize = 21; 01881 kder =2; 01882 } 01883 ksizem3 = ksize -3; 01884 01885 /* Copy input variables to output variables */ 01886 01887 memcopy(gpnt1,epnt1,21,DOUBLE); 01888 memcopy(gpar1,epar1,2,DOUBLE); 01889 01890 /* At the start of the iteration the point gpnt1 is put into both implicit 01891 equations */ 01892 01893 /* Set a number of local pointers that are used often */ 01894 sp = gpnt1; 01895 spu = gpnt1 + 3; 01896 spv = gpnt1 + 6; 01897 spn = gpnt1 + 18; 01898 01899 kcont = 1; 01900 01901 while (kcont) 01902 01903 { 01904 /* Independent of which parameter direction is constant we want to 01905 * make an equation: 01906 * du*ta11 + dv*ta12 = tb1 01907 * describing the connection between du and dv. Afterwards du or dv can 01908 * be fixed and dv or du calculated 01909 */ 01910 01911 /* Calculate value and derivatives of the parametric surface put into 01912 the equation of the implicit surface */ 01913 01914 s1331(gpnt1,eimpli,ideg,1,sder,sproj,&kstat); 01915 01916 ta11 = sder[1]; 01917 ta12 = sder[2]; 01918 tb1 = -sder[0]; 01919 01920 01921 /* Now we can branch on the constant parameter dircection */ 01922 01923 if (idir == 1) 01924 { 01925 /* First parameter is constant */ 01926 01927 tdu = apar - gpar1[0]; 01928 if (DNEQUAL(ta12,DZERO) ) 01929 { 01930 tdv = (tb1-tdu*ta11)/ta12; 01931 } 01932 else 01933 { 01934 /* spv is normal to normalvector */ 01935 goto war02; 01936 } 01937 01938 gpar1[0] = apar; 01939 gpar1[1] += tdv; 01940 } 01941 else 01942 { 01943 /* Second parameter direction constant */ 01944 tdv = apar - gpar1[1]; 01945 if (DNEQUAL(ta11,DZERO)) 01946 { 01947 tdu = (tb1-tdv*ta12)/ta11; 01948 } 01949 else 01950 { 01951 /* spv is normal to normalvector */ 01952 goto war02; 01953 } 01954 gpar1[0] += tdu; 01955 gpar1[1] = apar; 01956 } 01957 01958 01959 /* Calculate value of new point */ 01960 01961 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+18,&kstat); 01962 if (kstat<0) goto error; 01963 01964 /* Stop iteration if degenerate point */ 01965 if (kstat == 2) goto war02; 01966 01967 /* Find distance between point and point on implicit surface along sproj 01968 */ 01969 tcurdst = s1309(gpnt1,sproj,eimpli,ideg,&kstat); 01970 if (kstat < 0) goto error; 01971 01972 tcurdst = fabs(tcurdst); 01973 01974 /* tcurdst now contains the distance between the point in the parametric 01975 surface and the projection along sproj of this point onto the implicit 01976 surface if ideg== 1,2 or 1001. In the case ideg==1003,1004,1005 we have a 01977 silhouette line and tcurdst contains the angle PI minus the angle 01978 between the view direction and the normal of the surface */ 01979 01980 01981 /* We continue iteration so long as the error tcurdst is not decreasing */ 01982 01983 knbit = knbit + 1; 01984 01985 if (DEQUAL(tcurdst,DZERO)) 01986 { 01987 /* Length is zero iteration has converged */ 01988 kcont = 0; 01989 goto war00; 01990 } 01991 01992 if (knbit<=1) 01993 { 01994 /* First iteration intitate distance variable, if the equation 01995 systems were not singular */ 01996 tdist = tcurdst; 01997 } 01998 else 01999 { 02000 /* More than one iteration done, stop if distance or angle is not 02001 decreasing. */ 02002 if (tcurdst>=tdist) 02003 { 02004 /* Distance or angle is not decreasing */ 02005 if ( (ideg < 1003 && tdist <= aepsge) || 02006 ( (ideg==1003 || ideg==1004 || ideg==1005) && 02007 tdist <= ANGULAR_TOLERANCE)) 02008 { 02009 /* Distance within tolerance */ 02010 goto war00; 02011 02012 } 02013 else 02014 { 02015 /* Distance is not within tolerance, divergence */ 02016 goto war02; 02017 } 02018 } 02019 /* Distance still decreasing */ 02020 02021 tdist = tcurdst; 02022 } 02023 02024 /* Make sure that not to many iteration are being done */ 02025 if (knbit > kmaxit) goto war02; 02026 } 02027 02028 02029 /* Iteration converged */ 02030 war00: 02031 02032 *jstat = 0; 02033 goto out; 02034 02035 /* To many iterations or iteration diverging */ 02036 war02: *jstat = 2; 02037 goto out; 02038 02039 /* Error in lower level routine. */ 02040 02041 error : *jstat = kstat; 02042 s6err("s9boundimp",*jstat,kpos); 02043 goto out; 02044 02045 out: 02046 return; 02047 } 02048 02049 02050 //=========================================================================== 02051 void s1308(double ep[],int idim,double eimpli[],int ideg,double enorm[],int *jstat) 02052 //=========================================================================== 02053 { 02054 int ki,kj,kl; /* Variables in loop */ 02055 int kdimp1=idim+1; /* Dimension + 1 */ 02056 int kpos=0; /* Position of error */ 02057 int kstat=0; /* Local error */ 02058 double tsum; /* Dummy variable */ 02059 02060 if (ideg != 1 && ideg !=2 && ideg != 1001) goto err175; 02061 02062 if (ideg == 1) 02063 { 02064 /* First degree implicit surface normal vector is eimpli[0:idim-1] */ 02065 memcopy(enorm,eimpli,idim,DOUBLE); 02066 } 02067 else if (ideg==2) 02068 { 02069 02070 /* Calculate the matrix product */ 02071 02072 for (ki=0;ki<idim;ki++) 02073 { 02074 tsum = eimpli[idim*kdimp1+ki]; 02075 for (kj=0,kl=ki ; kj<idim ; kj++,kl+=kdimp1) 02076 { 02077 tsum +=(eimpli[kl]*ep[kj]); 02078 } 02079 enorm[ki] = tsum; 02080 } 02081 } 02082 else if (ideg==1001) 02083 { 02084 /* Torus surface */ 02085 02086 double *scentr; /* The center of the torus */ 02087 double *snorm; /* The normal of the torus symmetry plane */ 02088 double tbigr; /* The big radius of the torus */ 02089 double tsmalr; /* The small radius of the torus */ 02090 double sdum1[3]; /* Temporary storage for point */ 02091 double sdum2[3]; /* Temporary storage for point */ 02092 double tproj; /* Projection of vector onto snorm */ 02093 02094 02095 scentr = eimpli; 02096 snorm = eimpli+3; 02097 tbigr = *(eimpli+6); 02098 tsmalr = *(eimpli+7); 02099 02100 /* Find projection of vector from torus center on to torus axis */ 02101 s6diff(ep,scentr,3,sdum1); 02102 tproj = s6scpr(sdum1,snorm,3); 02103 02104 /* Project vector from torus center to ep onto torus plane */ 02105 for (ki=0;ki<3;ki++) 02106 sdum2[ki] = sdum1[ki] - tproj*snorm[ki]; 02107 (void)s6norm(sdum2,3,sdum2,&kstat); 02108 if (kstat<0) goto error; 02109 02110 /* Find vector from torus circle to ep */ 02111 for (ki=0;ki<3;ki++) 02112 sdum1[ki] = sdum1[ki] - tbigr*sdum2[ki]; 02113 02114 /* Normalize this vector */ 02115 (void)s6norm(sdum1,3,enorm,&kstat); 02116 if (kstat<0) goto error; 02117 } 02118 02119 *jstat = 0; 02120 goto out; 02121 02122 /* IDEG NOT 1 OR 2 */ 02123 err175: 02124 *jstat = -175; 02125 s6err("s1308",*jstat,kpos); 02126 goto out; 02127 02128 02129 /* Error in lower leve function */ 02130 error: 02131 *jstat = kstat; 02132 s6err("s1308",*jstat,kpos); 02133 goto out; 02134 02135 out: 02136 return; 02137 } 02138 02139 02140 02141 //=========================================================================== 02142 void s1001 (SISLSurf * ps, double min1, double min2, 02143 double max1, double max2, 02144 SISLSurf ** rsnew, int *jstat) 02145 //=========================================================================== 02146 { 02147 int kstat; /* Local status variable. */ 02148 int kpos = 0; /* Position of error. */ 02149 int kleft1 = 0; /* Knot navigator. */ 02150 int kleft2 = 0; /* Knot navigator. */ 02151 int kleft3 = 0; /* Knot navigator. */ 02152 int kleft4 = 0; /* Knot navigator. */ 02153 int kdim = ps->idim; /* Dimension of geometry space. */ 02154 int kkind = ps->ikind; /* Kind of surface. */ 02155 int kn1; /* Number of vertices in 1. par. dir. */ 02156 int kn2; /* Number of vertices in 2. par. dir. */ 02157 int cuopen_1, cuopen_2; /* Open flags for the new surface. */ 02158 int change_1,change_2; /* Flag, need to change surf in dir ? */ 02159 int wholeperi1 = FALSE; /* Flag, pick whole peri. param. range */ 02160 int wholeperi2 = FALSE; /* Flag, pick whole peri. param. range */ 02161 double *st1=SISL_NULL; /* Knot vector in 1. par. dir. */ 02162 double *st2=SISL_NULL; /* Knot vector in 2. par. dir. */ 02163 double *scoef1 = SISL_NULL; /* Coefficients of input curve to 02164 refinement in 1. par. dir. */ 02165 double *scoef2 = SISL_NULL; /* Coefficients of refined surface. */ 02166 double *scoef = SISL_NULL; /* Coefficients of refined surface. */ 02167 SISLCurve *qc1 = SISL_NULL; /* Input curve to pick curve. */ 02168 SISLCurve *qc2 = SISL_NULL; /* Output curve from pick curve. */ 02169 SISLCurve *qc3 = SISL_NULL; /* Output curve from pick curve. */ 02170 double *oldcoef; /* Pointer to vertices of old surf. */ 02171 /* ----------------------------------------------------------------- */ 02172 02173 if(kkind == 2 || kkind == 4) 02174 { 02175 oldcoef = ps->rcoef; 02176 kdim++; 02177 } 02178 else 02179 { 02180 oldcoef = ps->ecoef; 02181 } 02182 02183 kleft1=ps->ik1-1; 02184 kleft2=ps->in1; 02185 kleft3=ps->ik2-1; 02186 kleft4=ps->in2; 02187 change_1 = change_2 = TRUE; 02188 02189 if ( min1 == ps->et1[ps->ik1 -1] && max1 == ps->et1[ps->in1] ) 02190 { 02191 if ( s6knotmult(ps->et1,ps->ik1,ps->in1, 02192 &kleft1,ps->et1[ps->ik1-1],&kstat) == ps->ik1 && 02193 s6knotmult(ps->et1,ps->ik1,ps->in1, 02194 &kleft2,ps->et1[ps->in1],&kstat) == ps->ik1 ) 02195 change_1 = FALSE; 02196 else 02197 wholeperi1 = ( ps->cuopen_1 == SISL_SURF_PERIODIC ); 02198 } 02199 02200 if ( min2 == ps->et2[ps->ik2 -1] && max2 == ps->et2[ps->in2] ) 02201 { 02202 if ( s6knotmult(ps->et2,ps->ik2,ps->in2, 02203 &kleft3,ps->et2[ps->ik2-1],&kstat) == ps->ik2 && 02204 s6knotmult(ps->et2,ps->ik2,ps->in2, 02205 &kleft4,ps->et2[ps->in2],&kstat) == ps->ik2 ) 02206 change_2 = FALSE; 02207 else 02208 wholeperi2 = ( ps->cuopen_2 == SISL_SURF_PERIODIC ); 02209 } 02210 02211 if (change_1) 02212 { 02213 /* Treat the first parameter direction of the 02214 surface. First express the surface as a curve. */ 02215 if ((scoef1 = newarray (kdim * ps->in1 * ps->in2, double)) == SISL_NULL) 02216 goto err101; 02217 02218 /* Change parameter directions of surface. */ 02219 s6chpar (oldcoef, ps->in1, ps->in2, kdim, scoef1); 02220 02221 /* Create curve. */ 02222 qc1 = newCurve (ps->in1, ps->ik1, ps->et1, scoef1, 1, kdim * ps->in2, 0); 02223 if (qc1 == SISL_NULL) 02224 goto err101; 02225 qc1->cuopen = ps->cuopen_1; 02226 02227 /* Pick part of curve */ 02228 s1713 (qc1, min1, max1, &qc2, &kstat); 02229 if (kstat < 0) 02230 goto error; 02231 02232 /* Change parameter directions of the coefficient array of 02233 the refined curve. */ 02234 02235 if ((scoef2 = newarray (qc2->in *ps->in2 * kdim, DOUBLE)) == SISL_NULL) 02236 goto err101; 02237 s6chpar (qc2->ecoef, ps->in2, qc2->in, kdim, scoef2); 02238 02239 /* Set local parameters of refined surface. */ 02240 02241 kn1 = qc2->in; 02242 kn2 = ps->in2; 02243 st1 = qc2->et; 02244 st2 = ps->et2; 02245 if ( wholeperi1 ) 02246 cuopen_1 = SISL_SURF_CLOSED; 02247 else 02248 cuopen_1 = qc2->cuopen; 02249 02250 /* Free curve used as input to s1713. */ 02251 if (qc1) 02252 freeCurve (qc1); 02253 qc1 = SISL_NULL; 02254 } 02255 02256 else 02257 { 02258 /* Set local parameters of input surface. */ 02259 02260 kn1 = ps -> in1; 02261 kn2 = ps -> in2; 02262 st1 = ps -> et1; 02263 st2 = ps -> et2; 02264 scoef2 = oldcoef; 02265 cuopen_1 = ps->cuopen_1; 02266 } 02267 02268 if (change_2) 02269 { 02270 /* Treat the first parameter direction of the 02271 surface. First express the surface as a curve. */ 02272 02273 if ((qc1 = newCurve (kn2, ps->ik2, st2, scoef2, 1, kn1 * kdim, 0)) 02274 == SISL_NULL) 02275 goto err101; 02276 qc1->cuopen = ps->cuopen_2; 02277 02278 /* Pick part of curve */ 02279 s1713 (qc1, min2, max2, &qc3, &kstat); 02280 if (kstat < 0) 02281 goto error; 02282 02283 02284 /* Set local parameters of the refined surface. */ 02285 kn2 = qc3->in; 02286 st2 = qc3->et; 02287 scoef = qc3->ecoef; 02288 if ( wholeperi2 ) 02289 cuopen_2 = SISL_SURF_CLOSED; 02290 else 02291 cuopen_2 = qc3->cuopen; 02292 02293 /* Free curve used as input to s1713. */ 02294 if (qc1) 02295 freeCurve (qc1); 02296 qc1 = SISL_NULL; 02297 } 02298 else 02299 { 02300 scoef = scoef2; 02301 cuopen_2 = ps->cuopen_2; 02302 } 02303 02304 /* Express result as a surface. */ 02305 if ((*rsnew = newSurf (kn1, kn2, ps->ik1, ps->ik2, st1, st2, 02306 scoef, kkind, ps->idim, 1)) == SISL_NULL) 02307 goto err101; 02308 02309 02310 (*rsnew)->cuopen_1 = cuopen_1; 02311 (*rsnew)->cuopen_2 = cuopen_2; 02312 02313 /* Task done */ 02314 02315 *jstat = 0; 02316 goto out; 02317 02318 /* ---------------------- ERROR EXITS ------------------------------- */ 02319 /* Error in scratch allocation. */ 02320 02321 err101: 02322 *jstat = -101; 02323 s6err ("s1001", *jstat, kpos); 02324 goto out; 02325 02326 /* Error in lower level routine. */ 02327 02328 error: 02329 *jstat = kstat; 02330 s6err ("s1001", *jstat, kpos); 02331 goto out; 02332 02333 out: 02334 /* Free scratch occupied by local arrays and objects. */ 02335 02336 if (change_1) 02337 { 02338 if (scoef1) freearray (scoef1); 02339 if (scoef2) freearray (scoef2); 02340 scoef1 = SISL_NULL; 02341 scoef2 = SISL_NULL; 02342 } 02343 02344 if (qc1) freeCurve (qc1); 02345 if (qc2) freeCurve (qc2); 02346 if (qc3) freeCurve (qc3); 02347 } 02348 02349 02350 //=========================================================================== 02351 void s6crvcheck(SISLCurve *pc,int *jstat) 02352 //=========================================================================== 02353 { 02354 int kstat = 0; /* Status variable. */ 02355 int ki,kj; /* Counter. */ 02356 int kdim; /* Dimension of space */ 02357 int rdim; /* Rational dimension. */ 02358 int kn; /* Number of knots */ 02359 int kk; /* Number of vertices */ 02360 int kmark; /* Indicates if k-tupple knots */ 02361 int knnew; /* New number of vertices */ 02362 int kind; /* Type of curve, 2 and 4 rational. */ 02363 double *snt=SISL_NULL; /* Compressed knot vector */ 02364 double *sncoef=SISL_NULL; /* Compressed vertex vector */ 02365 double *srcoef=SISL_NULL; /* Compressed vertex vector */ 02366 double *st; /* Knots */ 02367 double *scoef; /* Vertices */ 02368 double *rcoef; /* Rational vertices. */ 02369 02370 *jstat = 0; 02371 02372 if (pc == SISL_NULL) goto out; 02373 02374 kk = pc -> ik; 02375 kn = pc -> in; 02376 kdim = pc -> idim; 02377 rdim = kdim + 1; 02378 kind = pc -> ikind; 02379 st = pc -> et; 02380 scoef = pc -> ecoef; 02381 rcoef = pc -> rcoef; 02382 02383 /* Run through all knots to detect if st[ki]=st[ki+kk-1] e.g. that we 02384 have at least kk-tupple internal knots */ 02385 02386 kmark = 0; 02387 for (ki=1 ; ki < kn-1 ; ki++) 02388 if (st[ki] == st[ki+kk-1] && 02389 DEQUAL(s6dist(scoef+(ki-1)*kdim,scoef+ki*kdim,kdim),DZERO)) 02390 { 02391 kmark = 1; 02392 break; 02393 } 02394 02395 if (kmark == 0) goto out; 02396 02397 /* We have at least kk-tupple knots, remove not necessary knots and vertices */ 02398 02399 if((snt = newarray(kn+kk,DOUBLE)) == SISL_NULL) goto err101; 02400 if((sncoef = newarray(kn*kdim,DOUBLE)) == SISL_NULL) goto err101; 02401 02402 if (kind == 2 || kind == 4) 02403 { 02404 srcoef = newarray(kn*rdim,DOUBLE); 02405 if (srcoef == SISL_NULL) goto err101; 02406 for (ki=0,kj=0 ; ki < kn ; ki ++) 02407 if (ki == 0 || ki == kn-1 || st[ki] < st[ki+kk-1] || 02408 DNEQUAL(s6dist(rcoef+(ki-1)*rdim,rcoef+ki*rdim,rdim),DZERO)) 02409 { 02410 snt[kj] = st[ki]; 02411 memcopy(sncoef+kdim*kj,scoef+kdim*ki,kdim,DOUBLE); 02412 memcopy(srcoef+rdim*kj,rcoef+rdim*ki,rdim,DOUBLE); 02413 kj++; 02414 } 02415 } 02416 else 02417 { 02418 for (ki=0,kj=0 ; ki < kn ; ki ++) 02419 if (ki == 0 || ki == kn-1 || st[ki] < st[ki+kk-1] || 02420 DNEQUAL(s6dist(scoef+(ki-1)*kdim,scoef+ki*kdim,kdim),DZERO)) 02421 { 02422 snt[kj] = st[ki]; 02423 memcopy(sncoef+kdim*kj,scoef+kdim*ki,kdim,DOUBLE); 02424 kj++; 02425 } 02426 } 02427 02428 for (ki=kn ; ki<kn+kk ; ki++,kj++) 02429 snt[kj] = st[ki]; 02430 02431 knnew = kj - kk; 02432 02433 /* An additional end knot might have been left */ 02434 02435 if (snt[knnew-1] == snt[knnew+kk-1]) knnew--; 02436 02437 /* Put compressed description back to curve object */ 02438 02439 if (pc->icopy > 0) 02440 { 02441 pc -> in = knnew; 02442 memcopy(pc->et,snt,knnew+kk,DOUBLE); 02443 memcopy(pc->ecoef,sncoef,knnew*kdim,DOUBLE); 02444 if (kind == 2 || kind == 4) 02445 memcopy(pc->rcoef,srcoef,knnew*rdim,DOUBLE); 02446 kstat = 1; 02447 } 02448 02449 /* Task done. */ 02450 02451 *jstat = kstat; 02452 goto out; 02453 02454 /* Error in space allocation. */ 02455 02456 err101: 02457 *jstat = -101; 02458 goto out; 02459 02460 out: 02461 if (snt != SISL_NULL) freearray(snt); 02462 if (sncoef != SISL_NULL) freearray(sncoef); 02463 } 02464 02465 02466 //=========================================================================== 02467 void s1379(double ep[],double ev[],double epar[],int im,int idim, 02468 SISLCurve **rcurve,int *jstat) 02469 //=========================================================================== 02470 { 02471 int ki,kj; /* Loop variables */ 02472 int kk; /* Polynomial order */ 02473 int kn; /* Number of vertices */ 02474 int kpoint; /* Pointer into point and derivative array */ 02475 int kcoef; /* Pointer into coefficient array */ 02476 int kpos=0; /* Position of error */ 02477 int kthis; /* Current point */ 02478 int kstat=0; /* Status variable */ 02479 int kcycpos = 1; /* Flag telling if first and last points are equal */ 02480 int kcycder = 1; /* Flag telling if first and last derviatives are equal */ 02481 double *st=SISL_NULL; /* Knot vector */ 02482 double *scoef=SISL_NULL; /* B-spline vertices */ 02483 double th1,th2; /* Parameter intervals */ 02484 02485 02486 02487 /* Check input */ 02488 02489 if (im < 2) goto err181; 02490 if (idim < 1) goto err102; 02491 02492 /* Set the dimension and order of the spline space */ 02493 02494 kn = 2*im; 02495 kk = 4; 02496 02497 /* Allocate arrays for temporary storage of knots and vertices */ 02498 02499 st = newarray(kn+kk,DOUBLE); 02500 if (st == SISL_NULL) goto err101; 02501 scoef = newarray(idim*kn,DOUBLE); 02502 if (scoef == SISL_NULL) goto err101; 02503 02504 /* Check if the curve is periodic, e.g. if first and last points are 02505 equal and/or that first and last derivates are equal */ 02506 02507 /* for (kj=0, kcycpos=1 ; kj<idim && kcycpos == 1 ; kj++) 02508 if (ep[kj] != ep[idim*(im-1)+kj]) kcycpos =0; */ 02509 for (kj=0, kcycpos=1 ; kj<idim && kcycpos == 1 ; kj++) 02510 if (DNEQUAL(ep[kj], ep[idim*(im-1)+kj])) kcycpos =0; 02511 02512 /* for (kj=0, kcycder=1 ; kj<idim && kcycder == 1 ; kj++) 02513 if (ev[kj] != ev[idim*(im-1)+kj]) kcycder= 0; */ 02514 for (kj=0, kcycder=1 ; kj<idim && kcycder == 1 ; kj++) 02515 if (DNEQUAL(ev[kj], ev[idim*(im-1)+kj])) kcycder= 0; 02516 02517 /* Make the knot vector, first all knots except the two first and the two last */ 02518 02519 for (ki=2,kj=0 ; ki<kn+2 ; ki+=2, kj++) 02520 st[ki] = st[ki+1] = epar[kj]; 02521 02522 02523 02524 /* Make the two first and two last knots */ 02525 02526 if (kcycder == 1 && kcycpos == 1) 02527 { 02528 /* Two first knots to be shifted */ 02529 02530 st[0]= st[1] = epar[0] - (epar[im-1]-epar[im-2]); 02531 st[kn+2]= st[kn+3] = epar[im-1] + epar[1] - epar[0]; 02532 } 02533 else if (kcycder ==0 && kcycpos ==1) 02534 { 02535 /* First and last knot to be shifted */ 02536 02537 st[0] = epar[0] - (epar[im-1]-epar[im-2]); 02538 st[1] = st[2]; 02539 st[kn+2] = st[kn]; 02540 st[kn+3] = epar[im-1] + epar[1] - epar[0]; 02541 } 02542 else 02543 { 02544 /* k-regular basis */ 02545 02546 st[0] = st[1] = st[2]; 02547 st[kn+2] = st[kn+3] = st[kn]; 02548 } 02549 02550 /* Compute knot vector and coefficients as indicated above */ 02551 02552 for (kj=0, kcoef=0, kpoint = 0 ; kj < kn ; kj+=2) 02553 { 02554 th1 = st[kj+3] - st[kj+1]; 02555 th2 = st[kj+4] - st[kj+2]; 02556 02557 /* Compute coefficient no kj */ 02558 02559 kthis = kpoint; 02560 for (ki=0;ki<idim;ki++,kpoint++) 02561 { 02562 scoef[kcoef++] = ep[kpoint] - th1*ONE_THIRD*ev[kpoint]; 02563 } 02564 02565 /* Compute coefficient no kj+1 */ 02566 02567 kpoint = kthis; 02568 for (ki=0;ki<idim;ki++,kpoint++) 02569 { 02570 scoef[kcoef++] = ep[kpoint] + th2*ONE_THIRD*ev[kpoint]; 02571 } 02572 } 02573 02574 /* Make new curve object */ 02575 02576 *rcurve = newCurve(kn,kk,st,scoef,1,idim,1); 02577 if (*rcurve == SISL_NULL) goto err101; 02578 02579 /* Remove unneccesarry knots */ 02580 02581 s6crvcheck(*rcurve,&kstat); 02582 if (kstat<0) goto error; 02583 02584 /* Periodicity flag */ 02585 if (kcycpos) 02586 { 02587 test_cyclic_knots((*rcurve)->et,(*rcurve)->in,(*rcurve)->ik,&kstat); 02588 if (kstat<0) goto error; 02589 if (kstat == 2) (*rcurve)->cuopen = SISL_CRV_PERIODIC; 02590 } 02591 02592 /* Calculation completed */ 02593 02594 *jstat = 0; 02595 goto out; 02596 02597 02598 /* Error in space allocation. Return zero. */ 02599 02600 02601 /* Error in space allocation */ 02602 err101: *jstat = -101; 02603 s6err("s1379",*jstat,kpos); 02604 goto out; 02605 02606 02607 /* Dimension less than 1*/ 02608 err102: *jstat = -102; 02609 s6err("s1379",*jstat,kpos); 02610 goto out; 02611 02612 /* Too few interpolation conditions */ 02613 02614 err181: *jstat = -181; 02615 s6err("s1379",*jstat,kpos); 02616 goto out; 02617 02618 error: *jstat =kstat; 02619 s6err("s1379",*jstat,kpos); 02620 goto out; 02621 02622 out: 02623 if (st != SISL_NULL) freearray(st); 02624 if (scoef != SISL_NULL) freearray(scoef); 02625 02626 return; 02627 } 02628 02629 02630 //=========================================================================== 02631 void s6twonorm(double evec[],double enorm1[],double enorm2[],int *jstat) 02632 //=========================================================================== 02633 { 02634 int kstat; /* Local status variable */ 02635 int kdim = 3; /* We work in 3-D */ 02636 int kpos=0; /* Position of eror */ 02637 double svec[3],sdum[3]; /* Local dummy arrays */ 02638 double t1,t2,t3; /* Absolute value of components of svec */ 02639 02640 02641 /* If the dimension is 1 the length of the vector is the same as the 02642 absolute value of the number */ 02643 02644 02645 /* Normalize input vector */ 02646 02647 (void)s6norm(evec,kdim,svec,&kstat); 02648 02649 if (kstat == 0) goto err174; 02650 02651 t1 =fabs(svec[0]); 02652 t2 =fabs(svec[1]); 02653 t3 =fabs(svec[2]); 02654 02655 /* Make along one of the main axis that has component 1 in the direction 02656 that svec has the smalles component */ 02657 02658 sdum[0] = (double)0.0; 02659 sdum[1] = (double)0.0; 02660 sdum[2] = (double)0.0; 02661 02662 if (t1 < t2 && t1 < t3) 02663 { 02664 sdum[0] = (double)1.0; 02665 } 02666 else if (t2 < t3) 02667 { 02668 sdum[1] = (double)1.0; 02669 } 02670 else 02671 { 02672 sdum[2] = (double)1.0; 02673 } 02674 02675 /* Make normal of sdum and svec */ 02676 02677 s6crss(svec,sdum,enorm1); 02678 02679 /* Normalize enorm1 */ 02680 02681 (void)s6norm(enorm1,kdim,enorm1,&kstat); 02682 02683 /* Make normal of enorm1 and svec */ 02684 02685 s6crss(svec,enorm1,enorm2); 02686 02687 /* Normalize enorm2 */ 02688 02689 (void)s6norm(enorm2,kdim,enorm2,&kstat); 02690 02691 *jstat = 0; 02692 goto out; 02693 02694 /* Direction vector of zero length */ 02695 02696 err174: *jstat = -174; 02697 s6err("s6twonorm",*jstat,kpos); 02698 goto out; 02699 out: 02700 return; 02701 } 02702 02703 02704 //=========================================================================== 02705 void s9boundit(double epnt1[],double epnt2[],double epar1[],double epar2[], 02706 SISLSurf *psurf1,SISLSurf *psurf2,double apar,int idir,double aepsge, 02707 double gpnt1[],double gpnt2[],double gpar1[],double gpar2[],int *jstat) 02708 //=========================================================================== 02709 { 02710 int kcont; /* Indicator telling if iteration is not finished */ 02711 int kder = 2; /* Derivative indicator */ 02712 int klfu=0; /* Pointer into knot vector */ 02713 int klfv=0; /* Pointer into knot vector */ 02714 int klfs=0; /* Pointer into knot vector */ 02715 int klft=0; /* Pointer into knot vector */ 02716 int kstat; /* Status variable */ 02717 int knbit=0; /* Counter for number of iterations */ 02718 int kdim = 3; /* Set dimension to 3 */ 02719 int kmaxit = 100; /* Maximal number of iterations allowed */ 02720 int kpos=1; /* Position indicator ofr errors */ 02721 double snorm1[3]; /* Normalvector to constant parameter line */ 02722 double snorm2[3]; /* Normalvector to constant parameter line */ 02723 double *sp,*spu,*spv,*spn; /* Pointers into gpnt1 */ 02724 double *sq,*sqs,*sqt,*sqn; /* Pointers into gpnt2 */ 02725 double ta11,ta12,ta21; /* Variables used in equation systems */ 02726 double ta22,tb1,tb2; /* Variables used in equation systems */ 02727 double sdiff[3]; /* Difference between two vectors */ 02728 double tdum2; /* Dummy variables */ 02729 double tdum3; /* Dummy variables */ 02730 double tdist; /* Distance betweentwo points in iteration */ 02731 double tdu,tdv,tds,tdt; /* Increments of parameter values */ 02732 02733 02734 /* Copy input variables to output variables */ 02735 02736 memcopy(gpnt1,epnt1,21,DOUBLE); 02737 memcopy(gpnt2,epnt2,21,DOUBLE); 02738 memcopy(gpar1,epar1,2,DOUBLE); 02739 memcopy(gpar2,epar2,2,DOUBLE); 02740 02741 /* At the start of the iteration the two point gpnt1 and gpnt2 might be 02742 very close since we in most cases start from a point on the intersection 02743 curve. */ 02744 02745 /* Set a number of local pointers that are used often */ 02746 sp = gpnt1; 02747 spu = gpnt1 + 3; 02748 spv = gpnt1 + 6; 02749 spn = gpnt1 + 18; 02750 sq = gpnt2; 02751 sqs = gpnt2 + 3; 02752 sqt = gpnt2 + 6; 02753 sqn = gpnt2 + 18; 02754 02755 kcont = 1; 02756 02757 while (kcont) 02758 02759 { 02760 if (idir==1 || idir==2) 02761 { 02762 /* The constant parameter direction is in the first surface, intersect 02763 with implicit representation of tangent plane of second surface. 02764 Independent of which parameter direction is constant we want to 02765 make an equation: 02766 du*ta11 + dv*ta12 = tb1 02767 describing the connection between du and dv. Afterwards du or dv can 02768 be fixed and dv or du calculated 02769 02770 Put a parametric representation of the tangent plane of surface 1 into 02771 the implicit representation of the tangent plane of surface 2. 02772 */ 02773 02774 ta11 = s6scpr(spu,sqn,kdim); 02775 ta12 = s6scpr(spv,sqn,kdim); 02776 s6diff(sq,sp,kdim,sdiff); 02777 02778 tb1 = s6scpr(sdiff,sqn,kdim); 02779 02780 /* Now we can branch on the constant parameter direction */ 02781 02782 if (idir == 1) 02783 { 02784 /* First parameter is constant */ 02785 02786 tdu = apar - gpar1[0]; 02787 if (DNEQUAL(ta12,DZERO)) 02788 { 02789 tdv = (tb1-tdu*ta11)/ta12; 02790 } 02791 else 02792 { 02793 /* spv is normal to normalvector */ 02794 goto war02; 02795 } 02796 02797 gpar1[0] = apar; 02798 gpar1[1] += tdv; 02799 } 02800 else 02801 { 02802 /* Second parameter direction constant */ 02803 tdv = apar - gpar1[1]; 02804 if (DNEQUAL(ta11,DZERO)) 02805 { 02806 tdu = (tb1-tdv*ta12)/ta11; 02807 } 02808 else 02809 { 02810 /* spv is normal to normalvector */ 02811 goto war02; 02812 } 02813 gpar1[0] += tdu; 02814 gpar1[1] = apar; 02815 } 02816 02817 /* Calculate the point found in first surface */ 02818 02819 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+18,&kstat); 02820 if (kstat<0) goto error; 02821 02822 /* If the surface has normal of zero length leave the routine */ 02823 02824 if (kstat == 2) goto war02; 02825 02826 /* Make the difference of the found point and sq */ 02827 02828 s6diff(gpnt1,sq,kdim,sdiff); 02829 02830 02831 /* Project the point onto surface 2 along the normal sqn */ 02832 02833 02834 /* Make two normals to the normal of surface two in last point */ 02835 02836 s6twonorm(sqn,snorm1,snorm2,&kstat); 02837 if (kstat<0) goto error; 02838 02839 ta11 = s6scpr(sqs,snorm1,kdim); 02840 ta12 = s6scpr(sqt,snorm1,kdim); 02841 ta21 = s6scpr(sqs,snorm2,kdim); 02842 ta22 = s6scpr(sqt,snorm2,kdim); 02843 02844 tb1 = s6scpr(sdiff,snorm1,kdim); 02845 02846 tb2 = s6scpr(sdiff,snorm2,kdim); 02847 02848 /* Calculate determinant of equation system */ 02849 tdum2 = ta11*ta22 - ta12*ta21; 02850 02851 /* If tdum2 = 0.0, then the equation system is singular, iteration not 02852 possible. */ 02853 if (DNEQUAL(tdum2,DZERO)) 02854 { 02855 gpar2[0] += (tb1*ta22-tb2*ta12)/tdum2; 02856 gpar2[1] += (ta11*tb2-ta21*tb1)/tdum2; 02857 } 02858 02859 /* Calculate point in second surface */ 02860 02861 s1421(psurf2,kder,gpar2,&klfs,&klft,gpnt2,gpnt2+18,&kstat); 02862 if (kstat<0) goto error; 02863 02864 /* If the surface has normal of zero length leave the routine */ 02865 02866 if (kstat == 2) goto war02; 02867 } 02868 02869 else 02870 { 02871 /* idir==3 or idir==4 */ 02872 02873 /* The constant parameter direction is in the second surface, intersect 02874 with implicit representation of tangent plane of second surface. 02875 Independent of which parameter direction is constant we want to 02876 make an equation: 02877 ds*ta11 + dt*ta12 = tb1 02878 describing the connection between ds and dt. Afterwards ds or dt can 02879 be fixed and dt or ds calculated 02880 02881 Put a parametric representation of the tangent plane of surface 2 into 02882 the implicit representation of the tangent plane of surface 1. 02883 */ 02884 02885 ta11 = s6scpr(sqs,spn,kdim); 02886 ta12 = s6scpr(sqt,spn,kdim); 02887 s6diff(sp,sq,kdim,sdiff); 02888 02889 tb1 = s6scpr(sdiff,spn,kdim); 02890 02891 /* Now we can branch on the constant parameter direction */ 02892 02893 if (idir == 3) 02894 { 02895 /* First parameter is constant */ 02896 02897 tds = apar - gpar2[0]; 02898 if (DNEQUAL(ta12,DZERO)) 02899 { 02900 tdt = (tb1-tds*ta11)/ta12; 02901 } 02902 else 02903 { 02904 /* sqt is normal to normalvector */ 02905 goto war02; 02906 } 02907 02908 gpar2[0] = apar; 02909 gpar2[1] += tdt; 02910 } 02911 else 02912 { 02913 /* Second parameter direction constant */ 02914 tdt = apar - gpar2[1]; 02915 if (DNEQUAL(ta11,DZERO)) 02916 { 02917 tds = (tb1-tdt*ta12)/ta11; 02918 } 02919 else 02920 { 02921 /* spv is normal to normalvector */ 02922 goto war02; 02923 } 02924 gpar2[0] += tds; 02925 gpar2[1] = apar; 02926 02927 } 02928 02929 /* Calculate the point found in first surface */ 02930 02931 s1421(psurf2,kder,gpar2,&klfs,&klft,gpnt2,gpnt2+18,&kstat); 02932 if (kstat<0) goto error; 02933 02934 /* If the surface has normal of zero length leave the routine */ 02935 02936 if (kstat == 2) goto war02; 02937 02938 /* Make the difference of the found point and sq */ 02939 02940 s6diff(gpnt2,sp,kdim,sdiff); 02941 02942 02943 /* Project the point onto surface 2 along the normal spn */ 02944 02945 02946 /* Make two normals to the normal of surface one in last point */ 02947 02948 s6twonorm(spn,snorm1,snorm2,&kstat); 02949 if (kstat<0) goto error; 02950 02951 02952 /* Put a parametric representation of the tangent plane of surface 1 into 02953 the implicit representation of the tangent planes of the constant 02954 parameter line of surface 2 */ 02955 02956 ta11 = s6scpr(spu,snorm1,kdim); 02957 ta12 = s6scpr(spv,snorm1,kdim); 02958 ta21 = s6scpr(spu,snorm2,kdim); 02959 ta22 = s6scpr(spv,snorm2,kdim); 02960 02961 tb1 = s6scpr(sdiff,snorm1,kdim); 02962 02963 tb2 = s6scpr(sdiff,snorm2,kdim); 02964 02965 /* Calculate determinant of equation system */ 02966 02967 tdum2 = ta11*ta22 - ta12*ta21; 02968 02969 /* If tdum2 = 0.0, then the equation system is singular, iteration not 02970 possible. */ 02971 02972 if (DNEQUAL(tdum2,DZERO)) 02973 { 02974 gpar1[0] += (tb1*ta22-tb2*ta12)/tdum2; 02975 gpar1[1] += (ta11*tb2-ta21*tb1)/tdum2; 02976 } 02977 02978 /* Calculate point in first surface */ 02979 02980 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+18,&kstat); 02981 if (kstat<0) goto error; 02982 02983 /* If the surface has normal of zero length leave the routine */ 02984 02985 if (kstat == 2) goto war02; 02986 } 02987 02988 02989 /* Make difference between the two points, 02990 and calculate length of difference */ 02991 02992 s6diff(gpnt1,gpnt2,kdim,sdiff); 02993 tdum3 = s6length(sdiff,kdim,&kstat); 02994 knbit = knbit + 1; 02995 02996 if (kstat==0) 02997 { 02998 /* Length is zero iteration has converged */ 02999 kcont = 0; 03000 goto war00; 03001 } 03002 03003 if (knbit<=1) 03004 { 03005 /* First iteration intitate distance variable, if the equation 03006 systems were not singular */ 03007 03008 if (DEQUAL(tdum2,DZERO)) goto war02; 03009 tdist = tdum3; 03010 } 03011 else 03012 { 03013 /* More than one iteration done, stop if distance is not decreasing. 03014 Then decide if we converge distance between the points is within 03015 the tolerance and the last step had singular or none singular 03016 equation systems. */ 03017 03018 if (tdum3>=tdist) 03019 { 03020 /* Distance is not decreasing */ 03021 if (tdist <= aepsge) 03022 { 03023 /* Distance within tolerance */ 03024 if (DEQUAL(tdum2,DZERO)) 03025 { 03026 /* Singular equation system */ 03027 goto war01; 03028 } 03029 else 03030 { 03031 /* Nonsingular equation system */ 03032 goto war00; 03033 } 03034 } 03035 else 03036 { 03037 /* Distance is not within tolerance, divergence */ 03038 goto war02; 03039 } 03040 } 03041 /* Distance still decreasing */ 03042 03043 tdist = tdum3; 03044 } 03045 03046 /* Make sure that not to many iteration are being done */ 03047 if (knbit > kmaxit) goto war02; 03048 } 03049 03050 03051 /* Iteration converged */ 03052 03053 war00: 03054 *jstat = 0; 03055 goto out; 03056 03057 /* Iteration converged, singular point found */ 03058 03059 war01: 03060 *jstat = 1; 03061 goto out; 03062 03063 /* To many iterations or iteration diverging */ 03064 03065 war02: 03066 *jstat = 2; 03067 goto out; 03068 03069 /* Error in lower level routine. */ 03070 03071 error : *jstat = kstat; 03072 s6err("s9boundit",*jstat,kpos); 03073 goto out; 03074 03075 out: 03076 return; 03077 } 03078 03079 03080 //=========================================================================== 03081 void s1602(double estapt[],double endpt[],int ik,int idim,double astpar, 03082 double *cendpar,SISLCurve **rc,int *jstat) 03083 //=========================================================================== 03084 { 03085 int kit; /* Loop control */ 03086 int kit2; /* Loop contero */ 03087 int kvert; /* Counter for position in vertex array */ 03088 int kpos=0; /* Position of error */ 03089 03090 double *st=SISL_NULL; /* Pointer to the first element of the knot vector 03091 of the curve. */ 03092 double *scoef=SISL_NULL; /* Pointer to the first element of the curve's 03093 B-spline coefficients. */ 03094 double tdist; /* Distance */ 03095 double tdel; /* Delta x, y , .... */ 03096 03097 /* Check input */ 03098 03099 if (idim < 1) goto err102; 03100 if (ik < 2) goto err109; 03101 03102 /* Find distance between start nd end point */ 03103 tdist = s6dist(estapt,endpt,idim); 03104 03105 03106 /* Make knots. First allocate space */ 03107 03108 st = newarray(ik*2,DOUBLE); 03109 if (st == SISL_NULL) goto err101; 03110 03111 for (kit=0; kit<ik; kit++) 03112 { 03113 st[kit] = astpar; 03114 st[kit+ik] = astpar + tdist; 03115 } 03116 03117 /* calculate the vertices. First allocate space */ 03118 03119 /* First allocate space for vertices */ 03120 03121 scoef = newarray(ik*idim,DOUBLE); 03122 if (scoef == SISL_NULL) goto err101; 03123 03124 /* Find first and last vertex. */ 03125 03126 kvert = (ik-1) * idim; 03127 for (kit=0; kit<idim; kit++,kvert++) 03128 { 03129 scoef[kit] = estapt[kit]; 03130 scoef[kvert] = endpt[kit]; 03131 } 03132 03133 /* Find other vertices */ 03134 03135 for (kit=0; kit<idim; kit++) 03136 { 03137 tdel = (endpt[kit] - estapt[kit])/(ik - 1); 03138 for (kit2=2; kit2<ik; kit2++) 03139 scoef[(kit2-1)*idim + kit] = scoef[(kit2-2)*idim + kit] + tdel; 03140 } 03141 03142 /* Make the curve */ 03143 03144 *rc = SISL_NULL; 03145 *rc = newCurve(ik,ik,st,scoef,1,idim,1); 03146 if (*rc == SISL_NULL) goto err101; 03147 03148 *cendpar = st[ik]; 03149 *jstat = 0; 03150 goto out; 03151 03152 /* Error in memory allocation */ 03153 03154 err101: 03155 *jstat = -101; 03156 s6err("s1602",*jstat,kpos); 03157 goto out; 03158 03159 /* Error in input. Dimension less than 1 */ 03160 03161 err102: 03162 *jstat = -102; 03163 s6err("s1602",*jstat,kpos); 03164 goto out; 03165 /* Error in input. Order less than 2 */ 03166 03167 err109: 03168 *jstat = -109; 03169 s6err("s1602",*jstat,kpos); 03170 goto out; 03171 03172 out: 03173 if (st != SISL_NULL) freearray(st); 03174 if (scoef != SISL_NULL) freearray(scoef); 03175 return; 03176 } 03177 03178 03179 //=========================================================================== 03180 void s1755 (double orknt[], int in, int ik, double extknt[], int *inh, int *jstat) 03181 //=========================================================================== 03182 { 03183 int ki; /* Loop control parameters */ 03184 int kstart, kstop; 03185 int numb; 03186 int kpos = 0; /* Position indicator for errors */ 03187 double prev, par; /* Parameters used to find consecutive 03188 distinct knotvector values */ 03189 double tstart, tstop; /* tstart=orknt[ik-1], tstop=orknt[in] */ 03190 03191 *jstat = 0; 03192 03193 03194 /* Test if legal input. */ 03195 03196 if ((ik < 1) || (in <ik)) 03197 goto err112; 03198 03199 03200 /* Test if input knot vector degenerate. */ 03201 03202 if (orknt[ik - 1] >= orknt[in]) 03203 goto err112; 03204 03205 kstop = in +ik; 03206 03207 03208 /* PRODUCTION OF KNOTS: First we fill in extra knots at each 03209 distinct knot value, then we remove the superfluous knots. */ 03210 03211 numb = 0; 03212 prev = orknt[0] - 1; 03213 for (ki = 0; ki < kstop; ki++) 03214 { 03215 par = orknt[ki]; 03216 if (par < prev) 03217 goto err112; 03218 03219 if (par != prev) 03220 { 03221 /* New distinct knot value, insert additional knot. */ 03222 03223 extknt[numb] = par; 03224 numb++; 03225 } 03226 extknt[numb] = par; 03227 prev = par; 03228 numb++; 03229 } 03230 03231 /* Remove superfluous knots at start. Find greatest start knot. */ 03232 03233 kstart = 0; 03234 tstart = orknt[ik - 1]; 03235 while (extknt[kstart] <= tstart) 03236 kstart++; 03237 kstart--; 03238 03239 03240 /* Find smallest end knot */ 03241 03242 kstop = numb - 1; 03243 tstop = orknt[in]; 03244 while (extknt[kstop] >= tstop) 03245 kstop--; 03246 kstop++; 03247 03248 03249 /* The knots from kstart-ik up to 03250 * kstop+ik are the knots to be kept */ 03251 03252 *inh = kstop - kstart + ik; 03253 03254 03255 /* Copy the knots to be kept to the start of the knot array */ 03256 03257 memcopy (extknt, &extknt[kstart - ik], *inh + ik + 1, DOUBLE); 03258 goto out; 03259 03260 03261 /* Error in description of B-spline */ 03262 03263 err112: 03264 *jstat = -112; 03265 s6err ("s1755", *jstat, kpos); 03266 goto out; 03267 03268 out: 03269 return; 03270 } 03271 03272 03273 //=========================================================================== 03274 void s1753 (double et[], double ecf[], int in, int ik, int idim, double etr[], 03275 double ecfr[], int inr, double ecc[], double ecw[], int *jstat) 03276 //=========================================================================== 03277 { 03278 int ki, kj, kk, kl, kr, kstop;/* Loop control variables */ 03279 int kjmid, ikmid; /* kjmid=(kj-1)*idim ikmid=(ik-1)*idim */ 03280 int kpos = 0; /* Error position indicator */ 03281 double ty1, ty2, tyi, tyik; /* Parameters used in Main Loop */ 03282 double dummy; 03283 double tden; 03284 03285 *jstat = 0; 03286 03287 03288 /* Check input values. */ 03289 03290 if ((ik < 1) || (in <ik) ||(inr < (ik + 1))) 03291 goto err112; 03292 03293 03294 /* Initiate local variables. */ 03295 03296 kr = 1; 03297 for (kj = 1; kj <= inr; kj++) 03298 { 03299 03300 /* Find kr, such that et[kr-1]<=etr[kj-1]<et[kr] */ 03301 03302 for (kr--; et[kr] <= etr[kj - 1]; kr++) ; 03303 03304 03305 /* Set ecc and ecw to zero. */ 03306 03307 for (ki = 0; ki < ik * idim; ki++) 03308 { 03309 ecc[ki] = (double) 0.0; 03310 ecw[ki] = (double) 0.0; 03311 } 03312 03313 /* Initialize the remaining ecc and ecw entries. */ 03314 03315 kstop = MIN (ik, in +ik - kr); 03316 for (ki = MAX (0, ik - kr); ki < kstop; ki++) 03317 for (kl = 0; kl < idim; kl++) 03318 { 03319 dummy = ecf[(ki + kr - ik) * idim + kl]; 03320 ecc[ki * idim + kl] = dummy; 03321 ecw[ki * idim + kl] = dummy; 03322 } 03323 03324 /* MAIN LOOP. */ 03325 03326 for (kk = ik - 1; kk > 0; kk--) 03327 { 03328 ty1 = etr[kj + kk - 1]; 03329 ty2 = etr[kj + kk]; 03330 kstop = MAX (ik - kk, ik - kr); 03331 03332 for (ki = MIN (ik - 1, in +2 * ik - kk - kr - 1); ki >= kstop; ki--) 03333 { 03334 tyi = et[kr + ki - ik]; 03335 tyik = et[kr + ki + kk - ik]; 03336 tden = tyik - tyi; 03337 03338 for (kl = 0; kl < idim; kl++) 03339 { 03340 ecc[ki * idim + kl] = ((ty2 - tyi) * ecc[ki * idim + kl] + 03341 (tyik - ty2) * ecc[(ki - 1) * idim + kl]) / tden; 03342 ecw[ki * idim + kl] = ((ty1 - tyi) * ecw[ki * idim + kl] + 03343 (tyik - ty1) * ecw[(ki - 1) * idim + kl]) / tden + 03344 ecc[ki * idim + kl]; 03345 } 03346 } 03347 } 03348 kjmid = (kj - 1) * idim; 03349 ikmid = (ik - 1) * idim; 03350 03351 for (kl = 0; kl < idim; kl++) 03352 ecfr[kjmid + kl] = ecw[ikmid + kl] / ik; 03353 } 03354 03355 goto out; 03356 03357 03358 /* Error in description of bases */ 03359 03360 err112: 03361 *jstat = -112; 03362 s6err ("s1753", *jstat, kpos); 03363 goto out; 03364 03365 out: 03366 return; 03367 } 03368 03369 03370 //=========================================================================== 03371 void s1754 (double *et, int in, int ik, int ikh, double **iknt, int *inh, int *jstat) 03372 //=========================================================================== 03373 { 03374 int ki, kj; /* Loop control parameters */ 03375 int kstart, kstop; 03376 int numb; 03377 int kpos = 0; /* Position indicator for errors */ 03378 int kant; /* Equals ikh-ik */ 03379 double prev, par; /* Parameters used to find consecutive 03380 distinct knotvector values */ 03381 double tstart, tstop; /* tstart=et[ik-1], tstop=et[in] */ 03382 03383 *jstat = 0; 03384 03385 03386 /* Test if legal input. */ 03387 03388 if (ik < 1 || ikh < ik || in <ik) 03389 goto err112; 03390 03391 03392 /* Test if input knot vector degenerate. */ 03393 03394 if (et[ik - 1] >= et[in]) 03395 goto err112; 03396 03397 03398 /* Allocate internal array arr. */ 03399 03400 *iknt = newarray ((in +ik) *(ikh - ik + 1), DOUBLE); 03401 if (*iknt == SISL_NULL) 03402 goto err101; 03403 03404 03405 /* If ik=ikh, just copy knots. */ 03406 03407 kstop = in +ik; 03408 if (ik == ikh) 03409 { 03410 *inh = in; 03411 memcopy (*iknt, et, kstop, DOUBLE); 03412 goto out; 03413 } 03414 03415 /* PRODUCTION OF KNOTS: First we fill in extra knots at each 03416 distinct knot value, then we remove the superfluous knots. */ 03417 03418 numb = 0; 03419 kant = ikh - ik; 03420 prev = et[0] - 1; 03421 for (ki = 0; ki < kstop; ki++) 03422 { 03423 par = et[ki]; 03424 if (par < prev) 03425 goto err112; 03426 03427 if (par != prev) 03428 { 03429 /* New distinct knot value, insert additional knots. */ 03430 03431 for (kj = 0; kj < kant; kj++, numb++) 03432 (*iknt)[numb] = par; 03433 } 03434 (*iknt)[numb] = par; 03435 prev = par; 03436 numb++; 03437 } 03438 03439 /* Remove superfluous knots at start. Find greatest start knot. */ 03440 03441 kstart = 0; 03442 tstart = et[ik - 1]; 03443 while ((*iknt)[kstart] <= tstart) 03444 kstart++; 03445 kstart--; 03446 03447 03448 /* Find smallest end knot. */ 03449 03450 kstop = numb - 1; 03451 tstop = et[in]; 03452 while ((*iknt)[kstop] >= tstop) 03453 kstop--; 03454 kstop++; 03455 03456 03457 /* The knots from kstart-ikh+1 up to 03458 * kstop+ikh-1 are the knots to be kept. */ 03459 03460 *inh = kstop - kstart + ikh - 1; 03461 03462 03463 /* Copy the knots to be kept to the start of the knot array. */ 03464 03465 kstart -= ikh - 1; 03466 kstop = *inh + ikh; 03467 memcopy (*iknt, &(*iknt)[kstart], kstop, double); 03468 03469 goto out; 03470 03471 /* Memory error or error in allocation. */ 03472 03473 err101: 03474 *jstat = -101; 03475 s6err ("s1754", *jstat, kpos); 03476 goto out; 03477 03478 /* Error in description of B-spline. */ 03479 03480 err112: 03481 *jstat = -112; 03482 s6err ("s1754", *jstat, kpos); 03483 goto out; 03484 03485 out: 03486 if (*iknt != SISL_NULL) 03487 { 03488 *iknt = increasearray (*iknt, *inh + ikh, DOUBLE); 03489 if (*iknt == SISL_NULL) 03490 goto err101; 03491 } 03492 return; 03493 } 03494 03495 //=========================================================================== 03496 void s1750(SISLCurve *pc,int ikh,SISLCurve **rc,int *jstat) 03497 //=========================================================================== 03498 { 03499 int ki, kn, kk; /* Loop control parameters */ 03500 int kordr; 03501 int inhrem; /* Used to store inh, for later use in last 03502 * call to s1753 */ 03503 int kpos = 0; /* Error position indicator */ 03504 int kstat = 0; /* Status variable */ 03505 double *kcc = SISL_NULL; 03506 double *kcw = SISL_NULL; /* Arrays for internal use only */ 03507 double *orknot = SISL_NULL; /* Used to store 'original' knot vector */ 03508 double *xtknot = SISL_NULL; /* Used to store extended knot vector */ 03509 double *pointer = SISL_NULL; 03510 double *orcoef = SISL_NULL; /* Used to store 'original' coefficient matrix */ 03511 double *et = SISL_NULL; /* Original knot vector */ 03512 double *ebcoef = SISL_NULL; /* Vertices of original curve */ 03513 int in; /* Number of vertices of original curve */ 03514 int ik; /* Order of original curve */ 03515 int idim; /* Dimension of the space where the curve lie */ 03516 int kdim; /* Potential rational dimension. */ 03517 int kind; /* Kind of curve, 2 and 4 are rationals. */ 03518 double *iknt = SISL_NULL; /* New knot vector */ 03519 double *icoef = SISL_NULL; /* Coefficients of new curve */ 03520 int inh; /* Number of vertices produced */ 03521 03522 *jstat = 0; 03523 03524 /* Initialization of variables. */ 03525 03526 kind = pc->ikind; 03527 idim = pc->idim; 03528 et = pc->et; 03529 if (kind == 2 || kind == 4) 03530 { 03531 ebcoef = pc->rcoef; 03532 kdim = idim + 1; 03533 } 03534 else 03535 { 03536 ebcoef = pc->ecoef; 03537 kdim = idim; 03538 } 03539 in = pc->in; 03540 ik = pc->ik; 03541 03542 /* Test if legal input. */ 03543 03544 if ((ik < 1) || (ikh < ik) || (in <ik)) goto err112; 03545 03546 /* If ikh=ik, copy input curve to output variables. */ 03547 03548 if (ikh == ik) 03549 { 03550 *rc = newCurve (in, ik, et, ebcoef, pc->ikind, idim, 1); 03551 if (*rc == SISL_NULL) goto err171; 03552 03553 /* If the input curve is periodic, the output curve is periodic. */ 03554 (*rc)->cuopen = pc->cuopen; 03555 goto out; 03556 } 03557 03558 /* Find size of knot vector and vertex vector, 03559 and find knot vector expressed in order ikh. */ 03560 03561 s1754 (et, in, ik, ikh, &iknt, &inh, &kstat); 03562 if (kstat < 0) goto error; 03563 03564 /* Allocate coefficients array for raised curve. */ 03565 03566 if((icoef = newarray (inh * kdim, DOUBLE)) == SISL_NULL) goto err101; 03567 03568 /* Allocate arrays for internal use. */ 03569 03570 if((kcc = newarray (kdim * ikh, DOUBLE)) == SISL_NULL) goto err101; 03571 if((kcw = newarray (kdim * ikh, DOUBLE)) == SISL_NULL) goto err101; 03572 03573 /* Find vertices if ikh = ik+1 */ 03574 03575 if (ikh == ik + 1) 03576 { 03577 s1753 (et, ebcoef, in, ik, kdim, iknt, icoef, inh, kcc, kcw, &kstat); 03578 if (kstat < 0) goto error; 03579 03580 *rc = newCurve (inh, ikh, iknt, icoef, pc->ikind, idim, 2); 03581 if (*rc == SISL_NULL) goto err171; 03582 03583 /* If the input curve is periodic, the output curve is periodic. */ 03584 (*rc)->cuopen = pc->cuopen; 03585 03586 goto out; 03587 } 03588 03589 /* Allocate arrays to store knot vector for use in s1755. */ 03590 03591 orknot = newarray ((in +ik) *(ikh - ik + 1), DOUBLE); 03592 if (orknot == SISL_NULL) goto err101; 03593 xtknot = newarray ((in +ik) *(ikh - ik + 1), DOUBLE); 03594 if (xtknot == SISL_NULL) goto err101; 03595 03596 /* Allocate array to store vertices. */ 03597 03598 orcoef = newarray (inh * kdim, DOUBLE); 03599 if (orcoef == SISL_NULL) goto err101; 03600 03601 /* Initialize orknot and orcoef. */ 03602 03603 for (ki = 0; ki < (in +ik); ki++) 03604 orknot[ki] = et[ki]; 03605 03606 for (ki = 0; ki < (kdim * in); ki++) 03607 orcoef[ki] = ebcoef[ki]; 03608 03609 03610 /* MAIN LOOP. Do the order raisings. */ 03611 03612 inhrem = inh; 03613 kn = in; 03614 kk = ik; 03615 for (kordr = ik + 1; kordr < ikh; kordr++) 03616 { 03617 /* Produce raised knots. */ 03618 03619 s1755 (orknot, kn, kk, xtknot, &inh, &kstat); 03620 if (kstat < 0) goto error; 03621 03622 /* Produce raised vertices. */ 03623 03624 s1753 (orknot, orcoef, kn, kk, kdim, xtknot, icoef, 03625 inh, kcc, kcw, &kstat); 03626 if (kstat < 0) goto error; 03627 03628 03629 if ((kordr + 1) < ikh) 03630 { 03631 pointer = orknot; 03632 orknot = xtknot; 03633 xtknot = pointer; 03634 } 03635 kk = kordr; 03636 kn = inh; 03637 pointer = orcoef; 03638 orcoef = icoef; 03639 icoef = pointer; 03640 } 03641 03642 inh = inhrem; 03643 s1753 (xtknot, orcoef, kn, kk, kdim, iknt, icoef, inh, kcc, kcw, &kstat); 03644 if (kstat < 0) goto error; 03645 03646 /* OK. 03647 * Create new curve */ 03648 03649 *rc = newCurve (inh, ikh, iknt, icoef, pc->ikind, idim, 2); 03650 if (*rc == SISL_NULL) goto err171; 03651 03652 /* If the input curve is periodic, the output curve is periodic. */ 03653 (*rc)->cuopen = pc->cuopen; 03654 03655 goto out; 03656 03657 03658 /* Error in array allocation */ 03659 03660 err101: 03661 *jstat = -101; 03662 s6err ("s1750", *jstat, kpos); 03663 goto out; 03664 03665 /* Could not create curve. */ 03666 03667 err171: 03668 *jstat = -171; 03669 s6err ("s1750", *jstat, kpos); 03670 goto out; 03671 03672 /* Error in description of B-spline */ 03673 03674 err112: 03675 *jstat = -112; 03676 s6err ("s1750", *jstat, kpos); 03677 goto out; 03678 03679 /* Error in lower level routine */ 03680 03681 error: 03682 *jstat = kstat; 03683 s6err ("s1750", *jstat, kpos); 03684 goto out; 03685 03686 out: 03687 if (kcc != SISL_NULL) freearray (kcc); 03688 if (kcw != SISL_NULL) freearray (kcw); 03689 if (orknot != SISL_NULL) freearray (orknot); 03690 if (xtknot != SISL_NULL) freearray (xtknot); 03691 if (orcoef != SISL_NULL) freearray (orcoef); 03692 return; 03693 } 03694 03695 03696 //=========================================================================== 03697 void s1715(SISLCurve *pc1,SISLCurve *pc2,int iend1,int iend2,SISLCurve **rcnew,int *jstat) 03698 //=========================================================================== 03699 { 03700 int kstat=0; /* Local status variable. */ 03701 int kpos=0; /* Position of error. */ 03702 int kcopy=0; /* To mark if pc1 (1) or pc2 (2) is 03703 changed to point at a local copy. */ 03704 int km1=0,km2=0; /* Knot mutiplicety at the end to join. */ 03705 int km2end=0; /* Knot mutiplicety at the end of the 03706 second curve. */ 03707 int kk; /* Order of the new curve. */ 03708 int kn; /* Number of the vertices in the new curve. */ 03709 int kdim; /* Dimensjon of the space in whice curve lies.*/ 03710 int routdim; /* Rational dimension of the output curve. */ 03711 int kn1=pc1->in; /* Number of vertices in the old curves. */ 03712 int kn2=pc2->in; /* Number of vertices in the old curves. */ 03713 int ki,kj; /* Control variable in loop, and others. */ 03714 double tdel; /* The translation of the knots to the 03715 second curve. */ 03716 double *s1,*s2,*s3; /* Pointers used in loop. */ 03717 double *stran=SISL_NULL; /* The translation vector to vertices. */ 03718 double *st=SISL_NULL; /* The new knot-vector. */ 03719 double *scoef=SISL_NULL; /* The new vertice. */ 03720 SISLCurve *qc=SISL_NULL; /* Pointer to the new curve-object. */ 03721 03722 int ktype; /* Type of curves: */ 03723 /* = 1 : Both are B-splines */ 03724 /* = 2 : pc1 is B-spline and pc2 is NURBS */ 03725 /* = 3 : pc1 is NURBS and pc2 is B-spline */ 03726 /* = 4 : Both are NURBS */ 03727 int knumb; /* Number of vertices. */ 03728 double weight; /* Rational weight. */ 03729 double *u1,*u2; /* Utility pointers into the vertices. */ 03730 03731 /* Check that we have curves to join. */ 03732 03733 if (!pc1 || !pc2) goto err150; 03734 03735 /* Check that The curves is in the same room, have the same kdim. */ 03736 03737 if (pc1->idim != pc2->idim) goto err106; 03738 else kdim = pc1->idim; 03739 03740 /* Check the type of the curves. */ 03741 03742 if (pc1->ikind == 2 || pc1->ikind == 4) 03743 { 03744 if (pc2->ikind == 2 || pc2->ikind == 4) 03745 { 03746 ktype = 4; 03747 routdim = kdim + 1; 03748 } 03749 else 03750 { 03751 ktype = 3; 03752 routdim = kdim + 1; 03753 } 03754 } 03755 else 03756 { 03757 if (pc2->ikind == 2 || pc2->ikind == 4) 03758 { 03759 ktype = 2; 03760 routdim = kdim + 1; 03761 } 03762 else 03763 { 03764 ktype = 1; 03765 routdim = kdim; 03766 } 03767 } 03768 03769 /* Allocate a kdim array to store the translation of the second curv.*/ 03770 03771 if ((stran=newarray(kdim,double)) == SISL_NULL) goto err153; 03772 03773 /* Checking the order of the curves, and raise the order if nessesary.*/ 03774 03775 if (pc1->ik < pc2->ik) 03776 { 03777 kcopy=1; 03778 kk=pc2->ik; 03779 s1750(pc1,kk,&pc1,&kstat); 03780 if (kstat) goto err153; 03781 } 03782 else 03783 if (pc2->ik < pc1->ik) 03784 { 03785 kcopy=2; 03786 kk=pc1->ik; 03787 s1750(pc2,kk,&pc2,&kstat); 03788 if (kstat) goto err153; 03789 } 03790 else 03791 kk = pc1->ik; 03792 03793 /* Finding the knot multiplicity at the juinction, km1 km2. 03794 At the end thats going to be the end of the new curve 03795 we also need to know the knot mutiticeply, km2end. */ 03796 03797 /* Having raised the order of the curves if necessary, 03798 remember the number of vertices in the two curves. */ 03799 03800 kn1=pc1->in; 03801 kn2=pc2->in; 03802 03803 if (iend1) 03804 while (pc1->et[kn1+kk-1-km1] == pc1->et[kn1+kk-1]) km1++; 03805 else 03806 while (pc1->et[km1] == *pc1->et) km1++; 03807 if (iend2) 03808 { 03809 while (pc2->et[kn2+kk-1-km2] == pc2->et[kn2+kk-1]) km2++; 03810 while (pc2->et[km2end] == *pc2->et) km2end++; 03811 } 03812 else 03813 { 03814 while (pc2->et[km2] == *pc2->et) km2++; 03815 while (pc2->et[kn2+kk-1-km2end] == pc2->et[kn2+kk-1]) km2end++; 03816 } 03817 03818 /* Find the number of vertices in the new curve. */ 03819 03820 kn = kn1 + kn2 + 3*kk - km1 - km2 - km2end -1; 03821 03822 /* Allocating the new arrays to the new curve. */ 03823 03824 if ((st=newarray(kn+kk,double))==SISL_NULL) goto err101; 03825 if ((scoef=newarray(kn*routdim,double))==SISL_NULL) goto err101; 03826 03827 /* Copying the knotvectors from the old curve to the new curves */ 03828 /****************************************************************/ 03829 03830 /* The first curve. */ 03831 03832 if (iend1) /* The junction is at the end of the first curve. */ 03833 { 03834 /* Copying all knots from the first curve that is different 03835 from the last knot. */ 03836 03837 memcopy(st,pc1->et,kn1+kk-km1,double); 03838 03839 /* Making a kk-1 touple knot at the junction. */ 03840 03841 for (s1=st+kn1+kk-km1,s2=s1+kk-1; s1<s2; s1++) 03842 *s1=pc1->et[kn1+kk-1]; 03843 03844 } 03845 else /* The junction is at the beginning of the first curve. */ 03846 { 03847 /* Computing the factor to turn the first knotvector. */ 03848 03849 tdel = *pc1->et + pc1->et[kn1+kk-1]; 03850 03851 /* Copying and turning the first knot vector except the 03852 knots at the junction. */ 03853 03854 for (s1=st,s2=pc1->et+km1,s3=pc1->et+kn1+kk-1; s2<=s3; s1++,s3--) 03855 *s1 = tdel - *s3; 03856 03857 /* Making a kk-1 touple knot at the junction. */ 03858 03859 for (s2--,s3=s1+kk-1; s1<s3; s1++) *s1= tdel - *s2; 03860 } 03861 03862 /* The second curve. */ 03863 03864 s2 = st+kn+kk-max(0,kk-km2end); /* The border for the last exsisting knot 03865 in the new knot vector. */ 03866 03867 if (!iend2) /* The junction is at the begining of the second curve. */ 03868 { 03869 /* Computing what the second knot vector has to be translated 03870 to get a kontinue total knotvector. */ 03871 03872 tdel = s1[-1] - *pc2->et; 03873 03874 /* copying and translating all knots except the knots 03875 at the junction. */ 03876 03877 for (s3=pc2->et+km2; s1<s2; s1++,s3++) *s1 = *s3 + tdel; 03878 } 03879 else 03880 { 03881 /* Coputing a factor to both translate and turn the knots. */ 03882 03883 tdel = pc2->et[kn2+kk-1] + s1[-1]; 03884 03885 /* Turning and translating all knots exept the knots 03886 at the junction. */ 03887 03888 for (s3=pc2->et+kn2+kk-km2-1; s1<s2; s1++,s3--) *s1 =tdel- *s3; 03889 } 03890 03891 /* Inserting new knots such that we have a kk touple knot at the end.*/ 03892 03893 for (ki=0; ki<kk-km2end; ki++) s1[ki] = s1[-1]; 03894 03895 /* Copying the coeffesientvectors to the new curves.*/ 03896 /***************************************************/ 03897 03898 /* Copying the first coeffisientvector. */ 03899 03900 knumb = min(kn1,kn1+kk-km1); 03901 ki = routdim*knumb; 03902 if (iend1) /* Just copying. */ 03903 { 03904 if (ktype == 1) 03905 memcopy(scoef,pc1->ecoef,ki,double); 03906 else if (ktype == 2) 03907 { 03908 for (kj=0; kj<knumb; kj++) 03909 { 03910 u1 = scoef + kj*routdim; 03911 u2 = pc1->ecoef + kj*kdim; 03912 memcopy(u1,u2,kdim,double); 03913 scoef[kj*routdim + kdim] = 1.; 03914 } 03915 } 03916 else if (ktype == 3 || ktype == 4) 03917 memcopy(scoef,pc1->rcoef,ki,double); 03918 s1 = scoef +ki; 03919 } 03920 else /* Copying back to front. */ 03921 { 03922 if (ktype == 2) 03923 { 03924 s2 = pc1->ecoef; 03925 s3 = s2 + kdim*(knumb - 1); 03926 for (s1=scoef; s2<=s3; s3-=2*kdim) 03927 { 03928 for (ki=0; ki<kdim; ki++,s1++,s3++) *s1 = *s3; 03929 *s1 = 1.; 03930 s1++; 03931 } 03932 } 03933 else 03934 { 03935 if (ktype == 1) 03936 s2 = pc1->ecoef; 03937 else 03938 s2 = pc1->rcoef; 03939 for (s1=scoef,s3=s2+ki-routdim; s2<=s3; s3-=2*routdim) 03940 for (ki=0; ki<routdim; ki++,s1++,s3++) *s1 = *s3; 03941 } 03942 } 03943 03944 /* If there is less than a kk touple knot at the end of the first curve 03945 than we have to inserte zeroes. */ 03946 03947 for (s2=s1+routdim*max(0,kk-km1); s1<s2; s1+=routdim) 03948 { 03949 for (ki=0; ki<kdim; ki++) 03950 s1[ki] = DZERO; 03951 if (ktype != 1) 03952 s1[kdim] = 1.; 03953 } 03954 03955 /* Compute the translation of the second curv. */ 03956 03957 for (ki=0; ki<kdim; ki++) 03958 { 03959 if (km2<kk) stran[ki] = DZERO; 03960 else 03961 stran[ki] = iend2? pc2->ecoef[kdim*(kn2-max(0,km2-kk)-1)+ki]: 03962 pc2->ecoef[kdim*max(0,km2-kk)+ki]; 03963 if (km1>=kk) 03964 stran[ki] -= iend1? pc1->ecoef[kdim*(kn1-max(0,km1-kk)-1)+ki]: 03965 pc1->ecoef[kdim*max(0,km1-kk)+ki]; 03966 } 03967 03968 03969 /* Copying the second coefficientvector. */ 03970 03971 /* Findig the startpoint for copying in the old coeffisient vector. */ 03972 03973 if (iend2) 03974 { 03975 if (ktype == 1 || ktype == 3) 03976 s3=pc2->ecoef+kdim*(kn2-max(0,km2-kk)-1); 03977 else 03978 s3=pc2->rcoef+routdim*(kn2-max(0,km2-kk)-1); 03979 } 03980 else 03981 { 03982 if (ktype == 1 || ktype == 3) 03983 s3=pc2->ecoef+kdim*max(0,km2-kk); 03984 else 03985 s3=pc2->rcoef+routdim*max(0,km2-kk); 03986 } 03987 03988 if (km2<kk) 03989 { 03990 /* If km2<kk-1 we have to insert zeroes and than transform. */ 03991 03992 for (kj=km2+1; kj<kk; kj++,s2+=routdim) 03993 { 03994 for (ki=0; ki<kdim; ki++,s1++) *s1 = -stran[ki]; 03995 if (ktype != 1) 03996 { 03997 *s1 = 1.; 03998 s1++; 03999 } 04000 } 04001 04002 /* Copying and transforming the first coeffisients. */ 04003 04004 if (ktype == 1) 04005 for (ki=0; ki<kdim; ki++,s1++,s3++) *s1 = *s3 - stran[ki]; 04006 else 04007 { 04008 if (ktype == 3) 04009 weight = 1.; 04010 else 04011 weight = s3[kdim]; 04012 for (ki=0; ki<kdim; ki++,s1++,s3++) *s1 = *s3 - stran[ki]*weight; 04013 *s1 = weight; 04014 s1++; 04015 if (ktype != 3) s3++; 04016 } 04017 } 04018 else 04019 if (ktype == 1 || ktype == 3) 04020 s3+=kdim; /* Skiping the first coeffisients. */ 04021 else 04022 s3+=routdim; /* Skiping the first coeffisients. */ 04023 04024 /* Copying and transforming the coeffisient from the second curve. */ 04025 04026 for (s2=scoef+routdim*min(kn,kn-kk+km2end); s1<s2;) 04027 { 04028 if (iend2) 04029 { 04030 if (ktype == 1 || ktype == 3) 04031 s3-=2*kdim; 04032 else 04033 s3-=2*routdim; 04034 } 04035 if (ktype == 1) 04036 for (ki=0; ki<kdim; ki++,s1++,s3++) *s1 = *s3 - stran[ki]; 04037 else 04038 { 04039 if (ktype == 3) 04040 weight = 1.; 04041 else 04042 weight = s3[kdim]; 04043 for (ki=0; ki<kdim; ki++,s1++,s3++) *s1 = *s3 - stran[ki]*weight; 04044 *s1 = weight; 04045 s1++; 04046 if (ktype != 3) s3++; 04047 } 04048 } 04049 04050 /* Insert and transform from zeroes if we do not have a kk touple 04051 knot at the end of the second curve. */ 04052 04053 for (kj=0; kj<kk-km2end; kj++) 04054 { 04055 for (ki=0; ki<kdim; ki++,s1++) *s1 = -stran[ki]; 04056 if (ktype != 1) 04057 { 04058 *s1 = 1.; 04059 s1++; 04060 } 04061 } 04062 04063 /* Create the new curve. */ 04064 04065 if (ktype == 1) 04066 { 04067 if ((qc=newCurve(kn,kk,st,scoef,1,kdim,2)) == SISL_NULL) goto err101; 04068 } 04069 else 04070 if ((qc=newCurve(kn,kk,st,scoef,2,kdim,2)) == SISL_NULL) goto err101; 04071 04072 /* Updating output. */ 04073 04074 *rcnew = qc; 04075 *jstat = 0; 04076 goto out; 04077 04078 04079 /* Error. Subrutine error. */ 04080 04081 err153: 04082 *jstat = kstat; 04083 goto outfree; 04084 04085 04086 /* Error. No curve to subdevice. */ 04087 04088 err150: 04089 *jstat = -150; 04090 s6err("s1715",*jstat,kpos); 04091 goto out; 04092 04093 04094 /* Error. Different dimensjon of the room. */ 04095 04096 err106: 04097 *jstat = -106; 04098 s6err("s1715",*jstat,kpos); 04099 goto out; 04100 04101 04102 /* Error. Allocation error, not enough memory. */ 04103 04104 err101: 04105 *jstat = -101; 04106 s6err("s1715",*jstat,kpos); 04107 goto outfree; 04108 04109 04110 outfree: 04111 if(qc) 04112 freeCurve(qc); 04113 else 04114 { 04115 if (st) freearray(st); 04116 if (scoef) freearray(scoef); 04117 } 04118 04119 /* Free local used memory. */ 04120 04121 out: 04122 if (stran) 04123 freearray(stran); 04124 if (kcopy == 1) 04125 freeCurve(pc1); 04126 else 04127 if (kcopy == 2) freeCurve(pc2); 04128 return; 04129 } 04130 04131 04132 04133 //=========================================================================== 04134 void s1710 (SISLCurve * pc1, double apar, SISLCurve ** rcnew1, 04135 SISLCurve ** rcnew2, int *jstat) 04136 //=========================================================================== 04137 { 04138 int kind = pc1->ikind; /* Type of curve pc1 is. */ 04139 int kstat; /* Local status variable. */ 04140 int kpos = 0; /* Position of error. */ 04141 int kmy; /* An index to the knot-vector. */ 04142 int kv, kv1; /* Number of knots we have to insert. */ 04143 int kpl, kfi, kla; /* To posisjon elements in trans.-matrix. */ 04144 int kk = pc1->ik; /* Order of the input curve. */ 04145 int kn = pc1->in; /* Number of the vertices in input curves. */ 04146 int kdim = pc1->idim; /* Dimensjon of the space in whice 04147 * the curve lies. */ 04148 int kn1, kn2; /* Number of vertices in the new curves. */ 04149 int knum; /* Number of knots less and equal than 04150 the intersection point. */ 04151 int ki, ki1; /* Control variable in loop. */ 04152 int kj, kj1, kj2; /* Control variable in loop. */ 04153 int newkind = 1; /* Type of curve the subcurves are */ 04154 double *s1, *s2, *s3, *s4; /* Pointers used in loop. */ 04155 double *st1 = SISL_NULL; /* The first new knot-vector. */ 04156 double *st2 = SISL_NULL; /* The second new knot-vector. */ 04157 double *salfa = SISL_NULL; /* A line of the trans.-matrix. */ 04158 double *scoef; /* Pointer to vertices. */ 04159 double *scoef1 = SISL_NULL; /* The first new vertice. */ 04160 double *scoef2 = SISL_NULL; /* The second new vertice. */ 04161 SISLCurve *q1 = SISL_NULL; /* Pointer to new curve-object. */ 04162 SISLCurve *q2 = SISL_NULL; /* Pointer to new curve-object. */ 04163 int incr; /* Number of extra knots copied 04164 * during periodicity */ 04165 int mu; /* Multiplisity at the k'th knot */ 04166 int kleft = kk-1; /* Knot navigator */ 04167 double delta; /* Period size in knot array. */ 04168 double salfa_local[5]; /* Local help array. */ 04169 04170 *rcnew1 = SISL_NULL; 04171 *rcnew2 = SISL_NULL; 04172 04173 /* if pc1 is rational, do subdivision in homogeneous coordinates */ 04174 /* just need to set up correct dim and kind for the new curves at end of routine */ 04175 if (kind == 2 || kind == 4) 04176 { 04177 scoef = pc1->rcoef; 04178 kdim++; 04179 newkind++; 04180 } 04181 else 04182 { 04183 scoef = pc1->ecoef; 04184 } 04185 04186 /* Check that we have a curve to subdivide. */ 04187 04188 if (!pc1) 04189 goto err150; 04190 04191 04192 /* Periodic curve treatment, UJK jan 92--------------------------------- */ 04193 if (pc1->cuopen == SISL_CRV_PERIODIC) 04194 { 04195 delta = (pc1->et[kn] - pc1->et[kk - 1]); 04196 04197 /* Check that the intersection point is an interior point. */ 04198 /*if (apar < *(pc1->et) || apar > *(pc1->et + kn + kk - 1))*/ 04199 if ((apar < pc1->et[0] && DNEQUAL(apar, pc1->et[0])) || 04200 (apar > pc1->et[kn+kk-1] && DNEQUAL(apar, pc1->et[kn+kk-1]))) 04201 goto err158; 04202 04203 /* If inside the knot vector, but outside well define 04204 intervall, we shift the parameter value one period. */ 04205 if (apar < pc1->et[kk - 1] && DNEQUAL(apar, pc1->et[kk - 1])) 04206 apar += delta; 04207 if (apar > pc1->et[kn] || DEQUAL(apar, pc1->et[kn])) 04208 apar -= delta; 04209 04210 /* Now we create a new curve that is a copy of pc1, 04211 but with the period repeated once, 04212 this allows us to pick a whole period. */ 04213 04214 /* Get multiplisity at start of full basis interval */ 04215 mu = s6knotmult(pc1->et, kk, kn, &kleft, pc1->et[kk-1], &kstat); 04216 if (kstat < 0) goto err153; 04217 if (mu >= kk) goto errinp; 04218 04219 /* Copy ----------------------------------- */ 04220 incr = kn - kk + mu; 04221 if ((scoef1 = newarray ((kn + incr) * kdim, double)) == SISL_NULL) 04222 goto err101; 04223 if ((st1 = newarray (kn + kk + incr, double)) == SISL_NULL) 04224 goto err101; 04225 04226 memcopy (scoef1, scoef, kn * kdim, double); 04227 memcopy (st1, pc1->et, kn + kk, double); 04228 memcopy (scoef1 + kn * kdim, scoef + (kk - mu) * kdim, 04229 incr * kdim, double); 04230 04231 04232 for (ki = 0; ki < incr; ki++) 04233 st1[kn + kk + ki] = st1[kn + kk + ki - 1] + 04234 (st1[2*kk - mu + ki] - st1[2*kk - mu + ki - 1]); 04235 04236 if ((q1 = newCurve (kn + incr, kk, st1, scoef1, 04237 newkind, pc1->idim, 2)) == SISL_NULL) 04238 goto err101; 04239 q1->cuopen = SISL_CRV_OPEN; 04240 04241 /* Pick part (one period)------------------ */ 04242 s1712 (q1, apar, apar + delta, 04243 rcnew1, &kstat); 04244 if (kstat < 0) 04245 goto err153; 04246 freeCurve (q1); 04247 if (*rcnew1) 04248 (*rcnew1)->cuopen = SISL_CRV_CLOSED; 04249 04250 /* Finished, exit */ 04251 *jstat = 2; 04252 goto out; 04253 04254 } 04255 04256 /* End of periodic curve treatment, UJK jan 92------------- */ 04257 04258 /* Check that the intersection point is an interior point. */ 04259 /* Changed by UJK and later ALA*/ 04260 /*if (apar < *(pc1->et) || apar > *(pc1->et+kn+kk-1)) goto err158; */ 04261 04262 if ((apar < pc1->et[kk - 1] && DNEQUAL(apar, pc1->et[kk - 1]))|| 04263 (apar > pc1->et[kn] && DNEQUAL(apar, pc1->et[kn]))) 04264 goto err158; 04265 04266 /* Allocate space for the kk elements which may not be zero in eache 04267 line of the basic transformation matrix.*/ 04268 04269 if (kk > 5) 04270 { 04271 if ((salfa = newarray (kk, double)) == SISL_NULL) goto err101; 04272 } 04273 else salfa = salfa_local; 04274 04275 04276 /* Find the number of the knots which is smaller or like 04277 the intersection point, and how many knots we have to insert.*/ 04278 04279 s1 = pc1->et; 04280 kv = kk; /* The maximum number of knots we may have to insert. */ 04281 04282 if ((apar > s1[0] && DNEQUAL(apar, s1[0])) && 04283 (apar < s1[kn+kk-1] && DNEQUAL(apar, s1[kn+kk-1]))) 04284 { 04285 /* Using binear search*/ 04286 kj1=0; 04287 kj2=kk+kn-1; 04288 knum = (kj1+kj2)/2; 04289 while (knum != kj1) 04290 { 04291 if ((s1[knum] < apar) && DNEQUAL (s1[knum], apar)) 04292 kj1=knum; 04293 else 04294 kj2=knum; 04295 knum = (kj1+kj2)/2; 04296 } 04297 knum++; /* The smaller knots. */ 04298 04299 while (DEQUAL (s1[knum], apar)) 04300 /* The knots thats like the intersection point. */ 04301 { 04302 apar = s1[knum]; 04303 knum++; 04304 kv--; 04305 } 04306 } 04307 else if (DEQUAL(apar,s1[0])) 04308 { 04309 apar = s1[0]; 04310 knum = 0; 04311 while (s1[knum] == apar) 04312 /* The knots thats like the intersection point. */ 04313 knum++; 04314 } 04315 else if (DEQUAL(apar,s1[kn+kk-1])) 04316 { 04317 apar = s1[kn+kk-1]; 04318 knum = kn+kk-1; 04319 while (s1[knum-1] == apar) 04320 /* The knots thats like the intersection point. */ 04321 knum--; 04322 } 04323 04324 /* Find the number of vertices in the two new curves. */ 04325 04326 kn1 = knum + kv - kk; 04327 kn2 = kn + kk - knum; 04328 04329 04330 04331 /* Allocating the new arrays to the two new curves. */ 04332 04333 if (kn1 > 0) 04334 { 04335 if ((scoef1 = newarray (kn1 * kdim, double)) == SISL_NULL) 04336 goto err101; 04337 if ((st1 = newarray (kn1 + kk, double)) == SISL_NULL) 04338 goto err101; 04339 } 04340 if (kn2 > 0) 04341 { 04342 if ((scoef2 = newarray (kn2 * kdim, double)) == SISL_NULL) 04343 goto err101; 04344 if ((st2 = newarray (kn2 + kk, double)) == SISL_NULL) 04345 goto err101; 04346 } 04347 04348 04349 /* Copying the knotvectors, all but the intersection point from 04350 the old curve to the new curves */ 04351 04352 memcopy (st1, pc1->et, kn1, double); 04353 memcopy (st2 + kk, pc1->et + knum, kn2, double); 04354 04355 04356 /* Updating the knotvectors by inserting a k-touple knot in 04357 the intersection point at each curve.*/ 04358 04359 for (s2 = st1 + kn1, s3 = st2, s4 = s3 + kk; s3 < s4; s2++, s3++) 04360 *s2 = *s3 = apar; 04361 04362 04363 /* Copying the coefisientvectors to the new curves.*/ 04364 04365 memcopy (scoef1, scoef, kdim * kn1, double); 04366 memcopy (scoef2, scoef + kdim * (knum - kk), kdim * kn2, double); 04367 04368 04369 /* Updating the coefisientvectors to the new curves.*/ 04370 04371 /* Updating the first curve. */ 04372 knum -= kk - 1; 04373 for (ki=max(0, knum), kv1=max(0,-knum), s1=scoef1+ki*kdim; ki < kn1; ki++) 04374 { 04375 /* Initialising: 04376 knum = knum-kk+1, Index of the first vertice to change. 04377 ki = knum, Index of the vertices we are going to 04378 change. Starting with knum, but if 04379 knum is negativ we start at zero. 04380 kv1 = 0, Number if new knots between index ki 04381 and ki+kk. We are starting one below 04382 becase we are counting up before using 04383 it. If knum is negativ we are not 04384 starting at zero but at -knum. 04385 s1=scoef1+ki*kdim,SISLPointer at the first vertice to 04386 change. */ 04387 04388 04389 /* Using the Oslo-algorithm to make a transformation-vector 04390 from the old vertices to one new vertice. */ 04391 04392 kmy = ki; 04393 s1700 (kmy, kk, kn, ++kv1, &kpl, &kfi, &kla, pc1->et, apar, salfa, &kstat); 04394 if (kstat) 04395 goto err153; 04396 04397 04398 /* Compute the kdim vertices with the same "index". */ 04399 04400 for (kj = 0; kj < kdim; kj++, s1++) 04401 for (*s1 = 0, kj1 = kfi, kj2 = kfi + kpl; kj1 <= kla; kj1++, kj2++) 04402 *s1 += salfa[kj2] * scoef[kj1 * kdim + kj]; 04403 } 04404 04405 /* And the second curve. */ 04406 04407 for (ki1 = min (kn1 + kv - 1, kn + kv), s1 = scoef2; ki < ki1; ki++) 04408 { 04409 /* Initialising: 04410 ki1 = kn1+kv-1, the index of the vertice next to the 04411 last vertice we have to change. 04412 If we do not have so many vertices, 04413 we have to use the index next to the 04414 last vertice we have, kn+kv. 04415 s1=scoef2 Pointer at the first vertice to 04416 change. */ 04417 04418 04419 /* Using the Oslo-algorithm to make a transformation-vector 04420 from the old vertices to one new vertice. */ 04421 04422 s1700 (kmy, kk, kn, kv1--, &kpl, &kfi, &kla, pc1->et, apar, salfa, &kstat); 04423 if (kstat) 04424 goto err153; 04425 04426 04427 /* Compute the kdim vertices with the same "index". */ 04428 04429 for (kj = 0; kj < kdim; kj++, s1++) 04430 for (*s1 = 0, kj1 = kfi, kj2 = kfi + kpl; kj1 <= kla; kj1++, kj2++) 04431 *s1 += salfa[kj2] * scoef[kj1 * kdim + kj]; 04432 } 04433 04434 04435 /* Allocating new curve-objects.*/ 04436 04437 if (kn1 > 0) 04438 q1 = newCurve (kn1, kk, st1, scoef1, newkind, pc1->idim, 2); 04439 04440 if (kn2 > 0) 04441 q2 = newCurve (kn2, kk, st2, scoef2, newkind, pc1->idim, 2); 04442 04443 if (q1 == SISL_NULL && q2 == SISL_NULL) goto err101; 04444 04445 /* Updating output. */ 04446 04447 *rcnew1 = q1; 04448 *rcnew2 = q2; 04449 if (q1 == SISL_NULL || q2 == SISL_NULL) 04450 *jstat = 5; /* The curve is subdivided in an endpoint. */ 04451 else 04452 *jstat = 0; 04453 goto out; 04454 04455 04456 /* Error. Error in low level routine. */ 04457 04458 err153: 04459 *jstat = kstat; 04460 s6err ("s1710", *jstat, kpos); 04461 goto outfree; 04462 04463 /* Error. Error in input */ 04464 errinp: 04465 *jstat = -154; 04466 s6err ("s1710", *jstat, kpos); 04467 goto outfree; 04468 04469 04470 /* Error. No curve to subdivide. */ 04471 04472 err150: 04473 *jstat = -150; 04474 s6err ("s1710", *jstat, kpos); 04475 goto out; 04476 04477 04478 /* Error. The parameter value is outside the curve. */ 04479 04480 err158: 04481 *jstat = -158; 04482 s6err ("s1710", *jstat, kpos); 04483 goto out; 04484 04485 04486 /* Error. Allocation error, not enough memory. */ 04487 04488 err101: 04489 *jstat = -101; 04490 s6err ("s1710", *jstat, kpos); 04491 goto outfree; 04492 04493 04494 outfree: 04495 if (q1) 04496 freeCurve (q1); 04497 04498 if (q2) 04499 freeCurve (q2); 04500 04501 04502 /* Free local used memory. */ 04503 04504 out: 04505 if (!q1) 04506 { 04507 if (st1) 04508 freearray (st1); 04509 if (scoef1) 04510 freearray (scoef1); 04511 } 04512 04513 if (!q2) 04514 { 04515 if (st2) 04516 freearray (st2); 04517 if (scoef2) 04518 freearray (scoef2); 04519 } 04520 04521 if (kk > 5 && salfa) 04522 freearray (salfa); 04523 return; 04524 } 04525 04526 04527 //=========================================================================== 04528 void s1714 (SISLCurve * pc, double apar1, double apar2, SISLCurve ** rcnew1, 04529 SISLCurve ** rcnew2, int *jstat) 04530 //=========================================================================== 04531 { 04532 int kstat; /* Local status variable. */ 04533 int kpos = 0; /* Position of error. */ 04534 SISLCurve *q1 = SISL_NULL; /* Pointer to new curve-object. */ 04535 SISLCurve *q2 = SISL_NULL; /* Pointer to new curve-object. */ 04536 04537 /* Check that we have a curve to devide. */ 04538 04539 if (!pc) 04540 goto err150; 04541 04542 /* Check that apar1 is not equal apar2. */ 04543 04544 if (DEQUAL (apar1, apar2)) 04545 goto err151; 04546 04547 /* Treating periodicity UJK, jan.92 and later ALA, sep.92 ------- */ 04548 if (pc->cuopen == SISL_CRV_PERIODIC) 04549 { 04550 double delta = pc->et[pc->in] - pc->et[pc->ik - 1]; 04551 04552 while(apar1 < pc->et[pc->ik - 1] && DNEQUAL(apar1, pc->et[pc->ik - 1])) 04553 apar1 += delta; 04554 while(apar1 > pc->et[pc->in] || DEQUAL(apar1, pc->et[pc->in])) 04555 apar1 -= delta; 04556 04557 while (apar2 < apar1 || DEQUAL(apar2, apar1)) 04558 apar2 += delta; 04559 04560 while (apar2 > (apar1+delta) && DNEQUAL(apar2, (apar1+delta))) 04561 apar2 -= delta; 04562 04563 /* Shift startpoint of curve (and make it ordinary closed )*/ 04564 s1710 (pc, apar1, &q1, &q2, &kstat); 04565 if (kstat < 0) 04566 goto err153; 04567 04568 if (q2) 04569 freeCurve (q2); 04570 q2 = SISL_NULL; 04571 04572 /* Split into two */ 04573 s1710 (q1, apar2, rcnew1, rcnew2, &kstat); 04574 if (kstat < 0) 04575 goto err153; 04576 04577 if (q1) 04578 freeCurve (q1); 04579 q1 = SISL_NULL; 04580 04581 04582 *jstat = 0; 04583 goto out; 04584 } 04585 /* End of treating periodicity UJK, jan.92 ------- */ 04586 04587 04588 /* Divide the curve into two at each point. 04589 Join the two end curves at each end.*/ 04590 04591 if (apar1 < apar2) 04592 { 04593 s1712 (pc, apar1, apar2, &q1, &kstat); 04594 if (kstat) 04595 goto err153; 04596 04597 s1713 (pc, apar2, apar1, &q2, &kstat); 04598 if (kstat) 04599 goto err153; 04600 } 04601 04602 else 04603 { 04604 s1712 (pc, apar2, apar1, &q2, &kstat); 04605 if (kstat) 04606 goto err153; 04607 04608 s1713 (pc, apar1, apar2, &q1, &kstat); 04609 if (kstat) 04610 goto err153; 04611 } 04612 04613 /* Updating output. */ 04614 04615 *rcnew1 = q1; 04616 *rcnew2 = q2; 04617 *jstat = 0; 04618 goto out; 04619 04620 04621 /* Error. Subrutine error. */ 04622 04623 err153: 04624 *jstat = kstat; 04625 goto outfree; 04626 04627 04628 /* Error. No curve to pick a part of. */ 04629 04630 err150: 04631 *jstat = -150; 04632 s6err ("s1714", *jstat, kpos); 04633 goto out; 04634 04635 04636 /* Error. No part, apar1 and apar2 has illegal values. */ 04637 04638 err151: 04639 *jstat = -151; 04640 s6err ("s1714", *jstat, kpos); 04641 goto out; 04642 04643 04644 /* Error in output. */ 04645 04646 outfree: 04647 if (q1) 04648 freeCurve (q1); 04649 if (q2) 04650 freeCurve (q2); 04651 04652 out: 04653 return; 04654 } 04655 04656 04657 //=========================================================================== 04658 void s1713(SISLCurve *pc,double abeg,double aend,SISLCurve **rcnew,int *jstat) 04659 //=========================================================================== 04660 { 04661 int kstat; /* Local status variable. */ 04662 int kpos=0; /* Position of error. */ 04663 double tbeg,tend; /* The smaller and greater point. */ 04664 SISLCurve *q1=SISL_NULL; /* Pointer to new curve-object. */ 04665 SISLCurve *q2=SISL_NULL; /* Pointer to new curve-object. */ 04666 SISLCurve *q3=SISL_NULL; /* Pointer to new curve-object. */ 04667 SISLCurve *q4=SISL_NULL; /* Pointer to new curve-object. */ 04668 04669 /* Check that we have a curve to pick a part of. */ 04670 04671 if (!pc) goto err150; 04672 04673 /* Treating periodicity UJK, jan.92 ------- */ 04674 if (pc->cuopen == SISL_CRV_PERIODIC) 04675 { 04676 s1714 (pc, abeg, aend, rcnew, &q1, jstat); 04677 if (q1) freeCurve(q1);q1=SISL_NULL; 04678 goto out; 04679 } 04680 04681 /* Check that the intersection points is interior points. */ 04682 04683 if ((abeg < pc->et[0] && DNEQUAL(abeg,pc->et[0])) || 04684 (abeg > pc->et[pc->in+pc->ik-1] && DNEQUAL(abeg,pc->et[pc->in+pc->ik-1]))) 04685 goto err151; 04686 if ((aend < pc->et[0] && DNEQUAL(aend,pc->et[0])) || 04687 (aend > pc->et[pc->in+pc->ik-1] && DNEQUAL(aend,pc->et[pc->in+pc->ik-1]))) 04688 goto err151; 04689 04690 /* Find the smaller and greater of the intersection points. */ 04691 04692 if (abeg<aend) 04693 { 04694 tbeg = abeg; 04695 tend = aend; 04696 } 04697 else 04698 if (abeg>aend) 04699 { 04700 tbeg = aend; 04701 tend = abeg; 04702 } 04703 04704 if (DEQUAL(abeg,aend)) 04705 { 04706 /* In this case we have just one point to 04707 devide at. The result is two curves, q1 q1. */ 04708 04709 s1710(pc,abeg,&q1,&q3,&kstat); 04710 if (kstat<0 || kstat==2) goto err153; 04711 } 04712 else 04713 { 04714 /* Devide into two at each point, 04715 we than have tree curves, q1 q2 q3.*/ 04716 04717 s1710(pc,tbeg,&q1,&q4,&kstat); 04718 if (kstat<0 || kstat==2) goto err153; 04719 04720 s1710(q4,tend,&q2,&q3,&kstat); 04721 if (kstat<0 || kstat==2) goto err153; 04722 04723 freeCurve(q4); q4 = SISL_NULL; 04724 } 04725 04726 /* If nessesary we have to join curve q3 and q1 to get the new curve.*/ 04727 04728 if (abeg > aend || DEQUAL(abeg,aend)) 04729 { 04730 if (q2) 04731 { 04732 freeCurve(q2); 04733 q2 = SISL_NULL; 04734 } 04735 if (!q1) 04736 { 04737 q2 = q3; 04738 q3 = SISL_NULL; 04739 } 04740 else if (!q3) 04741 { 04742 q2 = q1; 04743 q1 = SISL_NULL; 04744 } 04745 else 04746 { 04747 s1715(q3,q1,1,0,&q2,&kstat); 04748 if (kstat) goto err153; 04749 } 04750 } 04751 04752 /* Updating output. */ 04753 04754 *rcnew = q2; 04755 *jstat = 0; 04756 goto out; 04757 04758 /* Error. Subrutine error. */ 04759 04760 err153: 04761 *jstat = kstat; 04762 goto outfree; 04763 04764 /* Error. No curve to pick a part of. */ 04765 04766 err150: 04767 *jstat = -150; 04768 s6err("s1713",*jstat,kpos); 04769 goto out; 04770 04771 /* Error. No part, abeg and aend has illegal values. */ 04772 04773 err151: 04774 *jstat = -151; 04775 s6err("s1713",*jstat,kpos); 04776 goto out; 04777 04778 /* Error in output. */ 04779 04780 outfree: 04781 if(q2) freeCurve(q2); 04782 04783 /* Free local used memory. */ 04784 04785 out: 04786 if(q1) freeCurve(q1); 04787 if(q3) freeCurve(q3); 04788 if(q4) freeCurve(q4); 04789 return; 04790 } 04791 04792 04793 //=========================================================================== 04794 void s1706(SISLCurve *pc) 04795 //=========================================================================== 04796 { 04797 int kk=pc->ik; /* Order of the input curve. */ 04798 int kn=pc->in; /* Number of vertices in the input curve.*/ 04799 int kdim=pc->idim; /* Dimensjon of the space in whice curve 04800 lies. */ 04801 register double *s1,*s2; 04802 register double *s3; /* Pointers used in loop. */ 04803 register double t1,t2; /* Help variables. */ 04804 04805 /* Now curve to turn. */ 04806 04807 if (!pc) goto out; 04808 04809 /* Here we are turning the knot vector such that the first 04810 element have the same value as the old first element. */ 04811 04812 for (s1=pc->et,s2=s1+kk+kn-1,t1=(*s1)+(*s2); s1<=s2; s1++,s2--) 04813 { 04814 t2 = *s1; 04815 *s1 = t1 - *s2; 04816 *s2 = t1 - t2; 04817 } 04818 04819 /* Here we just turn the vertices. */ 04820 04821 for (s1=pc->ecoef,s2=s1+kdim*(kn-1); s1<s2; s2-=2*kdim) 04822 for (s3=s1+kdim; s1<s3; s1++,s2++) 04823 { 04824 t1 = *s1; 04825 *s1 = *s2; 04826 *s2 = t1; 04827 } 04828 04829 /* If necessary turn rational vertices. */ 04830 04831 if (pc->ikind == 2 || pc->ikind == 4) 04832 { 04833 kdim++; 04834 for (s1=pc->rcoef,s2=s1+kdim*(kn-1); s1<s2; s2-=2*kdim) 04835 for (s3=s1+kdim; s1<s3; s1++,s2++) 04836 { 04837 t1 = *s1; 04838 *s1 = *s2; 04839 *s2 = t1; 04840 } 04841 } 04842 04843 out: 04844 return; 04845 } 04846 04847 //=========================================================================== 04848 void pick_crv_sf(SISLObject *po1, SISLObject *po2,int ipar, 04849 SISLIntpt *pt1,SISLIntpt *pt2,SISLCurve **rcrv, int *jstat) 04850 //=========================================================================== 04851 { 04852 int kstat = 0; /* Local status parameter. */ 04853 int kpos = 0; /* Position of error. */ 04854 int index=0; /* Index of other par dir in surf. */ 04855 int first_const; /* Flag, const first direction or not */ 04856 double tpar; /* Parameter value of curve in constant parameter 04857 direction. */ 04858 SISLSurf *ps1=SISL_NULL; /* Pointer to surf to pick crv from */ 04859 SISLCurve *pick_crv=SISL_NULL;/* Picked curve before trimming. */ 04860 /* -------------------------------------------------------------------- */ 04861 if (ipar < 0 || ipar >= po1->iobj + po2->iobj) goto errinp; 04862 04863 if (ipar >= po1->iobj) 04864 { 04865 /* pick from second object (must be a sf) */ 04866 if (po2->iobj != SISLSURFACE) goto errinp; 04867 ps1 = po2->s1; 04868 index = (ipar == po1->iobj) ? po1->iobj + 1 : po1->iobj; 04869 } 04870 else 04871 { 04872 /* pick from first object (must be a sf) */ 04873 if (po1->iobj != SISLSURFACE) goto errinp; 04874 ps1 = po1->s1; 04875 index = (ipar == 0) ? 1 : 0; 04876 } 04877 04878 if (ipar < index) first_const = TRUE; 04879 else first_const = FALSE; 04880 tpar = pt1->epar[ipar]; 04881 04882 04883 if (first_const == FALSE) 04884 { 04885 /* Pick curve with constant second parameter. */ 04886 s1436(ps1,tpar,&pick_crv,&kstat); 04887 if (kstat < 0) goto error; 04888 } 04889 else 04890 { 04891 /* Pick curve with constant first parameter. */ 04892 s1437(ps1,tpar,&pick_crv,&kstat); 04893 if (kstat < 0) goto error; 04894 } 04895 04896 /* SISLCurve picked, now trim it. */ 04897 if (DEQUAL(pt1->epar[index], pick_crv->et[pick_crv->ik-1]) && 04898 DEQUAL(pt2->epar[index], pick_crv->et[pick_crv->in])) 04899 { 04900 /* Return the whole curve */ 04901 (*rcrv) = pick_crv; 04902 pick_crv = SISL_NULL; 04903 } 04904 04905 04906 else if(DEQUAL(pt1->epar[index], pick_crv->et[pick_crv->in]) && 04907 DEQUAL(pt2->epar[index], pick_crv->et[pick_crv->ik-1])) 04908 { 04909 /* Return the whole curve, but turn it first */ 04910 /* Return the whole curve */ 04911 (*rcrv) = pick_crv; 04912 pick_crv = SISL_NULL; 04913 s1706(*rcrv); 04914 } 04915 else 04916 { 04917 /* Return a part of the curve */ 04918 double amin = min(pt1->epar[index], pt2->epar[index]); 04919 double amax = max(pt1->epar[index], pt2->epar[index]); 04920 04921 if (pick_crv->cuopen == SISL_CRV_PERIODIC) 04922 s1713(pick_crv,amin,amax,rcrv,&kstat); 04923 else 04924 s1712(pick_crv,amin,amax,rcrv,&kstat); 04925 04926 if (kstat < 0) goto error; 04927 04928 if (pt1->epar[index] > pt2->epar[index]) s1706(*rcrv); 04929 04930 } 04931 04932 *jstat = 0; 04933 goto out; 04934 04935 /* Error in input. */ 04936 errinp : *jstat = -1; 04937 s6err("pick_crv_sf",*jstat,kpos); 04938 goto out; 04939 04940 /* Error in lower level routine. */ 04941 error : *jstat = kstat; 04942 s6err("pick_crv_sf",*jstat,kpos); 04943 goto out; 04944 04945 out: if (pick_crv) freeCurve(pick_crv); 04946 } 04947 04948 04949 //=========================================================================== 04950 SISLIntsurf *newIntsurf (SISLIntlist * pintlist) 04951 //=========================================================================== 04952 { 04953 SISLIntsurf *pnew = SISL_NULL; /* Local pointer to instance to create. */ 04954 SISLIntpt *qpt = SISL_NULL; /* Local help pointer */ 04955 SISLIntpt *qpfirst = SISL_NULL; /* Local help pointer */ 04956 SISLIntpt *qplast = SISL_NULL; /* Local help pointer */ 04957 SISLIntpt *qprev = SISL_NULL; /* Local help pointer */ 04958 SISLIntpt *qnext = SISL_NULL; /* Local help pointer */ 04959 int index, ipar, ipoint; 04960 int ki, kk, kdir; /* Counter. */ 04961 int dummy,kstat; 04962 double *stpar1, *stpar2; 04963 /* ------------------------------------------------------------------ */ 04964 04965 if (pintlist == SISL_NULL) 04966 goto out; 04967 04968 qpfirst = pintlist->pfirst; 04969 qplast = pintlist->plast; 04970 ipoint = pintlist->inumb - 1; 04971 ipar = qpfirst->ipar; 04972 index = pintlist->ind_first; 04973 04974 04975 if (ipar <= 0) 04976 goto out; 04977 if (ipoint <= 1) 04978 goto out; 04979 04980 /* Allocate space for instance of Intsurf. */ 04981 pnew = newarray (1, SISLIntsurf); 04982 if (pnew == SISL_NULL) 04983 goto err101; 04984 04985 pnew->ipar = ipar; 04986 pnew->ipoint = ipoint; 04987 04988 /* First allocate space for parameter array. */ 04989 pnew->epar = stpar1 = newarray (ipar * ipoint, DOUBLE); 04990 if (pnew->epar == SISL_NULL) 04991 goto err101; 04992 04993 /* Allocate space for constant direction array. */ 04994 /* UJK, sept 92 */ 04995 /* pnew->const_par = newarray (ipar, int); */ 04996 pnew->const_par = newarray (ipoint, int); 04997 if (pnew->const_par == SISL_NULL) 04998 goto err101; 04999 05000 /* Fill in arrays */ 05001 05002 qpt = qprev = qpfirst; 05003 qnext = qpt->pnext[index]; 05004 05005 for (ki = 0; ki < ipoint; ki++) 05006 { 05007 qpt->marker = -99; 05008 stpar2 = qpt->epar; 05009 for (kk = 0; kk < ipar; kk++) 05010 *(stpar1++) = *(stpar2++); 05011 05012 for (kdir = 0; kdir < ipar; kdir++) 05013 if (qpt->curve_dir[index] & 05014 (1 << (kdir + 1))) 05015 break; 05016 05017 pnew->const_par[ki] = kdir; 05018 05019 /* Next point */ 05020 qprev = qpt; 05021 qpt = qnext; 05022 sh6getother (qpt, qprev, &qnext, &kstat); 05023 05024 sh6getlist (qpt, qnext, &index, &dummy, &kstat); 05025 } 05026 05027 /* Task done. */ 05028 05029 05030 goto out; 05031 05032 /* Error in space allocation. Return zero. */ 05033 05034 err101:pnew = SISL_NULL; 05035 goto out; 05036 05037 out:return (pnew); 05038 } 05039 05040 //=========================================================================== 05041 void s1425(SISLSurf *ps1,int ider1,int ider2,int iside1,int iside2,double epar[], 05042 int *ileft1,int *ileft2,double eder[],int *jstat) 05043 //=========================================================================== 05044 { 05045 int kstat=0; /* Local status variable. */ 05046 int kpos=0; /* The position of error. */ 05047 int kn1,kn2; /* The number of B-splines accociated with the knot 05048 vectors st1 and st2. */ 05049 int kn; /* Variable used for storing shorter version of knot 05050 vector used by left hand derivatives */ 05051 int kmult; /* Multiplicity of knot */ 05052 int kk1,kk2; /* The polynomial order of the surface in the two 05053 directions. */ 05054 int kdim; /* The dimension of the space in which the surface 05055 lies. Equivalently, the number of components 05056 of each B-spline coefficient. */ 05057 int kder1,kder2; /* Local versions of ider1 and ider2. Since 05058 derivatives of order higher than kk1-1 and kk2-1, 05059 respectively, are all zero, we set 05060 kder1=min(kk1-1,ider1) and kder2=(kk2-1,ider2). */ 05061 int kleft2,kleft1; /* Local versions of ileft1 and ileft2 which are 05062 used in order to avoid the pointers. */ 05063 int ki,kj,kih,kjh; /* Control variables in for loops and for stepping 05064 through arrays. */ 05065 int kh,kl,kl1,kl2; /* Control variables in for loops and for stepping 05066 through arrays. */ 05067 double *st1,*st2; /* The knot vectors of the surface. These have 05068 length [kn1+kk1] and [kn2+kk2], 05069 respectively. */ 05070 double *scoef; /* The B-spline coefficients of the surface. 05071 This is an array of dimension [kn2*kn1*kdim]. */ 05072 double tt; /* Dummy variable used for holding an array element 05073 in a for loop. */ 05074 double *ebder=SISL_NULL; /* Pointer to an array of dimension 05075 [max(kk1*(ider1+1),kk2*(ider2+1))] which will 05076 contain the values and ider first derivatives of 05077 the kk1 (kk2) nonzero B-splines at epar[0] (epar[1]). 05078 These are stored in the following order: 05079 First the value, 1. derivative etc. of the 05080 first nonzero B-spline, then the same for the 05081 second nonzero B-spline and so on. */ 05082 05083 double *ew=SISL_NULL; /* Pointer to an array of dimension [kk1*(ider1+1)*kdim] 05084 which will be used to store the result of the first 05085 matrix multiplication in (2) above. This array is 05086 initialized to all zeros. */ 05087 double *sder=SISL_NULL; /* Pointer to array used for storage of points, if 05088 non rational sder points to eder, if rational sder 05089 has to be allocated to make room for the homogenous 05090 coordinate */ 05091 05092 double sdum1[49]; /* Arraye used for ebder */ 05093 double sdum2[147]; /* Array used for ew */ 05094 int knumb1; /* Necessary size of ebder */ 05095 int knumb2; /* Necessary size of ew */ 05096 05097 kleft2 = *ileft2; 05098 kleft1 = *ileft1; 05099 05100 /* Copy surface to local parameters. */ 05101 05102 kn1 = ps1 -> in1; 05103 kn2 = ps1 -> in2; 05104 kk1 = ps1 -> ik1; 05105 kk2 = ps1 -> ik2; 05106 st1 = ps1 -> et1; 05107 st2 = ps1 -> et2; 05108 kdim = ps1 -> idim; 05109 if (ps1->ikind == 2 || ps1->ikind == 4) 05110 { 05111 scoef = ps1 -> rcoef; 05112 kdim +=1; 05113 if((sder=newarray(kdim*(ider1+1)*(ider2+1),DOUBLE)) == SISL_NULL) 05114 goto err101; 05115 } 05116 else 05117 { 05118 scoef = ps1 -> ecoef; 05119 sder = eder; 05120 } 05121 05122 /* Check the input. */ 05123 05124 if (kdim < 1) goto err102; 05125 05126 if (kk1 < 1) goto err115; 05127 05128 if (kn1 < kk1 || kn2 < kk2) goto err116; 05129 05130 if (ider1 < 0 || ider2 < 0) goto err178; 05131 05132 if (st1[kk1-1] == st1[kk1] || st1[kn1-1] == st1[kn1]) goto err117; 05133 05134 if (st2[kk2-1] == st2[kk2] || st2[kn2-1] == st2[kn2]) goto err117; 05135 05136 kder1 = min(kk1-1,ider1); 05137 kder2 = min(kk2-1,ider2); 05138 05139 /* Allocate space for B-spline values and derivatives and one work array. */ 05140 05141 knumb1 = max(kk1*(kder1+1),kk2*(kder2+1)); 05142 05143 /* ONly allocate ebder if sdum1 too small */ 05144 05145 if (knumb1>49) 05146 { 05147 if((ebder=newarray(knumb1,double)) == SISL_NULL) goto err101; 05148 } 05149 else 05150 { 05151 ebder = &sdum1[0]; 05152 for (ki=0;ki<knumb1;ki++) 05153 ebder[ki] = DZERO; 05154 } 05155 05156 if (ebder == SISL_NULL) goto err101; 05157 05158 /* Only allocate ew if sdum2 too small */ 05159 05160 knumb2 = (kk1*(kder2+1)*kdim); 05161 if (knumb2>147) 05162 { 05163 if((ew=new0array(knumb2,double)) == SISL_NULL) goto err101; 05164 } 05165 else 05166 { 05167 ew = &sdum2[0]; 05168 for (ki=0;ki<knumb2;ki++) 05169 sdum2[ki] = DZERO; 05170 } 05171 05172 if (ew == SISL_NULL) goto err101; 05173 05174 /* Set all the elements of sder to 0. */ 05175 05176 for (ki=0; ki<(ider2+1)*(ider1+1)*kdim; ki++) sder[ki] = DZERO; 05177 05178 /* If the left hand derivative at epar[1] is to be calculated, this can be 05179 done by forgetting all polynomial segments starting in epar[1] or 05180 right of epar[1], thus the position of epar[1] in the knot vector is to be 05181 calculated */ 05182 05183 if (iside2<0) 05184 { 05185 /* Calculate last knot equal to or left of epar[1] */ 05186 05187 s1219(st2,kk2,kn2,&kleft2,epar[1],&kstat); 05188 if (kstat < 0) goto error; 05189 05190 05191 if (st2[kn2] == epar[1]) 05192 kmult = 0; 05193 else 05194 { 05195 kmult = s6knotmult(st2,kk2,kn2,&kleft2,epar[1],&kstat); 05196 if (kstat < 0) goto error; 05197 } 05198 05199 kleft2 = MAX(kk2-1,kleft2 - kmult); 05200 kn = kleft2+1; 05201 } 05202 else 05203 kn = kn2; 05204 05205 /* Compute the values and derivatives of the nonzero B-splines in the 05206 second parameter direction. */ 05207 05208 s1220(st2,kk2,kn,&kleft2,epar[1],kder2,ebder,&kstat); 05209 05210 if (kstat < 0) goto error; 05211 05212 /* Update ileft1 (ileft2 was updated above, in s1220). */ 05213 05214 s1219(st1,kk1,kn1,&kleft1,epar[0],&kstat); 05215 if (kstat < 0) goto error; 05216 05217 /* If the left hand derivative at epar[0] is to be calculated, this can be 05218 done by forgetting all polynomial segments starting in epar[0] or 05219 right of epar[0], thus the position of epar[0] in the knot vector 05220 is to be calculated */ 05221 05222 if (iside1<0) 05223 { 05224 /* ileft1 already calculated */ 05225 if (epar[0] == st1[kn1]) 05226 kmult = 0; 05227 else 05228 { 05229 kmult = s6knotmult(st1,kk1,kn1,&kleft1,epar[0],&kstat); 05230 if (kstat < 0) goto error; 05231 } 05232 05233 kleft1 = MAX(kk1-1,kleft1-kmult); 05234 kn = kleft1 + 1; 05235 } 05236 else 05237 kn = kn1; 05238 05239 /* Compute the first matrix product in (2) above. */ 05240 05241 /* ki steps through the appropriate kk2 rows of B-spline coefficients 05242 while kih steps through the B-spline value and derivatives for the 05243 B-spline given by ki. */ 05244 05245 kih = 0; 05246 for (ki=kleft2-kk2+1; ki<=kleft2; ki++) 05247 { 05248 05249 /* kj counts through the kder2+1 derivatives to be computed. 05250 kjh steps through ew once for each ki to accumulate the contribution 05251 from the different B-splines. 05252 kl1 points to the first component of the first B-spline coefficient 05253 in row no. ki of the B-spline coefficient matrix that multiplies 05254 a nonzero B-spline in the first parameter direction. 05255 */ 05256 05257 kjh = 0; kl1 = ki*kdim*kn1 + kdim*(kleft1-kk1+1); 05258 for (kj=0; kj<=kder2; kj++) 05259 { 05260 05261 /* The value of the B-spline derivative is stored in tt while 05262 kl2 steps through the kdim components of all the B-spline 05263 coefficients that multiplies nonzero B-splines along st1. 05264 */ 05265 05266 tt = ebder[kih++]; kl2 = kl1; 05267 for (kl=0; kl<kdim*kk1; kl++,kjh++,kl2++) 05268 { 05269 ew[kjh] += scoef[kl2]*tt; 05270 } 05271 } 05272 } 05273 05274 05275 /* Compute the values and derivatives of the nonzero B-splines in the 05276 first parameter direction. */ 05277 05278 s1220(st1,kk1,kn,&kleft1,epar[0],kder1,ebder,&kstat); 05279 05280 if (kstat < 0) goto error; 05281 05282 /* Compute the remaining matrix product. */ 05283 05284 /* kh steps through the kder2+1 derivatives in the first parameter direction 05285 (the rows of ew if we image it as a kk1x(ider1+1) matrix with each element 05286 a kdim dimensional vector) while kl1 steps through the elements of ew 05287 (again considering each element to have kdim components). 05288 */ 05289 05290 kl1 = 0; 05291 for (kh=0; kh<=kder2; kh++) 05292 { 05293 05294 /* ki steps through the kk1 columns of ew (corresponding to the columns 05295 of scoef that multiply nonzero B-splines along st1), while kih 05296 steps through the B-spline values and derivatives for the nonzero 05297 B-splines along st1 (stored in ebder). 05298 */ 05299 05300 kih = 0; 05301 for (ki=0; ki<kk1; ki++) 05302 { 05303 05304 /* kj counts through the kder1+1 derivatives in the first 05305 parameter direction (corresponding to the columns of sder). 05306 kjh points to the row of sder corresponding to derivatives of 05307 order kh in the second parameter direction (if sder is 05308 considered a matrix with elements consisting of vectors with 05309 kdim components. 05310 */ 05311 05312 kjh = kh*(kder1+1)*kdim; 05313 for (kj=0; kj<=kder1; kj++) 05314 { 05315 /* Pick out the current element of ebder. 05316 kl2 steps through the kdim components of the (kh,ki) 05317 element of ew. 05318 */ 05319 05320 tt = ebder[kih++]; 05321 kl2 = kl1; 05322 for (kl=0; kl<kdim; kl++,kjh++,kl2++) 05323 { 05324 sder[kjh] += ew[kl2]*tt; 05325 } 05326 } 05327 kl1 += kdim; 05328 } 05329 } 05330 05331 if (kder1 < ider1 || kder2 < ider2) 05332 05333 /* The derivatives are not positioned in the right way in sder, 05334 shift values into the right position 05335 */ 05336 05337 for (kj=ider2 ; 0<=kj ; kj--) 05338 { 05339 for (ki=ider1 ; 0<=ki ; ki--) 05340 { 05341 if ( ki <= kder1 && kj <= kder2) 05342 memcopy(sder+kdim*(ki+kj*(ider1+1)),sder+kdim*(ki+kj*(kder1+1)), 05343 kdim,DOUBLE); 05344 else 05345 for (kl=0;kl<kdim;kl++) 05346 *(sder+kdim*(ki+kj*(ider1+1))+kl) = DZERO; 05347 } 05348 } 05349 /* Free memory. */ 05350 05351 /* If rational surface calculate the derivatives based on derivatives in 05352 homogenous coordinates */ 05353 05354 if (ps1->ikind == 2 || ps1->ikind == 4) 05355 { 05356 s6sratder(sder,ps1->idim,ider1,ider2,eder,&kstat); 05357 if (kstat<0) goto error; 05358 if(sder != SISL_NULL) freearray(sder); 05359 } 05360 05361 /* Only free ew and ebder if the were allocated by newarray */ 05362 05363 if (knumb1 > 49) 05364 { 05365 if(ebder != SISL_NULL) freearray(ebder); 05366 } 05367 if (knumb2 > 147) 05368 { 05369 if(ew != SISL_NULL) freearray(ew); 05370 } 05371 05372 /* Successful computations. */ 05373 05374 *jstat = 0; 05375 goto out; 05376 05377 /* Not enough memory. */ 05378 err101: *jstat = -101; 05379 s6err("s1425",*jstat,kpos); 05380 goto out; 05381 05382 /* kdim less than 1. */ 05383 err102: *jstat = -102; 05384 s6err("s1425",*jstat,kpos); 05385 goto out; 05386 05387 /* Polynomial order less than 1. */ 05388 err115: *jstat = -115; 05389 s6err("s1425",*jstat,kpos); 05390 goto out; 05391 05392 /* Fewer B-splines than the order. */ 05393 err116: *jstat = -116; 05394 s6err("s1425",*jstat,kpos); 05395 goto out; 05396 05397 /* Error in knot vector. 05398 (The first or last interval of one of the knot vectors is empty.) */ 05399 err117: *jstat = -117; 05400 s6err("s1425",*jstat,kpos); 05401 goto out; 05402 05403 /* Illegal derivative requested. */ 05404 err178: *jstat = -178; 05405 s6err("s1425",*jstat,kpos); 05406 goto out; 05407 05408 /* Error in lower level routine. */ 05409 05410 error: *jstat = kstat; 05411 s6err("s1425",*jstat,kpos); 05412 goto out; 05413 05414 out: 05415 *ileft2 = kleft2; 05416 *ileft1 = kleft1; 05417 return; 05418 } 05419 05420 05421 05422 //=========================================================================== 05423 void s1422(SISLSurf *ps1,int ider,int iside1,int iside2,double epar[],int *ilfs, 05424 int *ilft,double eder[],double enorm[],int *jstat) 05425 //=========================================================================== 05426 { 05427 int kstat=0; /* Local status variable. */ 05428 int kpos=0; /* Position of error. */ 05429 int kdim; /* Dimension of the space in which the surface lies. */ 05430 int keder; /* Integer used in address calculations on eder */ 05431 int ksp; /* Integer used in address calculations on sp */ 05432 int kincre; /* Increment for address calculations */ 05433 int ki,kl; /* Control variables in for loop */ 05434 int knumb; /* Number of elements used for storage of deriv.s */ 05435 double *sp; /* Pointer to temporary array */ 05436 double sdum[48]; /* Array used in stead of allocation */ 05437 05438 05439 /* Allocate array for storage of ider*ider derivatives */ 05440 05441 sp = SISL_NULL; 05442 kdim = ps1 -> idim; 05443 knumb = kdim*(ider+1)*(ider+1); 05444 05445 /* Only allocate space if sdum is too smaall */ 05446 05447 if (knumb>48) 05448 sp = newarray(knumb,DOUBLE); 05449 else 05450 sp = &sdum[0]; 05451 05452 if (sp == SISL_NULL) goto err101; 05453 05454 05455 /* Evaluate s1422surface. */ 05456 05457 s1425(ps1,ider,ider,iside1,iside2,epar,ilfs,ilft,sp,&kstat); 05458 05459 if (kstat < 0) goto error; 05460 05461 /* Copy required derivatives into eder */ 05462 05463 kincre = kdim*ider; 05464 05465 /* Copy all derivatives of order 0, then of order 1, up to order ider */ 05466 05467 for (kl=0,keder=0;kl<=ider;kl++) 05468 { 05469 for (ki=0,ksp=kl*kdim ; ki<=kl ; ki++,ksp+=kincre,keder+=kdim) 05470 { 05471 memcopy(eder+keder,sp+ksp,kdim,DOUBLE); 05472 } 05473 } 05474 05475 /* Make cross products of tangents, if idim==3 and derivative >0 */ 05476 05477 if (ider>0 && kdim ==3) 05478 { 05479 double tlen1,tlen2,tnorm,tang=(double)0.0; 05480 05481 s6crss(eder+kdim,eder+2*kdim,enorm); 05482 05483 /* Make length of tangents and normal */ 05484 05485 tlen1 = s6length(eder+kdim,kdim,&kstat); 05486 tlen2 = s6length(eder+2*kdim,kdim,&kstat); 05487 tnorm = s6length(enorm,kdim,&kstat); 05488 05489 /* Calculate angle between tangents */ 05490 05491 if (tlen1 != DZERO && tlen2 != DZERO && tnorm != DZERO) 05492 tang = tnorm/(tlen1*tlen2); 05493 05494 if (tang == DZERO) *jstat = 2; 05495 else if (tang <= ANGULAR_TOLERANCE) *jstat = 1; 05496 else *jstat = 0; 05497 goto out; 05498 05499 } 05500 05501 *jstat = 0; 05502 goto out; 05503 05504 /* Error in lower level routine. */ 05505 05506 error : *jstat = kstat; 05507 s6err("s1422",*jstat,kpos); 05508 goto out; 05509 05510 err101: *jstat = -101; 05511 s6err("s1422",*jstat,kpos); 05512 05513 05514 out: 05515 05516 /* Free allocated space (Space only allocated if sdum is too small) */ 05517 05518 if (knumb>48) 05519 if (sp != SISL_NULL) freearray(sp); 05520 05521 return; 05522 } 05523 05524 05525 //=========================================================================== 05526 void sh6evalint (SISLObject * ob1, SISLObject * ob2, double eimpli[], int ideg, 05527 SISLIntpt * pt, double aepsge, double *curve_3d[], 05528 double *curve_2d_1[], double *curve_2d_2[], int *jstat) 05529 //=========================================================================== 05530 { 05531 int dim; /* Geometric dimension. */ 05532 int kstat; 05533 int kpos = 1; /* Position indicator ofr errors */ 05534 int left1 = 0, left2 = 0; /* Knot navigators in s1421 */ 05535 int kder = 2; /* Numb of derivatives */ 05536 int silhouett; /* Flag silhouett case */ 05537 int ki; /* Variable used in loop */ 05538 int ksize; /* Size of output from s1421 or getgeom */ 05539 double *geom1 = SISL_NULL; /* Output values from s1421 or getgeom */ 05540 double con_tang[3]; /* Constant tangent. */ 05541 double *norm1 = SISL_NULL; /* Output values from s1421 or getgeom */ 05542 double *geom2 = SISL_NULL; /* Output values from s1421 or getgeom */ 05543 double *norm2 = SISL_NULL; /* Output values from s1421 or getgeom */ 05544 double normimpl[3]; /* Normal of impl surf */ 05545 double right_dir[3]; /* Right direction of 3D intersect. curve */ 05546 double dot; /* Scalar product */ 05547 double dummy[6]; 05548 double ang; 05549 double min_hp_ang = 0.00000000001; 05550 *jstat = 0; 05551 con_tang[0] = (double) 1.0; 05552 con_tang[1] = DZERO; 05553 con_tang[2] = DZERO; 05554 05555 05556 if (ob1->iobj != SISLSURFACE && ob1->iobj != SISLCURVE) 05557 goto errinp; 05558 if (!pt) 05559 goto errinp; 05560 if (ideg < 0) 05561 goto errinp; 05562 05563 if (ob1->iobj == SISLSURFACE ) 05564 dim = ob1->s1->idim; 05565 else 05566 dim = ob1->c1->idim; 05567 05568 if (dim > 3 || dim < 1) 05569 goto errinp; 05570 05571 *curve_3d = pt->geo_track_3d; 05572 *curve_2d_1 = pt->geo_track_2d_1; 05573 *curve_2d_2 = pt->geo_track_2d_2; 05574 05575 if (pt->evaluated) 05576 goto out; 05577 05578 if (ideg == 0) 05579 { 05580 /* No implicit geometry involved */ 05581 kpos = 1; 05582 if (ob2->iobj != SISLSURFACE && ob2->iobj != SISLCURVE) 05583 goto errinp; 05584 05585 if (ob2->iobj == SISLCURVE) 05586 { 05587 /* At least the second object is a spline curve, 05588 use this one */ 05589 kpos = 2; 05590 if (ob2->c1->idim > 3) goto errinp; 05591 05592 /* Get geometry of first surface */ 05593 sh6getgeom (ob1, 1, pt, &geom1, &norm1, aepsge, &kstat); 05594 if (kstat < 0) 05595 goto error; 05596 05597 /* Get geometry of objects */ 05598 sh6getgeom (ob2, 2, pt, &geom2, &norm2, aepsge, &kstat); 05599 if (kstat < 0) 05600 goto error; 05601 05602 /* The number of elements to copy is given by pt->size_<obnr> 05603 and we have obnr=2 (PFU 05/09-94) */ 05604 memcopy(*curve_3d,geom2,pt->size_2,double); 05605 05606 } 05607 else 05608 { 05609 05610 05611 /* Two 3d surfaces */ 05612 kpos = 3; 05613 if (ob2->iobj != SISLSURFACE) 05614 goto errinp; 05615 if ((dim = ob2->s1->idim) != 3) 05616 goto errinp; 05617 05618 /* Get geometry of first surface */ 05619 sh6getgeom (ob1, 1, pt, &geom1, &norm1, aepsge, &kstat); 05620 if (kstat < 0) 05621 goto error; 05622 05623 /* Get geometry of second surface */ 05624 sh6getgeom (ob2, 2, pt, &geom2, &norm2, aepsge, &kstat); 05625 if (kstat < 0) 05626 goto error; 05627 05628 /* Get normal direction */ 05629 s6crss (norm1, norm2, right_dir); 05630 if (kstat < 0) 05631 goto error; 05632 05633 /* Compute angle. */ 05634 ang = s6ang(norm1, norm2,3); 05635 if (ang < min_hp_ang) 05636 { 05637 /* The point is a singular meeting point.*/ 05638 if (pt->iinter == SI_ORD) pt->iinter = SI_SING; 05639 } 05640 05641 /* Get tangent and curvature */ 05642 s1304 (geom1, geom2, pt->epar, pt->epar + 2, 05643 *curve_3d, *curve_2d_1, *curve_2d_2, &kstat); 05644 if (kstat < 0) 05645 goto error; 05646 05647 if ((dot = s6scpr (right_dir, *curve_3d + 3, 3)) < DZERO) 05648 { 05649 /* Change direction for tangent */ 05650 for (ki = 0; ki < 3; ki++) 05651 (*curve_3d)[ki + 3] *= -(double) 1; 05652 for (ki = 0; ki < 2; ki++) 05653 { 05654 (*curve_2d_1)[ki + 2] *= -(double) 1; 05655 (*curve_2d_2)[ki + 2] *= -(double) 1; 05656 } 05657 } 05658 } 05659 05660 pt->evaluated = TRUE; 05661 } 05662 else 05663 { 05664 /* Implicit cases */ 05665 if (ideg == 2000) 05666 { 05667 /* Here we treat the cases 05668 spline surf vs implicit analytic curve 05669 spline curve vs implicit analytic curve 05670 spline curve vs implicit analytic surf 05671 in all these cases only 3D posisition is necessary */ 05672 05673 /* Clean up from 1D or 2D result */ 05674 if (pt->geo_data_1) 05675 freearray (pt->geo_data_1); 05676 if (pt->geo_data_2) 05677 freearray (pt->geo_data_2); 05678 pt->geo_data_1 = SISL_NULL; 05679 pt->size_1 = 0; 05680 pt->geo_data_2 = SISL_NULL; 05681 pt->size_2 = 0; 05682 05683 /* Get the right values are computed */ 05684 sh6getgeom (ob1, 1, pt, &geom1, &norm1, aepsge, &kstat); 05685 if (kstat < 0) 05686 goto error; 05687 05688 memcopy(*curve_3d,geom1,dim,double); 05689 memcopy((*curve_3d)+dim,con_tang,dim,double); 05690 05691 } 05692 else 05693 { 05694 if (ideg == 1003 || ideg == 1004 || ideg == 1005) 05695 { 05696 /* Silhouette cases, B-spline surface */ 05697 kpos = 3; 05698 ksize = 33; 05699 silhouett = TRUE; 05700 kder = 3; 05701 05702 } 05703 else 05704 { 05705 /* Analytic surf vs B-spline surface */ 05706 05707 kpos = 4; 05708 ksize = 21; 05709 silhouett = FALSE; 05710 kder = 2; 05711 } 05712 05713 if (pt->size_1 != ksize) 05714 { 05715 /* Clean up from 1D result */ 05716 if (pt->geo_data_1) 05717 freearray (pt->geo_data_1); 05718 if (pt->geo_data_2) 05719 freearray (pt->geo_data_2); 05720 pt->geo_data_1 = SISL_NULL; 05721 pt->size_1 = 0; 05722 pt->geo_data_2 = SISL_NULL; 05723 pt->size_2 = 0; 05724 05725 05726 if ((pt->geo_data_1 = newarray (ksize, DOUBLE)) 05727 == SISL_NULL) 05728 goto err101; 05729 pt->size_1 = ksize; 05730 geom1 = pt->geo_data_1; 05731 norm1 = pt->geo_data_1 + ksize - 3; 05732 05733 s1422 (ob1->s1, kder, pt->iside_1, pt->iside_2, 05734 pt->epar, &left1, &left2, geom1, 05735 norm1, &kstat); 05736 if (kstat < 0) 05737 goto error; 05738 } 05739 else 05740 { 05741 /* The right values are computed */ 05742 sh6getgeom (ob1, 1, pt, &geom1, &norm1, aepsge, &kstat); 05743 if (kstat < 0) 05744 goto error; 05745 05746 } 05747 05748 05749 /* Get normal of implicit surface */ 05750 s1331 (geom1, eimpli, ideg, kder = -1, dummy, normimpl, &kstat); 05751 if (kstat < 0) 05752 goto error; 05753 05754 /* Get the right direction of the intersection curve */ 05755 if (silhouett) 05756 { 05757 ang = 1.5; /* Not used */ 05758 memcopy (right_dir, normimpl, 3, DOUBLE); 05759 for (ki=0;ki<3;ki++) right_dir[ki] *= -(double)1.0; 05760 } 05761 else 05762 { 05763 /* Compute angle. */ 05764 ang = s6ang(norm1, normimpl,3); 05765 s6crss (norm1, normimpl, right_dir); 05766 } 05767 05768 /* Get tangent and curvature to the real intersection. */ 05769 s1306 (geom1, pt->epar, 05770 eimpli, ideg, *curve_3d, *curve_2d_1, &kstat); 05771 if (kstat < 0) 05772 goto error; 05773 if (kstat == 2) 05774 { 05775 /* The point is a singular meeting point.*/ 05776 if (pt->iinter == SI_ORD) pt->iinter = SI_SING; 05777 } 05778 else if (kstat == 10) 05779 { 05780 /* The point is a singular non-meeting point. 05781 Tangent found, but sign might be wrong. */ 05782 if (pt->iinter == SI_ORD || pt->iinter == SI_SING ) 05783 pt->iinter = SI_TOUCH; 05784 } 05785 else if (ang < min_hp_ang) 05786 { 05787 /* The point is a singular meeting point.*/ 05788 if (pt->iinter == SI_ORD) pt->iinter = SI_SING; 05789 } 05790 else 05791 if ((dot = s6scpr (right_dir, *curve_3d + 3, 3)) < DZERO) 05792 { 05793 /* Change direction for tangent */ 05794 for (ki = 0; ki < 3; ki++) 05795 (*curve_3d)[ki + 3] *= -(double) 1; 05796 for (ki = 0; ki < 2; ki++) 05797 (*curve_2d_1)[ki + 2] *= -(double) 1; 05798 05799 } 05800 } 05801 05802 05803 pt->evaluated = TRUE; 05804 05805 } 05806 05807 *jstat = 0; 05808 goto out; 05809 05810 /* ---------- ERROR EXITS --------------------------- */ 05811 /* Error in alloc */ 05812 err101: 05813 *jstat = -101; 05814 s6err ("shevalint", *jstat, kpos); 05815 goto out; 05816 05817 /* Error in lower level */ 05818 error: 05819 *jstat = kstat; 05820 s6err ("shevalint", *jstat, kpos); 05821 goto out; 05822 05823 /* Error in input */ 05824 errinp: 05825 *jstat = -200; 05826 s6err ("shevalint", *jstat, kpos); 05827 goto out; 05828 05829 05830 out:; 05831 } 05832 05833 05834 //=========================================================================== 05835 void sh6idsplit (SISLIntdat ** pintdat, SISLIntpt * psource, int *jstat) 05836 //=========================================================================== 05837 { 05838 int ki; /* Counters. */ 05839 int no_main; /* No of neighbours (main points) */ 05840 int test= FALSE; /* No equality testing when inserted 05841 in pintdat */ 05842 int kstat = 0; /* Local status. */ 05843 SISLIntpt *pneighb = SISL_NULL; /* Current neighbour */ 05844 SISLIntpt *pshadow = SISL_NULL; /* Current copy of source point */ 05845 /* ------------------------------------------------*/ 05846 05847 *jstat = 0; 05848 05849 if (psource == SISL_NULL) 05850 { 05851 *jstat = 1; 05852 goto out; 05853 } 05854 05855 /* Get number of neighbours */ 05856 no_main = sh6nmbmain (psource, &kstat); 05857 if (kstat < 0) 05858 goto error; 05859 05860 for (ki=psource->no_of_curves - 1; no_main > 1; ki--) 05861 { 05862 pneighb = sh6getnext(psource, ki); 05863 if (!pneighb) goto error; 05864 if (sh6ismain(pneighb)) 05865 { 05866 pshadow = hp_copyIntpt(psource); 05867 sh6idnpt(pintdat, &pshadow, test=FALSE, &kstat); 05868 if (kstat < 0) goto error; 05869 05870 sh6insertpt(psource, pneighb, pshadow, &kstat); 05871 if (kstat < 0) goto error; 05872 05873 sh6disconnect(psource, pshadow, &kstat); 05874 if (kstat < 0) goto error; 05875 no_main--; 05876 } 05877 } 05878 goto out; 05879 05880 05881 error: 05882 *jstat = kstat; 05883 goto out; 05884 05885 out:; 05886 } 05887 05888 05889 //=========================================================================== 05890 void sh6gettophlp (SISLIntpt * pt, int pretop[4], int case_2d, int *jstat) 05891 //=========================================================================== 05892 { 05893 int loc_top[4]; 05894 int ki; 05895 05896 *jstat = 0; 05897 05898 /* Check pt. */ 05899 05900 if (pt == SISL_NULL) 05901 goto err2; 05902 /* Only help points are treated */ 05903 if (sh6ishelp (pt) && pt->marker == 0) 05904 { 05905 /* To avoid infinite loops : */ 05906 pt->marker = -10; 05907 05908 sh6gettop (pt, 0, loc_top, loc_top + 1, loc_top + 2, loc_top + 3, jstat); 05909 if (*jstat < 0) 05910 goto out; 05911 05912 if (case_2d) 05913 { 05914 /* Spesial treatment 2D surf point */ 05915 for (ki=0; ki<4; ki++) 05916 if (loc_top[ki] == SI_IN) pretop[ki] = SI_IN; 05917 else if (loc_top[ki] == SI_OUT && pretop[ki] != SI_IN) 05918 pretop[ki] = SI_OUT; 05919 } 05920 else 05921 { 05922 /* Overrule ? */ 05923 for (ki = 0; ki < 4; ki++) 05924 if ((pretop[ki] == SI_UNDEF || 05925 pretop[ki] == SI_ON) && 05926 loc_top[ki] != SI_UNDEF && 05927 loc_top[ki] != SI_ON) 05928 pretop[ki] = loc_top[ki]; 05929 } 05930 05931 for (ki = 0; ki < pt->no_of_curves; ki++) 05932 sh6gettophlp (pt->pnext[ki], pretop, case_2d, jstat); 05933 05934 /* Data is set. */ 05935 05936 } 05937 05938 05939 goto out; 05940 05941 05942 err2: 05943 /* Error in input. pt is SISL_NULL. */ 05944 05945 *jstat = -2; 05946 s6err ("sh6gettophlp", *jstat, 0); 05947 goto out; 05948 05949 05950 out: 05951 return; 05952 } 05953 05954 //=========================================================================== 05955 void sh1779_at (SISLObject * po1, SISLObject * po2, SISLIntpt * pintpt, int *jstat) 05956 //=========================================================================== 05957 { 05958 int kstat = 0; /* Status variable. */ 05959 int kpar1, kpar2; /* Index of parameter value of object. */ 05960 int kn; /* Number of vertices of curve. */ 05961 int kk; /* Order of curve. */ 05962 int lleft[2]; /* Array storing pre-topology information. */ 05963 int lright[2]; /* Array storing pre-topology information. */ 05964 int *ll1, *ll2, *lr1, *lr2; /* Pointers into pre-topology arrays. */ 05965 double tref; /* Referance value in equality test. */ 05966 double *st; /* Knot vector of curve. */ 05967 double *sptpar = pintpt->epar;/* Pointer to parameter values of int.pt. */ 05968 SISLCurve *qc; /* Pointer to the curve. */ 05969 SISLSurf *qs; /* Pointer to the surface. */ 05970 double sf_low_lim[2]; 05971 double sf_high_lim[2]; 05972 /* ---------------------------------------------------------------------- */ 05973 /* Don't make pretop for help points ! */ 05974 if (sh6ishelp (pintpt)) 05975 { 05976 *jstat = 0; 05977 goto out; 05978 } 05979 05980 /* Set pointers into the arrays storing pre-topology information. */ 05981 if (po1->iobj == SISLCURVE) 05982 { 05983 qc = po1->c1; 05984 qs = po2->s1; 05985 kpar1 = 0; 05986 kpar2 = 1; 05987 ll1 = lleft; 05988 lr1 = lright; 05989 ll2 = lleft + 1; 05990 lr2 = lright + 1; 05991 } 05992 else 05993 { 05994 qc = po2->c1; 05995 qs = po1->s1; 05996 05997 kpar1 = 2; 05998 kpar2 = 0; 05999 ll1 = lleft + 1; 06000 lr1 = lright + 1; 06001 ll2 = lleft; 06002 lr2 = lright; 06003 } 06004 06005 kk = qc->ik; 06006 kn = qc->in; 06007 st = qc->et; 06008 tref = st[kn] - st[kk - 1]; 06009 06010 sf_low_lim[0] = qs->et1[qs->ik1 - 1] + REL_COMP_RES; 06011 sf_low_lim[1] = qs->et2[qs->ik2 - 1] + REL_COMP_RES; 06012 sf_high_lim[0] = qs->et1[qs->in1] - REL_COMP_RES; 06013 sf_high_lim[1] = qs->et2[qs->in2] - REL_COMP_RES; 06014 06015 sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat); 06016 if (kstat < 0) 06017 goto error; 06018 /* Check endpoint of curve. */ 06019 06020 if (DEQUAL (sptpar[kpar1] + tref, st[kk - 1] + tref)) 06021 *ll1 = SI_AT; 06022 if (DEQUAL (sptpar[kpar1] + tref, st[kn] + tref)) 06023 *lr1 = SI_AT; 06024 06025 /* Update pre-topology of intersection point. */ 06026 sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat); 06027 if (kstat < 0) 06028 goto error; 06029 06030 *jstat = 0; 06031 goto out; 06032 06033 /* Error lower level routine. */ 06034 error:*jstat = kstat; 06035 goto out; 06036 06037 out: 06038 return; 06039 } 06040 06041 //=========================================================================== 06042 void sh1780_at (SISLObject * po1, SISLObject * po2, SISLIntpt * pintpt, int *jstat) 06043 //=========================================================================== 06044 { 06045 int kstat = 0; /* Status variable. */ 06046 int kk1, kk2; /* Orders of the two curves. */ 06047 int kn1, kn2; /* Number of vertices in the curves. */ 06048 int lleft[2]; /* Array storing pre-topology information. */ 06049 int lright[2]; /* Array storing pre-topology information. */ 06050 double tref; /* Reference value in equality test. */ 06051 double *st1, *st2; /* Pointers to knot vectors of curves. */ 06052 double *sptpar = pintpt->epar;/* Parameter array of int.pt. */ 06053 /* --------------------------------------------------------------------- */ 06054 06055 /* Don't make pretop for help points ! */ 06056 if (sh6ishelp (pintpt)) 06057 { 06058 *jstat = 0; 06059 goto out; 06060 } 06061 06062 06063 /* Express the curve by local parameters. */ 06064 06065 kn1 = po1->c1->in; 06066 kk1 = po1->c1->ik; 06067 st1 = po1->c1->et; 06068 kn2 = po2->c1->in; 06069 kk2 = po2->c1->ik; 06070 st2 = po2->c1->et; 06071 tref = MAX (st1[kn1] - st1[kk1 - 1], st2[kn2] - st2[kk2 - 1]); 06072 06073 /* Update pre-topology of intersection point. */ 06074 sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat); 06075 06076 /* Change the pre-topology information if the intersection point 06077 lies at an endpoint of the curves. */ 06078 if (DEQUAL (sptpar[0] + tref, st1[kn1] + tref)) 06079 { 06080 lright[0] = SI_AT; 06081 } 06082 if (DEQUAL (sptpar[0] + tref, st1[kk1 - 1] + tref)) 06083 { 06084 lleft[0] = SI_AT; 06085 } 06086 if (DEQUAL (sptpar[1] + tref, st2[kn2] + tref)) 06087 { 06088 lright[1] = SI_AT; 06089 } 06090 if (DEQUAL (sptpar[1] + tref, st2[kk2 - 1] + tref)) 06091 { 06092 lleft[1] = SI_AT; 06093 } 06094 06095 /* Update pre-topology of intersection point. */ 06096 sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat); 06097 if (kstat < 0) 06098 goto error; 06099 06100 06101 *jstat = 0; 06102 goto out; 06103 06104 06105 /* Error lower level routine. */ 06106 error:*jstat = kstat; 06107 goto out; 06108 06109 out: 06110 return; 06111 } 06112 06113 06114 //=========================================================================== 06115 void sh1781_at (SISLObject * po1, SISLObject * po2, SISLIntpt * pintpt, int *jstat) 06116 //=========================================================================== 06117 { 06118 int kstat = 0; /* Status variable. */ 06119 int kn; /* Number of vertices of curve. */ 06120 int kk; /* Order of curve. */ 06121 int lleft[2]; /* Array storing pre-topology information. */ 06122 int lright[2]; /* Array storing pre-topology information. */ 06123 int *ll1, *ll2, *lr1, *lr2; /* Pointers into pre-topology arrays. */ 06124 double *st; /* Pointer to knot vector of curve. */ 06125 double *sptpar = pintpt->epar;/* Pointer to parameter array of int.pt. */ 06126 double tref; /* Referance value in equality test. */ 06127 SISLCurve *qc; /* Pointer to current curve. */ 06128 /* --------------------------------------------------------------------- */ 06129 06130 06131 /* Don't make pretop for help points ! */ 06132 if (sh6ishelp (pintpt)) 06133 { 06134 *jstat = 0; 06135 goto out; 06136 } 06137 06138 /* Set pointers into the arrays storing pre-topology information. */ 06139 06140 if (po1->iobj == SISLCURVE) 06141 { 06142 ll1 = lleft; 06143 lr1 = lright; 06144 ll2 = lleft + 1; 06145 lr2 = lright + 1; 06146 } 06147 else 06148 { 06149 ll1 = lleft + 1; 06150 lr1 = lright + 1; 06151 ll2 = lleft; 06152 lr2 = lright; 06153 } 06154 06155 /* Get pre-topology information. */ 06156 sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat); 06157 if (kstat < 0) 06158 goto error; 06159 06160 /* Test dimension of geometry space. */ 06161 if (po1->iobj == SISLCURVE) 06162 qc = po1->c1; 06163 else 06164 qc = po2->c1; 06165 06166 /* Store curve information in local parameters. */ 06167 kn = qc->in; 06168 kk = qc->ik; 06169 st = qc->et; 06170 tref = st[kn] - st[kk - 1]; 06171 06172 /* Test if the intersection point lies at an endpoint of 06173 the curve. */ 06174 06175 if (DEQUAL (sptpar[0] + tref, st[kn] + tref)) 06176 *lr1 = SI_AT; 06177 if (DEQUAL (sptpar[0] + tref, st[kk - 1] + tref)) 06178 *ll1 = SI_AT; 06179 06180 /* Update pretopology of intersection point. */ 06181 06182 sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat); 06183 if (kstat < 0) 06184 goto error; 06185 06186 *jstat = 0; 06187 goto out; 06188 06189 06190 /* Error lower level routine. */ 06191 error:*jstat = kstat; 06192 goto out; 06193 06194 out: 06195 return; 06196 } 06197 06198 06199 //=========================================================================== 06200 void sh_set_at (SISLObject * po1, SISLObject * po2, SISLIntdat * pintdat, int *jstat) 06201 //=========================================================================== 06202 { 06203 int kstat = 0; /* Status variable. */ 06204 int ki; /* Counter. */ 06205 int kdim; /* Dimension of geometry space. */ 06206 SISLIntpt *qpt = SISL_NULL; /* Pointer to intersection point. */ 06207 /* --------------------------------------------------------------------- */ 06208 06209 /* Init */ 06210 *jstat = 0; 06211 06212 /* Test if an intersection data structure exist. */ 06213 if (pintdat == SISL_NULL) 06214 goto out; 06215 06216 06217 /* Fetch dimension of geometry space. */ 06218 if (po1->iobj == SISLPOINT) 06219 06220 kdim = po1->p1->idim; 06221 else if (po1->iobj == SISLCURVE) 06222 kdim = po1->c1->idim; 06223 else 06224 kdim = po1->s1->idim; 06225 06226 /* Treat only cases: 06227 crv vs pt 1D 06228 crv vs crv 06229 crv vs sf 06230 (?sf vs pt 2D) 06231 */ 06232 06233 if (!(((po1->iobj == SISLCURVE && po2->iobj >= SISLCURVE) || 06234 (po2->iobj == SISLCURVE && po1->iobj >= SISLCURVE)) || 06235 (kdim == 1 && (po1->iobj + po2->iobj) == (SISLPOINT + SISLCURVE)) || 06236 (kdim == 2 && (po1->iobj + po2->iobj) == (SISLPOINT + SISLSURFACE)))) 06237 goto out; 06238 06239 06240 for (ki = 0; ki < (pintdat)->ipoint; ki++) 06241 { 06242 qpt = (pintdat)->vpoint[ki]; 06243 06244 /* Browse on the dimension of geometry space and the type of 06245 the input objects. */ 06246 06247 if (kdim == 1 && ((po1->iobj == SISLCURVE && po2->iobj == SISLPOINT) 06248 || (po2->iobj == SISLCURVE && po1->iobj == SISLPOINT))) 06249 { 06250 /* Compute pre-topology in one-dimensional curve-level value 06251 intersection. */ 06252 06253 sh1781_at (po1, po2,qpt, &kstat); 06254 if (kstat < 0) 06255 goto error; 06256 } 06257 else if (po1->iobj == SISLCURVE && po2->iobj == SISLCURVE) 06258 { 06259 /* curve-curve intersection. */ 06260 sh1780_at (po1, po2, qpt, &kstat); 06261 if (kstat < 0) 06262 goto error; 06263 } 06264 else if (kdim == 3 && 06265 ((po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE) || 06266 (po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE))) 06267 { 06268 /* Surface-curve intersection in 3-dimensional geometry space. */ 06269 06270 sh1779_at (po1, po2, qpt, &kstat); 06271 if (kstat < 0) 06272 goto error; 06273 } 06274 } 06275 06276 /* Task performed. */ 06277 06278 *jstat = 0; 06279 goto out; 06280 06281 /* Error in lower level routine. */ 06282 06283 error:*jstat = kstat; 06284 goto out; 06285 06286 out: 06287 return; 06288 } 06289 06290 06291 //=========================================================================== 06292 void sh6idlis (SISLObject * po1, SISLObject * po2, SISLIntdat ** pintdat, 06293 double aepsge, int *jstat) 06294 //=========================================================================== 06295 { 06296 int kstat; /* Local status variable. */ 06297 int kpos = 0; /* Position of error. */ 06298 int list_index = 0; /* Counter */ 06299 int knum = 0; /* Counter */ 06300 int indstart; /* Indexes used in lists */ 06301 int indlast; /* Indexes used in lists */ 06302 int ind1, ind2; 06303 int inddum; /* Indexes used in lists */ 06304 int no_main = 0; /* Counter */ 06305 int ki1, ki2, ki, kj; /* Counters */ 06306 int r1, r2, l1, l2; /* Pretopology info. */ 06307 int ktype = 0; /* To indicate type of list. */ 06308 int direction; /* Direction of curve */ 06309 double *geom, *norm1, *norm2; /* help pointers. */ 06310 SISLIntpt *prev, *pcurr; /* to traverse list of points. */ 06311 SISLIntpt *pnext, *pstart; /* to traverse list of points. */ 06312 SISLIntpt *plast, *pother; /* to traverse list of points. */ 06313 int pretop[4]; 06314 int case_2d = 0; /* Case flag, 2d Sf vs Pnt. */ 06315 int const_dir; /* Reduction of internal points 06316 along a constant parameter. */ 06317 int log_1, log_2; 06318 /* ------------------------------------------------------------- */ 06319 06320 /* If we do not have any intersection data we just return. */ 06321 06322 if ((*pintdat) == SISL_NULL) 06323 goto out; 06324 if ((po1->iobj == SISLSURFACE && po1->s1->idim == 2) || 06325 (po2->iobj == SISLSURFACE && po2->s1->idim == 2)) 06326 case_2d = TRUE; 06327 else 06328 case_2d = FALSE; 06329 06330 /* We first destroy existing intersection lists. */ 06331 06332 for (kj = 0; kj < (*pintdat)->ilist; kj++) 06333 freeIntlist ((*pintdat)->vlist[kj]); 06334 06335 /* Set SI_AT info in topology part */ 06336 sh_set_at (po1, po2, *pintdat, &kstat); 06337 if (kstat < 0) 06338 goto error; 06339 06340 06341 06342 /* Traverse all intersection points to get pretopology from help 06343 points */ 06344 06345 for (ki1 = 0; *pintdat && ki1 < (*pintdat)->ipoint; ki1++) 06346 { 06347 pcurr = (*pintdat)->vpoint[ki1]; 06348 if (sh6ismain (pcurr)) 06349 { 06350 sh6gettop (pcurr, 0, pretop, pretop + 1, pretop + 2, pretop + 3, &kstat); 06351 if (kstat < 0) 06352 goto error; 06353 06354 for (ki2 = 0; ki2 < pcurr->no_of_curves; ki2++) 06355 { 06356 sh6gettophlp (pcurr->pnext[ki2], pretop, case_2d, &kstat); 06357 if (kstat < 0) 06358 goto error; 06359 } 06360 06361 sh6settop (pcurr, 0, pretop[0], pretop[1], pretop[2], pretop[3], &kstat); 06362 if (kstat < 0) 06363 goto error; 06364 06365 } 06366 } 06367 06368 06369 /* Remove all internal points in a list when along a 06370 constant parameter direction */ 06371 /* Remove all singularpoints that has exactly two 06372 singular neighbours. */ 06373 06374 if ((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT 06375 && po1->s1->idim == 1) || 06376 (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT 06377 && po2->s1->idim == 1) || 06378 (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE 06379 && po1->s1->idim == 3)) 06380 const_dir = 2; 06381 else if ((po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE) || 06382 (po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE)) 06383 const_dir = 1; 06384 else 06385 const_dir = 0; 06386 06387 for (kj = 0; kj < (*pintdat)->ipoint; kj++) 06388 { 06389 06390 pcurr = (*pintdat)->vpoint[kj]; 06391 06392 sh6getnhbrs (pcurr, &pstart, &plast, &kstat); 06393 if (kstat < 0) 06394 goto error; 06395 06396 if (kstat == 0) 06397 { 06398 /* Two neighbours, check */ 06399 sh6getlist (pcurr, pstart, &indstart, &inddum, &kstat); 06400 if (kstat < 0) 06401 goto error; /* Error. */ 06402 if (kstat == 1) 06403 goto errinconsist; /* pcurr and pstart are not linked. */ 06404 06405 sh6getlist (pcurr, plast, &indlast, &inddum, &kstat); 06406 if (kstat < 0) 06407 goto error; /* Error. */ 06408 if (kstat == 1) 06409 goto errinconsist; /* pcurr and plast are not linked. */ 06410 06411 log_1 = pcurr->curve_dir[indstart]; 06412 log_1 = log_1>>1; 06413 log_1 &= 15; 06414 log_2 = pcurr->curve_dir[indlast]; 06415 log_2 = log_2>>1; 06416 log_2 &= 15; 06417 06418 06419 if (const_dir == 0 || 06420 (log_1 & log_2 ) || 06421 (pcurr->iinter == SI_SING && 06422 pstart->iinter == SI_SING && plast->iinter == SI_SING)) 06423 { 06424 sh6idkpt (pintdat, &pcurr, 1, &kstat); 06425 if (kstat < 0) 06426 goto error; 06427 /* Recursive nature : */ 06428 kj = -1; 06429 } 06430 06431 06432 } 06433 } 06434 06435 /* -------------------------------------------- */ 06436 if (const_dir > 1) 06437 { 06438 /* Split curves at points when change in curve_dir */ 06439 for (kj = 0; kj < (*pintdat)->ipoint; kj++) 06440 { 06441 06442 pcurr = (*pintdat)->vpoint[kj]; 06443 06444 sh6getnhbrs (pcurr, &pstart, &plast, &kstat); 06445 if (kstat < 0) 06446 goto error; 06447 06448 if (pcurr->iinter == SI_ORD && kstat == 0) 06449 { 06450 /* Two neighbours, check */ 06451 sh6getlist (pcurr, pstart, &indstart, &inddum, &kstat); 06452 if (kstat < 0) 06453 goto error; /* Error. */ 06454 if (kstat == 1) 06455 goto errinconsist; /* pcurr and pstart are not linked. */ 06456 06457 sh6getlist (pcurr, plast, &indlast, &inddum, &kstat); 06458 if (kstat < 0) 06459 goto error; /* Error. */ 06460 if (kstat == 1) 06461 goto errinconsist; /* pcurr and plast are not linked. */ 06462 06463 log_1 = pcurr->curve_dir[indstart]; 06464 log_1 = log_1>>1; 06465 log_1 &= 15; 06466 log_2 = pcurr->curve_dir[indlast]; 06467 log_2 = log_2>>1; 06468 log_2 &= 15; 06469 06470 /* If both curve_dir is set as constant, this must be a singular 06471 point, (remember internal points on same edge has been 06472 removed! )*/ 06473 if (log_1 && log_2 ) pcurr->iinter = SI_SING; 06474 } 06475 06476 06477 } 06478 } 06479 06480 /* -------------------------------------------- */ 06481 06482 if (const_dir > 1) 06483 { 06484 06485 /* Split curves at corner points. This is put in to avoid 06486 problems for the marching. */ 06487 06488 for (kj = 0; kj < (*pintdat)->ipoint; kj++) 06489 { 06490 06491 pcurr = (*pintdat)->vpoint[kj]; 06492 06493 pcurr->marker = FALSE; 06494 if (pcurr->iinter == SI_ORD && sh6nmbmain(pcurr,&kstat) == 2) 06495 06496 { 06497 sh6isinside(po1,po2,pcurr,&kstat); 06498 06499 /* UJK, February 1993, Sometimes an intersection point on an edge is not 06500 identified as singular. Therefore we split the curve at edges, 06501 if this is no natural ending (ie parallel pnt), 06502 int_join_per will join them. */ 06503 /* if (kstat == 3 || kstat == 4) */ 06504 06505 if (kstat < 0) goto error; 06506 06507 if (kstat > 1) 06508 { 06509 /* The point lies on a boarder. Mark it 06510 achieve a split. */ 06511 06512 /* UJK, aug 93, always mark singular in corners */ 06513 if (kstat == 3 || kstat == 4) pcurr->iinter = SI_SING; 06514 pcurr->marker = TRUE; 06515 } 06516 } 06517 } 06518 } 06519 06520 06521 if (const_dir > 1) 06522 { 06523 /* All previous trim points in a corner, must split it's neighbour if 06524 this lies on a corner */ 06525 for (kj = 0; kj < (*pintdat)->ipoint; kj++) 06526 { 06527 06528 pcurr = (*pintdat)->vpoint[kj]; 06529 06530 if (pcurr->iinter == SI_TRIM && 06531 sh6nmbmain (pcurr, &kstat) == 1) 06532 { 06533 sh6isinside (po1, po2, pcurr, &kstat); 06534 if (kstat == 3 || kstat == 4) 06535 { 06536 sh6getnhbrs (pcurr, &pstart, &plast, &kstat); 06537 if (kstat < 0) 06538 goto error; 06539 if (pstart->iinter == SI_TRIM) 06540 { 06541 sh6isinside (po1, po2, pstart, &kstat); 06542 if (kstat == 3 || kstat == 4) 06543 { 06544 06545 pstart->iinter = SI_SING; 06546 06547 /* Recursive nature : */ 06548 kj = -1; 06549 } 06550 } 06551 } 06552 } 06553 } 06554 } 06555 06556 /* April 92, we need one instanse of each end point. This 06557 because of the storing of geometric data in the points 06558 that is in some cases contex dependent (mirroring 06559 in singular situation or translation of parameter space 06560 values in periodicity treatment). 06561 We identify junction points and make a copy 06562 for each branch. */ 06563 for (ki1 = 0; *pintdat && ki1 < (*pintdat)->ipoint; ki1++) 06564 { 06565 pcurr = (*pintdat)->vpoint[ki1]; 06566 if (sh6ismain (pcurr)) 06567 { 06568 /* Get number of neighbours */ 06569 no_main = sh6nmbmain (pcurr, &kstat); 06570 if (kstat < 0) 06571 goto error; 06572 06573 if (pcurr->marker || 06574 (no_main == 2 && pcurr->iinter == SI_SING) || 06575 no_main > 2) 06576 { 06577 if (pcurr->iinter == SI_ORD && no_main > 2) 06578 pcurr->iinter = SI_SING; 06579 sh6idsplit(pintdat, pcurr, &kstat); 06580 if (kstat < 0) goto error; 06581 } 06582 } 06583 } 06584 /* End of split */ 06585 06586 /* Traverse all intersection points, mark all main points */ 06587 for (ki1 = 0; *pintdat && ki1 < (*pintdat)->ipoint; ki1++) 06588 if (sh6ismain ((*pintdat)->vpoint[ki1])) 06589 { 06590 /* Get number of neighbours */ 06591 (*pintdat)->vpoint[ki1]->marker = 06592 sh6nmbmain ((*pintdat)->vpoint[ki1], &kstat); 06593 if (kstat < 0) 06594 goto error; 06595 } 06596 else 06597 (*pintdat)->vpoint[ki1]->marker = 0; 06598 06599 06600 /* Traverse all intersection points to look for 06601 start points to lists. If a point has only one neighbour, 06602 or is SI_SING or has more than two neighbours, 06603 it is a start or end point. */ 06604 06605 for (ki1 = 0; *pintdat && ki1 < (*pintdat)->ipoint; ki1++) 06606 if ((*pintdat)->vpoint[ki1]->marker > 0) 06607 { 06608 /* Get number of neighbours */ 06609 no_main = sh6nmbmain ((*pintdat)->vpoint[ki1], &kstat); 06610 if (kstat < 0) 06611 goto error; 06612 06613 if (no_main == 1 || 06614 (no_main == 2 && (*pintdat)->vpoint[ki1]->iinter == SI_SING) || 06615 no_main > 2) 06616 { 06617 pstart = (*pintdat)->vpoint[ki1]; 06618 06619 for (ki2 = 0; ki2 < pstart->no_of_curves; ki2++) 06620 if (sh6ismain (pstart->pnext[ki2]) && 06621 pstart->pnext[ki2]->marker) 06622 { 06623 pcurr = pstart->pnext[ki2]; 06624 prev = pstart; 06625 knum = 1; 06626 06627 /* Get first index */ 06628 sh6getlist (pstart, pcurr, &indstart, &inddum, &kstat); 06629 06630 while (pcurr) 06631 { 06632 /* Remember index */ 06633 sh6getlist (prev, pcurr, &inddum, &indlast, &kstat); 06634 06635 prev->marker--; 06636 pcurr->marker--; 06637 sh6getother (pcurr, prev, &pnext, &kstat); 06638 if (kstat < 0) 06639 goto error; 06640 06641 prev = pcurr; 06642 pcurr = pnext; 06643 knum++; 06644 } 06645 06646 /* Create list */ 06647 /* To be sure that list array is big enough. */ 06648 06649 if (list_index == (*pintdat)->ilmax) 06650 { 06651 (*pintdat)->ilmax += 20; 06652 06653 if (((*pintdat)->vlist = 06654 increasearray ((*pintdat)->vlist, (*pintdat)->ilmax, 06655 SISLIntlist *)) == SISL_NULL) 06656 goto err101; 06657 } 06658 06659 /* Type setting may be done in s1880? */ 06660 ktype = 0; 06661 06662 /* Making a new list structure. */ 06663 if (((*pintdat)->vlist[list_index] = 06664 newIntlist (pstart, prev, ktype)) == SISL_NULL) 06665 goto err101; 06666 (*pintdat)->vlist[list_index]->inumb = knum; 06667 (*pintdat)->vlist[list_index]->ind_first = indstart; 06668 (*pintdat)->vlist[list_index]->ind_last = indlast; 06669 list_index++; 06670 06671 06672 06673 } 06674 } 06675 } 06676 06677 /* Only closed list left */ 06678 for (ki1 = 0; *pintdat && ki1 < (*pintdat)->ipoint; ki1++) 06679 if ((*pintdat)->vpoint[ki1]->marker > 0) 06680 { 06681 /* Get number of neighbours */ 06682 no_main = sh6nmbmain ((*pintdat)->vpoint[ki1], &kstat); 06683 if (kstat < 0) 06684 goto error; 06685 06686 06687 if (no_main == 2) 06688 { 06689 pstart = prev = (*pintdat)->vpoint[ki1]; 06690 06691 sh6getnhbrs (prev, &pcurr, &pnext, &kstat); 06692 if (kstat < 0 || pcurr == SISL_NULL) 06693 goto error; 06694 knum = 1; 06695 06696 /* Get first index */ 06697 sh6getlist (prev, pcurr, &indstart, &inddum, &kstat); 06698 06699 /* Get last index */ 06700 sh6getlist (prev, pnext, &indlast, &inddum, &kstat); 06701 06702 06703 06704 while (pcurr && pcurr != pstart) 06705 { 06706 prev->marker = 0; 06707 06708 sh6getother (pcurr, prev, &pnext, &kstat); 06709 if (kstat < 0) 06710 goto error; 06711 06712 prev = pcurr; 06713 pcurr = pnext; 06714 knum++; 06715 } 06716 prev->marker = 0; 06717 if (pcurr == pstart) 06718 { 06719 /* It really is a closed curve */ 06720 knum++; 06721 prev = pstart; 06722 } 06723 else 06724 goto errinconsist; 06725 06726 /* Create list */ 06727 /* To be sure that list array is big enough. */ 06728 06729 if (list_index == (*pintdat)->ilmax) 06730 { 06731 (*pintdat)->ilmax += 20; 06732 06733 if (((*pintdat)->vlist = 06734 increasearray ((*pintdat)->vlist, (*pintdat)->ilmax, 06735 SISLIntlist *)) == SISL_NULL) 06736 goto err101; 06737 } 06738 06739 /* Type setting may be done in s1880? */ 06740 ktype = 0; 06741 06742 /* Making a new list structure. */ 06743 if (((*pintdat)->vlist[list_index] = 06744 newIntlist (pstart, prev, ktype)) == SISL_NULL) 06745 goto err101; 06746 (*pintdat)->vlist[list_index]->inumb = knum; 06747 (*pintdat)->vlist[list_index]->ind_first = indstart; 06748 (*pintdat)->vlist[list_index]->ind_last = indlast; 06749 list_index++; 06750 06751 06752 } 06753 } 06754 06755 06756 (*pintdat)->ilist = list_index; 06757 06758 06759 /* If direction of a list is wrong, turn it. */ 06760 06761 for (kj = 0; kj < (*pintdat)->ilist; kj++) 06762 { 06763 knum = (*pintdat)->vlist[kj]->inumb; 06764 indstart = (*pintdat)->vlist[kj]->ind_first; 06765 06766 pcurr = (*pintdat)->vlist[kj]->pfirst; 06767 plast = (*pintdat)->vlist[kj]->plast; 06768 pnext = (*pintdat)->vlist[kj]->pfirst->pnext[indstart]; 06769 direction = (*pintdat)->vlist[kj]->pfirst->curve_dir[indstart]; 06770 06771 (*pintdat)->vlist[kj]->pretop[0] = SI_UNDEF; 06772 (*pintdat)->vlist[kj]->pretop[1] = SI_UNDEF; 06773 (*pintdat)->vlist[kj]->pretop[2] = SI_UNDEF; 06774 (*pintdat)->vlist[kj]->pretop[3] = SI_UNDEF; 06775 06776 06777 while (pnext != plast) 06778 { 06779 if (direction) 06780 break; 06781 06782 sh6getother (pnext, pcurr, &pother, &kstat); 06783 if (kstat < 0) 06784 goto error; 06785 sh6getlist (pnext, pother, &ind1, &ind2, &kstat); 06786 if (kstat < 0) 06787 goto error; 06788 direction = pnext->curve_dir[ind1]; 06789 pcurr = pnext; 06790 pnext = pother; 06791 } 06792 06793 if (direction < 0) 06794 { 06795 pcurr = (*pintdat)->vlist[kj]->pfirst; 06796 (*pintdat)->vlist[kj]->pfirst = (*pintdat)->vlist[kj]->plast; 06797 (*pintdat)->vlist[kj]->plast = pcurr; 06798 06799 inddum = (*pintdat)->vlist[kj]->ind_first; 06800 (*pintdat)->vlist[kj]->ind_first = (*pintdat)->vlist[kj]->ind_last; 06801 (*pintdat)->vlist[kj]->ind_last = inddum; 06802 indstart = (*pintdat)->vlist[kj]->ind_first; 06803 } 06804 06805 /* Set pretopology information. */ 06806 /* Traverse the list */ 06807 06808 if ((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT 06809 && po1->s1->idim == 1) || 06810 (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT 06811 && po2->s1->idim == 1) || 06812 (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE 06813 && po1->s1->idim == 3)) 06814 { 06815 pstart = prev = (*pintdat)->vlist[kj]->pfirst; 06816 plast = (*pintdat)->vlist[kj]->plast; 06817 06818 if ((pstart->edge_1 && plast->edge_1) || 06819 (pstart->edge_2 && plast->edge_2)) 06820 { 06821 l1 = SI_IN; 06822 r1 = SI_OUT; 06823 l2 = SI_OUT; 06824 r2 = SI_IN; 06825 06826 if (plast->edge_1 == SI_RIGHT) 06827 r1 = SI_AT; 06828 else if (plast->edge_1 == SI_LEFT) 06829 l1 = SI_AT; 06830 06831 if (plast->edge_2 == SI_RIGHT) 06832 r2 = SI_AT; 06833 else if (plast->edge_2 == SI_LEFT) 06834 l2 = SI_AT; 06835 06836 (*pintdat)->vlist[kj]->pretop[0] = l1; 06837 (*pintdat)->vlist[kj]->pretop[1] = r1; 06838 (*pintdat)->vlist[kj]->pretop[2] = l2; 06839 (*pintdat)->vlist[kj]->pretop[3] = r2; 06840 06841 } 06842 06843 else 06844 { 06845 06846 r1 = r2 = l1 = l2 = 0; 06847 pcurr = sh6getnext (prev, indstart); 06848 06849 /* UJK,Does not work 06850 while (pcurr != plast) */ 06851 while (0) 06852 { 06853 if (sh6nmbhelp (pcurr, &kstat)) 06854 { 06855 if (pcurr->left_obj_1[0] == pcurr->right_obj_1[0] && 06856 pcurr->left_obj_1[0] != 0 && r1 == 0) 06857 { 06858 l1 = r1 = pcurr->left_obj_1[0]; 06859 if (po1->iobj == 2 && po2->iobj == 2 && po1->s1->idim == 3) 06860 { 06861 sh6getgeom (po1, 1, pcurr, &geom, &norm1, aepsge, &kstat); 06862 if (kstat < 0) 06863 goto error; 06864 sh6getgeom (po2, 2, pcurr, &geom, &norm2, aepsge, &kstat); 06865 if (kstat < 0) 06866 goto error; 06867 06868 if (s6scpr (norm1, norm2, 3) < 0.0) 06869 l2 = r2 = l1; 06870 else 06871 l2 = r2 = (l1 == SI_IN ? SI_OUT : SI_IN); 06872 } 06873 else 06874 l2 = r2 = (l1 == SI_IN ? SI_OUT : SI_IN); 06875 06876 break; 06877 } 06878 06879 if (pcurr->left_obj_2[0] == pcurr->right_obj_2[0] && 06880 pcurr->left_obj_2[0] != 0 && r2 == 0) 06881 { 06882 l2 = r2 = pcurr->left_obj_2[0]; 06883 if (po1->iobj == 2 && po2->iobj == 2 && po1->s1->idim == 3) 06884 { 06885 sh6getgeom (po1, 1, pcurr, &geom, &norm1, aepsge, &kstat); 06886 if (kstat < 0) 06887 goto error; 06888 sh6getgeom (po2, 2, pcurr, &geom, &norm2, aepsge, &kstat); 06889 if (kstat < 0) 06890 goto error; 06891 06892 if (s6scpr (norm1, norm2, 3) < 0.0) 06893 l1 = r1 = l2; 06894 else 06895 l1 = r1 = (l2 == SI_IN ? SI_OUT : SI_IN); 06896 } 06897 else 06898 l1 = r1 = (l2 == SI_IN ? SI_OUT : SI_IN); 06899 06900 break; 06901 } 06902 } 06903 else if (kstat < 0) 06904 goto error; 06905 06906 06907 sh6getother (pcurr, prev, &pnext, &kstat); 06908 if (kstat < 0) 06909 goto error; 06910 06911 prev = pcurr; 06912 pcurr = pnext; 06913 } 06914 if (r1 == 0) 06915 { 06916 l1 = SI_IN; 06917 r1 = SI_OUT; 06918 l2 = SI_OUT; 06919 r2 = SI_IN; 06920 } 06921 06922 06923 (*pintdat)->vlist[kj]->pretop[0] = l1; 06924 (*pintdat)->vlist[kj]->pretop[1] = r1; 06925 (*pintdat)->vlist[kj]->pretop[2] = l2; 06926 (*pintdat)->vlist[kj]->pretop[3] = r2; 06927 06928 prev = pstart; 06929 pcurr = sh6getnext (prev, indstart); 06930 sh6getlist (prev, pcurr, &ind1, &ind2, &kstat); 06931 if (kstat < 0) 06932 goto error; 06933 06934 for (ki = 0; ki < knum; ki++) 06935 { 06936 sh6settop (prev, ind1, l1, r1, l2, r2, &kstat); 06937 if (!pcurr) 06938 break; 06939 sh6settop (pcurr, ind2, l1, r1, l2, r2, &kstat); 06940 sh6getother (pcurr, prev, &pnext, &kstat); 06941 if (kstat < 0) 06942 goto error; 06943 prev = pcurr; 06944 pcurr = pnext; 06945 sh6getlist (prev, pcurr, &ind1, &ind2, &kstat); 06946 if (kstat < 0) 06947 goto error; 06948 } 06949 } 06950 } 06951 06952 else if ((po1->iobj == SISLCURVE && po2->iobj == SISLPOINT) || 06953 (po2->iobj == SISLCURVE && po1->iobj == SISLPOINT)) 06954 06955 { 06956 /* Curve point cases */ 06957 06958 (*pintdat)->vlist[kj]->pretop[0] = 06959 (*pintdat)->vlist[kj]->pfirst->left_obj_1[0]; 06960 (*pintdat)->vlist[kj]->pretop[1] = 06961 (*pintdat)->vlist[kj]->plast->right_obj_1[0]; 06962 (*pintdat)->vlist[kj]->pretop[2] = 06963 (*pintdat)->vlist[kj]->pfirst->left_obj_2[0]; 06964 (*pintdat)->vlist[kj]->pretop[3] = 06965 (*pintdat)->vlist[kj]->plast->right_obj_2[0]; 06966 } 06967 06968 else if (po1->iobj == SISLCURVE && po2->iobj == SISLCURVE) 06969 { 06970 06971 /* Curve curve cases */ 06972 if ((*pintdat)->vlist[kj]->pfirst->epar[0] <= 06973 (*pintdat)->vlist[kj]->plast->epar[0]) 06974 { 06975 (*pintdat)->vlist[kj]->pretop[0] = 06976 (*pintdat)->vlist[kj]->pfirst->left_obj_1[0]; 06977 (*pintdat)->vlist[kj]->pretop[1] = 06978 (*pintdat)->vlist[kj]->plast->right_obj_1[0]; 06979 } 06980 else 06981 { 06982 (*pintdat)->vlist[kj]->pretop[0] = 06983 (*pintdat)->vlist[kj]->plast->left_obj_1[0]; 06984 (*pintdat)->vlist[kj]->pretop[1] = 06985 (*pintdat)->vlist[kj]->pfirst->right_obj_1[0]; 06986 } 06987 06988 if ((*pintdat)->vlist[kj]->pfirst->epar[1] <= 06989 (*pintdat)->vlist[kj]->plast->epar[1]) 06990 { 06991 (*pintdat)->vlist[kj]->pretop[2] = 06992 (*pintdat)->vlist[kj]->pfirst->left_obj_2[0]; 06993 (*pintdat)->vlist[kj]->pretop[3] = 06994 (*pintdat)->vlist[kj]->plast->right_obj_2[0]; 06995 } 06996 else 06997 { 06998 (*pintdat)->vlist[kj]->pretop[2] = 06999 (*pintdat)->vlist[kj]->plast->left_obj_2[0]; 07000 (*pintdat)->vlist[kj]->pretop[3] = 07001 (*pintdat)->vlist[kj]->pfirst->right_obj_2[0]; 07002 } 07003 } 07004 07005 else if ((po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE 07006 && po1->s1->idim == 3)) 07007 { 07008 07009 /* Suface curve case */ 07010 07011 (*pintdat)->vlist[kj]->pretop[0] = 07012 (*pintdat)->vlist[kj]->pfirst->left_obj_1[0]; 07013 (*pintdat)->vlist[kj]->pretop[1] = 07014 (*pintdat)->vlist[kj]->plast->right_obj_1[0]; 07015 07016 if ((*pintdat)->vlist[kj]->pfirst->epar[2] <= 07017 (*pintdat)->vlist[kj]->plast->epar[2]) 07018 { 07019 (*pintdat)->vlist[kj]->pretop[2] = 07020 (*pintdat)->vlist[kj]->pfirst->left_obj_2[0]; 07021 (*pintdat)->vlist[kj]->pretop[3] = 07022 (*pintdat)->vlist[kj]->plast->right_obj_2[0]; 07023 } 07024 else 07025 { 07026 (*pintdat)->vlist[kj]->pretop[2] = 07027 (*pintdat)->vlist[kj]->plast->left_obj_2[0]; 07028 (*pintdat)->vlist[kj]->pretop[3] = 07029 (*pintdat)->vlist[kj]->pfirst->right_obj_2[0]; 07030 } 07031 07032 } 07033 07034 else if ((po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE 07035 && po1->c1->idim == 3)) 07036 { 07037 07038 /* Curve suface case */ 07039 07040 if ((*pintdat)->vlist[kj]->pfirst->epar[0] <= 07041 (*pintdat)->vlist[kj]->plast->epar[0]) 07042 { 07043 (*pintdat)->vlist[kj]->pretop[0] = 07044 (*pintdat)->vlist[kj]->pfirst->left_obj_1[0]; 07045 (*pintdat)->vlist[kj]->pretop[1] = 07046 (*pintdat)->vlist[kj]->plast->right_obj_1[0]; 07047 } 07048 else 07049 { 07050 (*pintdat)->vlist[kj]->pretop[0] = 07051 (*pintdat)->vlist[kj]->plast->left_obj_1[0]; 07052 (*pintdat)->vlist[kj]->pretop[1] = 07053 (*pintdat)->vlist[kj]->pfirst->right_obj_1[0]; 07054 } 07055 07056 (*pintdat)->vlist[kj]->pretop[2] = 07057 (*pintdat)->vlist[kj]->pfirst->left_obj_2[0]; 07058 (*pintdat)->vlist[kj]->pretop[3] = 07059 (*pintdat)->vlist[kj]->plast->right_obj_2[0]; 07060 07061 } 07062 } 07063 07064 07065 07066 07067 *jstat = 0; 07068 goto out; 07069 07070 /* ------------------------------------------------------ */ 07071 errinconsist: 07072 *jstat = -500; 07073 s6err ("sh6idlis", *jstat, kpos); 07074 goto out; 07075 07076 err101: 07077 *jstat = -101; 07078 s6err ("sh6idlis", *jstat, kpos); 07079 goto out; 07080 07081 error: 07082 *jstat = kstat; 07083 s6err ("sh6idlis", *jstat, kpos); 07084 goto out; 07085 07086 out: 07087 ; 07088 } 07089 07090 07091 //=========================================================================== 07092 void sh6idunite (SISLIntdat ** intdat, SISLIntpt ** pt1, SISLIntpt ** pt2, 07093 double weight, int *jstat) 07094 //=========================================================================== 07095 { 07096 int ki, kstat; 07097 SISLIntpt *lpt; 07098 SISLIntpt *lpt1; 07099 SISLIntpt *lpt2; 07100 07101 sh6idnpt (intdat, pt1, 0, &kstat); 07102 if (kstat < 0) 07103 goto error; 07104 sh6idnpt (intdat, pt2, 0, &kstat); 07105 if (kstat < 0) 07106 goto error; 07107 07108 if (sh6ismain (*pt1)) 07109 { 07110 lpt1 = (*pt1); 07111 lpt2 = (*pt2); 07112 } 07113 else 07114 { 07115 lpt1 = (*pt2); 07116 lpt2 = (*pt1); 07117 weight = 1.0 - weight; 07118 } 07119 07120 sh6disconnect (lpt1, lpt2, &kstat); 07121 if (kstat < 0) 07122 goto error; 07123 07124 /* UJK, Oct. 91 */ 07125 /* for (ki=0;;ki++) */ 07126 for (ki = 0;;) 07127 { 07128 if ((lpt = sh6getnext (lpt2, ki)) == SISL_NULL) 07129 break; 07130 07131 sh6disconnect (lpt2, lpt, &kstat); 07132 if (kstat < 0) 07133 goto error; 07134 07135 07136 sh6connect (lpt1, lpt, &kstat); 07137 if (kstat < 0) 07138 goto error; 07139 } 07140 07141 for (ki = 0; ki < lpt1->ipar; ki++) 07142 lpt1->epar[ki] = lpt1->epar[ki] * (1.0 - weight) + lpt2->epar[ki] * weight; 07143 07144 sh6idkpt (intdat, &lpt2, 0, &kstat); 07145 if (kstat < 0) 07146 goto error; 07147 07148 (*pt1) = lpt1; 07149 (*pt2) = lpt2; 07150 07151 goto out; 07152 07153 error: 07154 *jstat = kstat; 07155 s6err ("sh6idunite", kstat, 0); 07156 goto out; 07157 out: 07158 ; 07159 } 07160 07161 07162 07163 //=========================================================================== 07164 void sh6edgred (SISLObject * po1, SISLObject * po2, 07165 SISLIntdat * pintdat, int *jstat) 07166 //=========================================================================== 07167 { 07168 int kstat, gstat, i, ki; 07169 int change = FALSE; 07170 int change_2 = FALSE; 07171 int num = 0; 07172 SISLIntpt *pt1 = SISL_NULL; 07173 SISLIntpt *pt2 = SISL_NULL; 07174 SISLIntpt *pcurr = SISL_NULL; 07175 07176 if (pintdat != SISL_NULL) 07177 { 07178 do 07179 { 07180 change_2 = FALSE; 07181 /* If trim point is internal and one neighbours, change to help 07182 point, if two neighbours unite till one of them */ 07183 do 07184 { 07185 change = FALSE; 07186 for (i = 0; i < pintdat->ipoint; i++) 07187 { 07188 pcurr = pintdat->vpoint[i]; 07189 if (pcurr->iinter == SI_TRIM) 07190 { 07191 sh6isinside (po1, po2, pcurr, &kstat); 07192 if (kstat < 0) 07193 goto error; 07194 if (kstat == 1) 07195 { 07196 num = sh6nmbmain (pcurr, &kstat); 07197 if (kstat < 0) 07198 goto error; 07199 if (num == 1) 07200 { 07201 sh6tohelp (pcurr, &kstat); 07202 change = TRUE; 07203 } 07204 else if (num == 2) 07205 { 07206 sh6getnhbrs (pcurr, &pt1, &pt2, &gstat); 07207 if (kstat < 0) 07208 goto error; 07209 if (pt1->iinter == SI_TRIM && 07210 pt2->iinter == SI_TRIM) 07211 { 07212 sh6idunite (&pintdat, &pt1, &pcurr, 07213 DZERO, &kstat); 07214 if (kstat < 0) 07215 goto error; 07216 change = TRUE; 07217 } 07218 } 07219 } 07220 } 07221 } 07222 } while (change); 07223 07224 07225 /* For a trim point on the edge with only one trim 07226 neighbour on an edge, unit till the other edge 07227 neighbour and change status of neighbour*/ 07228 do 07229 { 07230 change = FALSE; 07231 for (i = 0; i < pintdat->ipoint; i++) 07232 { 07233 pt1 = pt2 = SISL_NULL; 07234 pcurr = pintdat->vpoint[i]; 07235 if (pcurr->iinter == SI_TRIM) 07236 { 07237 sh6isinside (po1, po2, pcurr, &kstat); 07238 if (kstat < 0) 07239 goto error; 07240 if (kstat == 2) 07241 { 07242 for (ki = 0; ki < pcurr->no_of_curves; ki++) 07243 { 07244 pt1 = pcurr->pnext[ki]; 07245 if (pt1->iinter == SI_TRIM) 07246 { 07247 sh6comedg (po1, po2, pcurr, pt1, &kstat); 07248 if (kstat < 0) 07249 goto error; 07250 if (kstat) 07251 { 07252 if (pt2) 07253 { 07254 pt2 = SISL_NULL; 07255 break; 07256 } 07257 else 07258 pt2 = pt1; 07259 } 07260 } 07261 } 07262 if (pt2) 07263 { 07264 /* sh6idunite (&pintdat, &pt2, &pcurr, 07265 DZERO, &kstat); */ 07266 /* UJK, 12.08.93 */ 07267 /* sh6idkpt (&pintdat, &pcurr, 1, &kstat); 07268 sh6disconnect(pcurr,pt2,&kstat); */ 07269 pcurr->iinter = SI_SING; 07270 07271 /*------------------- */ 07272 /* If no trim neighbours on common 07273 edge, remove trim status. */ 07274 pcurr = pt2; 07275 kstat = 0; 07276 07277 for (ki = 0; ki < pcurr->no_of_curves; ki++) 07278 { 07279 pt1 = pcurr->pnext[ki]; 07280 if (pt1->iinter == SI_TRIM) 07281 { 07282 sh6comedg (po1, po2, pcurr, pt1, &kstat); 07283 if (kstat < 0) 07284 goto error; 07285 if (kstat) 07286 break; 07287 07288 } 07289 07290 } 07291 /* -------------------- */ 07292 if (!kstat) 07293 pcurr->iinter = SI_SING; 07294 change = TRUE; 07295 change_2 = TRUE; 07296 } 07297 07298 } 07299 07300 } 07301 } 07302 } while (change); 07303 } while (change_2); 07304 07305 07306 /* Reduce internal stuff */ 07307 sh6red (po1, po2, pintdat, &kstat); 07308 if (kstat < 0) 07309 goto error; 07310 07311 07312 /* General edge treatment */ 07313 07314 /* UJK, aug 93, spesial branch for crv/crv */ 07315 if (po1->iobj == SISLCURVE && 07316 po2->iobj == SISLCURVE ) 07317 { 07318 do 07319 { 07320 change = 0; 07321 for (i = 0; i < pintdat->ipoint; i++) 07322 { 07323 if (sh6ismain (pintdat->vpoint[i])) 07324 { 07325 sh6getnhbrs (pintdat->vpoint[i], &pt1, &pt2, &gstat); 07326 if (gstat == 1) 07327 { 07328 double parval; 07329 SISLCurve *pcu=SISL_NULL; 07330 if (pintdat->vpoint[i]->epar[0] == pt1->epar[0]) 07331 { 07332 parval = pintdat->vpoint[i]->epar[1]; 07333 pcu = po2->c1; 07334 } 07335 else if (pintdat->vpoint[i]->epar[1] == pt1->epar[1]) 07336 { 07337 parval = pintdat->vpoint[i]->epar[0]; 07338 pcu = po1->c1; 07339 } 07340 07341 if (pcu && 07342 parval > pcu->et[pcu->ik-1] && 07343 parval < pcu->et[pcu->in] ) 07344 07345 07346 { 07347 sh6tohelp (pintdat->vpoint[i], &kstat); 07348 if (kstat < 0) 07349 goto error; 07350 change = 1; 07351 } 07352 } 07353 } 07354 } 07355 } while (change); 07356 } 07357 else 07358 { 07359 do 07360 { 07361 change = 0; 07362 for (i = 0; i < pintdat->ipoint; i++) 07363 { 07364 if (sh6ismain (pintdat->vpoint[i])) 07365 { 07366 sh6isinside (po1, po2, pintdat->vpoint[i], &kstat); 07367 if (kstat < 0) 07368 goto error; 07369 07370 /* ALA and VSK. Test if the point lies on edge in 07371 one or two objects. */ 07372 if (kstat == 2 || kstat == 5) 07373 { 07374 sh6getnhbrs (pintdat->vpoint[i], &pt1, &pt2, &gstat); 07375 if (gstat == 1) 07376 { 07377 sh6comedg (po1, po2, pintdat->vpoint[i], pt1, &gstat); 07378 07379 /* ALA and VSK. Test if the points lie on the same 07380 edge in both objects if it lies on an edge in 07381 both objects. */ 07382 if ((kstat == 2 && gstat > 0) || 07383 (kstat == 5 && gstat == 3)) 07384 { 07385 sh6tohelp (pintdat->vpoint[i], &kstat); 07386 if (kstat < 0) 07387 goto error; 07388 change = 1; 07389 } 07390 } 07391 } 07392 } 07393 } 07394 } while (change); 07395 } 07396 } 07397 07398 07399 07400 *jstat = 0; 07401 goto out; 07402 07403 /* Error lower level routine. */ 07404 07405 error:(*jstat) = kstat; 07406 s6err ("sh6edgred", *jstat, 0); 07407 goto out; 07408 07409 out: 07410 return; 07411 } 07412 07413 //=========================================================================== 07414 void s9conmarch(SISLSurf *ps,double alevel,double epar[],int ndir[],int ipoint, 07415 double *gpar[],int *mpar[],int *jpoint,int *jstat) 07416 //=========================================================================== 07417 { 07418 int kstat; /* Status variable */ 07419 int kpos=0; /* Position of error */ 07420 int *lpar = SISL_NULL; /* Pointer to output integer array */ 07421 int ki,kj; 07422 int kn1,kn2,kk1,kk2; /* Surface attributes. */ 07423 double tstart1,tstart2,tend1,tend2; /* Surface attributes. */ 07424 int ksucc; /* Success indicator */ 07425 double tepsge=1.0; /* Not used */ 07426 double *spar=SISL_NULL; /* Pointer to output real array */ 07427 double scand1[2]; /* Result of iteration process */ 07428 double scand2[2]; /* Result of iteration process */ 07429 double *sp,*sq; /* Pointer used in loop */ 07430 double tdum1; /* Max knot value used in DEQUAL comparing. */ 07431 double tdum2; /* Max knot value used in DEQUAL comparing. */ 07432 07433 /* Init */ 07434 kn1 = ps->in1; 07435 kn2 = ps->in2; 07436 kk1 = ps->ik1; 07437 kk2 = ps->ik2; 07438 07439 tstart1 = ps->et1[kk1-1]; 07440 tend1 = ps->et1[kn1]; 07441 tstart2 = ps->et2[kk2-1]; 07442 tend2 = ps->et2[kn2]; 07443 07444 tdum1 = (double)2.0*max(fabs(tstart1),fabs(tend1)); 07445 tdum2 = (double)2.0*max(fabs(tstart2),fabs(tend2)); 07446 07447 /* Allocate output arrays */ 07448 07449 if ((*mpar=newarray(3*ipoint,INT )) == SISL_NULL) goto err101; 07450 if ((*gpar=newarray(6*ipoint,DOUBLE)) == SISL_NULL) goto err101; 07451 07452 lpar = *mpar; 07453 spar = *gpar; 07454 07455 memcopy(spar,epar,2*ipoint,DOUBLE); 07456 *jpoint = ipoint; 07457 07458 /* Initiate output integer array to point to no points */ 07459 07460 for (ki=0 ; ki< 3*ipoint ; ki++) *(lpar+ki) = 0; 07461 07462 07463 /* Loop for all input points. */ 07464 for (ki=0, sp=spar ; ki< ipoint-1 ; ki++, sp+=2) 07465 { 07466 /* Start marching from point ki */ 07467 07468 /* Exclude points already connected and parallell points. */ 07469 if (lpar[ki] != 0 || ndir[ki] == 0) continue; 07470 07471 /* SISLPoint not marched to */ 07472 07473 s1787(ps,alevel,tepsge,sp,scand1,scand2,&kstat); 07474 if (kstat<0) goto error; 07475 if (kstat==0) goto war00; 07476 07477 /* Run through remaining points to find if scand2 matches any 07478 of them. If we've got only two points, we connect them.*/ 07479 07480 ksucc = 0; 07481 07482 for (kj=ki+1,sq=spar+2*ki+2 ; kj<ipoint ; kj++,sq+=2) 07483 { 07484 07485 /* SISLPoint found */ 07486 07487 if (DEQUAL(sq[0]+tdum1,scand2[0]+tdum1) && 07488 DEQUAL(sq[1]+tdum2,scand2[1]+tdum2)) 07489 { 07490 /* Accepted end point found */ 07491 07492 lpar[ki] = kj+1; 07493 lpar[kj] = ki+1; 07494 ksucc = 1; 07495 break; 07496 } 07497 } 07498 /* If ksucc==0 then one of the searches was not successful */ 07499 07500 if (ksucc==0) goto war00; 07501 07502 } 07503 07504 goto success; 07505 07506 success: 07507 *jstat = 1; 07508 goto out; 07509 07510 /* No success */ 07511 war00: 07512 *jstat=0; 07513 /* If we got only singular points, set status. */ 07514 if (ndir[0] == 2) *jstat = 2; 07515 07516 goto out; 07517 07518 /* Error in space allocation */ 07519 err101: 07520 *jstat = -101; 07521 s6err("s9conmarch",*jstat,kpos); 07522 goto out; 07523 07524 /* Error in lower level function */ 07525 error: 07526 *jstat = kstat; 07527 s6err("s9conmarch",*jstat,kpos); 07528 goto out; 07529 07530 out:; 07531 } 07532 07533 07534 //=========================================================================== 07535 void s9surmarch(SISLSurf *ps1,SISLSurf *ps2,double epar[],int ndir[],int ipoint, 07536 double *gpar[],int *mpar[],int *jpoint,int *jstat) 07537 //=========================================================================== 07538 { 07539 int kstat; /* Status variable */ 07540 int kpos=0; /* Position of error */ 07541 int *lpar = SISL_NULL; /* Pointer to output integer array */ 07542 int ki,kj; 07543 int kn1,kn2,kk1,kk2; /* Surface attributes. */ 07544 double tstart1,tstart2,tend1,tend2; /* Surface attributes. */ 07545 int ksucc; /* Success indicator */ 07546 double tepsge=1.0; /* Not used */ 07547 double *spar=SISL_NULL; /* Pointer to output real array */ 07548 double scand1[4]; /* Result of iteration process */ 07549 double scand2[4]; /* Result of iteration process */ 07550 double *sp,*sq; /* Pointer used in loop */ 07551 double tdum1; /* Max knot value used in DEQUAL comparing. */ 07552 double tdum2; /* Max knot value used in DEQUAL comparing. */ 07553 double tdum3; /* Max knot value used in DEQUAL comparing. */ 07554 double tdum4; /* Max knot value used in DEQUAL comparing. */ 07555 07556 /* Init */ 07557 kn1 = ps1->in1; 07558 kn2 = ps1->in2; 07559 kk1 = ps1->ik1; 07560 kk2 = ps1->ik2; 07561 07562 tstart1 = ps1->et1[kk1-1]; 07563 tend1 = ps1->et1[kn1]; 07564 tstart2 = ps1->et2[kk2-1]; 07565 tend2 = ps1->et2[kn2]; 07566 07567 tdum1 = (double)2.0*max(fabs(tstart1),fabs(tend1)); 07568 tdum2 = (double)2.0*max(fabs(tstart2),fabs(tend2)); 07569 07570 kn1 = ps2->in1; 07571 kn2 = ps2->in2; 07572 kk1 = ps2->ik1; 07573 kk2 = ps2->ik2; 07574 07575 tstart1 = ps2->et1[kk1-1]; 07576 tend1 = ps2->et1[kn1]; 07577 tstart2 = ps2->et2[kk2-1]; 07578 tend2 = ps2->et2[kn2]; 07579 07580 07581 tdum3 = (double)2.0*max(fabs(tstart1),fabs(tend1)); 07582 tdum4 = (double)2.0*max(fabs(tstart2),fabs(tend2)); 07583 07584 07585 /* Allocate output arrays */ 07586 07587 if ((*mpar=newarray(2*ipoint,INT )) == SISL_NULL) goto err101; 07588 if ((*gpar=newarray(8*ipoint,DOUBLE)) == SISL_NULL) goto err101; 07589 07590 lpar = *mpar; 07591 spar = *gpar; 07592 07593 memcopy(spar,epar,4*ipoint,DOUBLE); 07594 *jpoint = ipoint; 07595 07596 /* Initiate output integer array to point to no points */ 07597 07598 for (ki=0 ; ki< 2*ipoint ; ki++) *(lpar+ki) = 0; 07599 07600 07601 /* Loop for all input points. */ 07602 for (ki=0, sp=spar ; ki< ipoint-1 ; ki++, sp+=4) 07603 { 07604 /* Start marching from point ki */ 07605 07606 /* Exclude points already connected and parallell points. */ 07607 if (lpar[ki] != 0 || ndir[ki] == 0) continue; 07608 07609 /* SISLPoint not marched to */ 07610 07611 s1788(ps1,ps2,tepsge,sp,scand1,scand2,&kstat); 07612 if (kstat<0) goto error; 07613 if (kstat==0) goto war00;; 07614 07615 /* Run through remaining points to find if scand2 matches any 07616 of them. If we've got only two points, we connect them.*/ 07617 07618 ksucc = 0; 07619 07620 for (kj=ki+1,sq=spar+4*ki+4 ; kj<ipoint ; kj++,sq+=4) 07621 { 07622 07623 /* SISLPoint found */ 07624 07625 if (DEQUAL(sq[0]+tdum1,scand2[0]+tdum1) && 07626 DEQUAL(sq[1]+tdum2,scand2[1]+tdum2) && 07627 DEQUAL(sq[2]+tdum3,scand2[2]+tdum3) && 07628 DEQUAL(sq[3]+tdum4,scand2[3]+tdum4)) 07629 07630 { 07631 /* Accepted end point found */ 07632 07633 lpar[ki] = kj+1; 07634 lpar[kj] = ki+1; 07635 ksucc = 1; 07636 break; 07637 } 07638 } 07639 /* If ksucc==0 then one of the searches was not successful */ 07640 07641 if (ksucc==0) goto war00; 07642 07643 } 07644 07645 goto success; 07646 07647 success: 07648 *jstat = 1; 07649 goto out; 07650 07651 /* No success */ 07652 war00: 07653 *jstat=0; 07654 /* If we got only singular points, set status.*/ 07655 if (ndir[0] == 2) *jstat = 2; 07656 goto out; 07657 07658 /* Error in space allocation */ 07659 err101: 07660 *jstat = -101; 07661 s6err("s9surmarch",*jstat,kpos); 07662 goto out; 07663 07664 /* Error in lower level function */ 07665 error: 07666 *jstat = kstat; 07667 s6err("s9surmarch",*jstat,kpos); 07668 goto out; 07669 07670 out:; 07671 } 07672 07673 07674 //=========================================================================== 07675 void shsing_s9dir(double cdiff[],double evals[],double evalq[]) 07676 //=========================================================================== 07677 { 07678 07679 07680 int ki; /* Loop control. */ 07681 int kdim = 3; /* Dim of object space. */ 07682 double *sval; /* Pointer to first surface value */ 07683 double *s_u,*s_v,*s_uu,*s_uv,*s_vv; /* Pointers to first surface derivatives */ 07684 double *ns; /* Pointer to first surface normal */ 07685 double *qval; /* Pointer to second surface value */ 07686 double *q_t,*q_r,*q_tt,*q_tr,*q_rr; /* Pointer to second surface derivatives */ 07687 double *nq; /* Pointer to second surface normal */ 07688 double nq_u[3], nq_v[3]; /* Derivatives of second surface normal (with u and v !) */ 07689 double help1[3], help2[3]; /* Help arrays */ 07690 double help3[3], help4[3]; /* Help arrays */ 07691 double matr[4]; /* Matrix in linear equation to be solved */ 07692 int piv[2]; /* Pivotation array */ 07693 double sq[3]; /* The difference cevtor S-Q */ 07694 double h_u[2]; /* The partial derivative of h() by u */ 07695 double h_v[2]; /* The partial derivative of h() by v */ 07696 int kstat; /* Local status */ 07697 07698 /* ------------------------------------------------------------------------------- */ 07699 07700 cdiff[0] = DZERO; 07701 cdiff[1] = DZERO; 07702 cdiff[2] = DZERO; 07703 cdiff[3] = DZERO; 07704 07705 /* Init, Set pointers to input values */ 07706 sval = evals; 07707 qval = evalq; 07708 07709 s_u = sval + kdim; 07710 s_v = s_u + kdim; 07711 s_uu = s_v + kdim; 07712 s_uv = s_uu + kdim; 07713 s_vv = s_uv + kdim; 07714 ns = s_vv + kdim; 07715 07716 q_t = qval + kdim; 07717 q_r = q_t + kdim; 07718 q_tt = q_r + kdim; 07719 q_tr = q_tt + kdim; 07720 q_rr = q_tr + kdim; 07721 nq = q_rr + kdim; 07722 07723 /* Get the difference vector S-Q */ 07724 s6diff(sval,qval,kdim,sq); 07725 07726 /* Find the derivatives of the h() function by solving 2 2x2 systems (same matrix) */ 07727 matr[0] = s6scpr(q_tt,sq,kdim) - s6scpr(q_t,q_t,kdim); 07728 matr[1] = s6scpr(q_tr,sq,kdim) - s6scpr(q_t,q_r,kdim); 07729 matr[2] = matr[1]; 07730 matr[3] = s6scpr(q_rr,sq,kdim) - s6scpr(q_r,q_r,kdim); 07731 07732 h_u[0] = -s6scpr(s_u,q_t,kdim); 07733 h_u[1] = -s6scpr(s_u,q_r,kdim); 07734 07735 h_v[0] = -s6scpr(s_v,q_t,kdim); 07736 h_v[1] = -s6scpr(s_v,q_r,kdim); 07737 07738 07739 /* Factorize matrix */ 07740 s6lufacp(matr,piv,2,&kstat); 07741 if (kstat != 0) goto out; 07742 07743 /* Solve */ 07744 s6lusolp(matr,h_u,piv,2,&kstat); 07745 if (kstat != 0) goto out; 07746 07747 /* Solve */ 07748 s6lusolp(matr,h_v,piv,2,&kstat); 07749 if (kstat != 0) goto out; 07750 07751 /* Construct matrix for finding du and dv */ 07752 for (ki=0;ki<kdim;ki++) 07753 { 07754 help1[ki] = q_tt[ki]*h_u[0] + q_tr[ki]*h_u[1]; 07755 help2[ki] = q_tr[ki]*h_u[0] + q_rr[ki]*h_u[1]; 07756 } 07757 s6crss(help1,q_r,help3); 07758 s6crss(q_t,help2,help4); 07759 07760 for (ki=0;ki<3;ki++) nq_u[ki] = help3[ki] + help4[ki]; 07761 07762 for (ki=0;ki<kdim;ki++) 07763 { 07764 help1[ki] = q_tt[ki]*h_v[0] + q_tr[ki]*h_v[1]; 07765 help2[ki] = q_tr[ki]*h_v[0] + q_rr[ki]*h_v[1]; 07766 } 07767 s6crss(help1,q_r,help3); 07768 s6crss(q_t,help2,help4); 07769 07770 for (ki=0;ki<3;ki++) nq_v[ki] = help3[ki] + help4[ki]; 07771 07772 for (ki=0;ki<4;ki++) matr[ki] = DZERO; 07773 07774 for (ki=0;ki<3;ki++) 07775 { 07776 matr[0] += s_uu[ki]*nq[ki] + s_u[ki]*nq_u[ki]; 07777 matr[1] += s_uv[ki]*nq[ki] + s_u[ki]*nq_v[ki]; 07778 matr[2] += s_uv[ki]*nq[ki] + s_v[ki]*nq_u[ki]; 07779 matr[3] += s_vv[ki]*nq[ki] + s_v[ki]*nq_v[ki]; 07780 } 07781 07782 /* solve the linear 2x2 system */ 07783 07784 s6lufacp(matr,piv,2,&kstat); 07785 if (kstat != 0) 07786 { 07787 if( DNEQUAL(matr[0],DZERO)) cdiff[0] = - s6scpr(s_u,nq,kdim)/matr[0]; 07788 else if( DNEQUAL(matr[1],DZERO)) cdiff[1] = - s6scpr(s_u,nq,kdim)/matr[1]; 07789 else if( DNEQUAL(matr[2],DZERO)) cdiff[0] = - s6scpr(s_v,nq,kdim)/matr[2]; 07790 else if( DNEQUAL(matr[3],DZERO)) cdiff[1] = - s6scpr(s_v,nq,kdim)/matr[3]; 07791 07792 } 07793 else 07794 { 07795 cdiff[0] = - s6scpr(s_u,nq,kdim); 07796 cdiff[1] = - s6scpr(s_v,nq,kdim); 07797 s6lusolp(matr,cdiff,piv,2,&kstat); 07798 } 07799 out:; 07800 07801 } 07802 07803 //=========================================================================== 07804 void shsing_s9corr(double gd[], double coef[],double limit[]) 07805 //=========================================================================== 07806 { 07807 int ki; 07808 07809 for (ki=0;ki<4;ki++) 07810 if (coef[ki] + gd[ki] < limit[2*ki]) gd[ki] = limit[2*ki] - coef[ki]; 07811 else if (coef[ki] + gd[ki] > limit[2*ki+1]) gd[ki] = limit[2*ki +1] - coef[ki]; 07812 07813 07814 } 07815 07816 07817 //=========================================================================== 07818 void shsing(SISLSurf *psurf1,SISLSurf *psurf2,double limit[], 07819 double enext[], double gpos[],int *jstat) 07820 //=========================================================================== 07821 { 07822 int kstat = 0; /* Local status variable. */ 07823 int kpos = 0; /* Position of error. */ 07824 int ki; /* Loop control */ 07825 int kleftt=0; /* Variables used in the evaluator. */ 07826 int klefts=0; /* Variables used in the evaluator. */ 07827 int kleftu=0; /* Variables used in the evaluator. */ 07828 int kleftv=0; /* Variables used in the evaluator. */ 07829 int kder=2; /* Order of derivatives to be calulated */ 07830 int kdim=3; /* Dimension of space the surface lies in */ 07831 int knbit; /* Number of iterations */ 07832 double tdelta[4]; /* Length of parameter intervals. */ 07833 double tdist; /* The current norm of the cross product */ 07834 /* between the two normals */ 07835 double tprev; /* The current norm of the cross product */ 07836 /* between the two normals */ 07837 double td[4],t1[4],tdn[4];/* Distances between old and new parameter */ 07838 /* value in the four parameter directions. */ 07839 double sval1[21]; /* Value ,first and second derivatiev of surf. */ 07840 double *snorm1=sval1+18; /* Normal vector of the surface */ 07841 double sval2[21]; /* Value ,first and second derivatiev of surf. */ 07842 double *snorm2=sval2+18; /* Normal vector of the surface */ 07843 double snext[4]; /* Parameter values */ 07844 double temp[3]; /* Temp vector storing cross products. */ 07845 double start[2]; /* Parameters limit of second surface, used in */ 07846 /* call to closest point */ 07847 double end[2]; /* Parameters limit of second surface, used in */ 07848 /* call to closest point */ 07849 double guess[2]; /* Start point for closest point iteration */ 07850 double tol = (double)10000.0*REL_COMP_RES; /* equality tol. in par.space */ 07851 SISLPoint *ppoint=SISL_NULL; /* Contains the current position in first */ 07852 /* surface used in closest point iteration */ 07853 int max_iter=20; /* Maximal number of iteration allowed */ 07854 07855 /* --------------------------------------------------------------------- */ 07856 07857 /* Test input. */ 07858 if (psurf1->idim != kdim) goto err106; 07859 if (psurf2->idim != kdim) goto err106; 07860 07861 /* Fetch referance numbers from the serach intervals for the surfaces. */ 07862 tdelta[0] = limit[1] - limit[0]; 07863 tdelta[1] = limit[3] - limit[2]; 07864 tdelta[2] = limit[5] - limit[4]; 07865 tdelta[3] = limit[7] - limit[6]; 07866 07867 /* Set limit values, used in closest point iteration */ 07868 start[0] = limit[4]; 07869 start[1] = limit[6]; 07870 end[0] = limit[5]; 07871 end[1] = limit[7]; 07872 07873 /* Create point, used in closest point iteration */ 07874 ppoint = newPoint(sval1,3,0); 07875 07876 /* Collapsed ? */ 07877 for (ki=0;ki<4;ki++) if (tdelta[ki] < tol) goto errsmall; 07878 07879 /* Initiate output variables. */ 07880 for (ki=0;ki<4;ki++) gpos[ki] = enext[ki]; 07881 07882 /* Evaluate 0.-2. derivatives of first surface */ 07883 s1421(psurf1,kder,gpos,&kleftt,&klefts,sval1,snorm1,&kstat); 07884 if (kstat < 0) goto error; 07885 07886 /* Get closest point in second surface. */ 07887 guess[0] = gpos[2]; 07888 guess[1] = gpos[3]; 07889 s1773(ppoint,psurf2,REL_COMP_RES,start,end,guess,gpos+2,&kstat); 07890 if (kstat < 0) goto error; 07891 07892 /* Evaluate 0.-2. derivatives of second surface */ 07893 s1421(psurf2,kder,gpos+2,&kleftu,&kleftv,sval2,snorm2,&kstat); 07894 if (kstat < 0) goto error; 07895 07896 /* Get length of normal cross product */ 07897 s6crss(snorm1,snorm2,temp); 07898 tprev = s6length(temp,kdim,&kstat); 07899 07900 /* Compute the Newton stepdistance vector in first surface. */ 07901 shsing_s9dir(td,sval1,sval2); 07902 07903 /* Adjust if we are not inside the parameter intervall. */ 07904 for (ki=0;ki<4;ki++) t1[ki] = td[ki]; 07905 07906 shsing_s9corr(t1,gpos,limit); 07907 07908 /* Iteratation loop. */ 07909 07910 for (knbit = 0; knbit < max_iter; knbit++) 07911 { 07912 07913 for (ki=0;ki<2;ki++) snext[ki] = gpos[ki] + t1[ki]; 07914 07915 /* Evaluate 0.-2. derivatives of first surface */ 07916 s1421(psurf1,kder,snext,&kleftt,&klefts,sval1,snorm1,&kstat); 07917 if (kstat < 0) goto error; 07918 07919 /* Get closest point in second surface. */ 07920 guess[0] = gpos[2]; 07921 guess[1] = gpos[3]; 07922 s1773(ppoint,psurf2,REL_COMP_RES,start,end,guess,snext+2,&kstat); 07923 if (kstat < 0) goto error; 07924 07925 /* Evaluate 0.-2. derivatives of second surface */ 07926 s1421(psurf2,kder,snext+2,&kleftu,&kleftv,sval2,snorm2,&kstat); 07927 if (kstat < 0) goto error; 07928 07929 /* Get length of normal cross product */ 07930 s6crss(snorm1,snorm2,temp); 07931 tdist = s6length(temp,kdim,&kstat); 07932 07933 /* Compute the Newton stepdistance vector. */ 07934 shsing_s9dir(tdn,sval1,sval2); 07935 07936 if (tdist <= tprev) 07937 { 07938 /* Ordinary converging. */ 07939 07940 for (ki=0;ki<4;ki++) 07941 { 07942 gpos[ki] = snext[ki]; 07943 td[ki] = t1[ki] = tdn[ki]; 07944 } 07945 07946 /* Adjust if we are not inside the parameter intervall. */ 07947 shsing_s9corr(t1,gpos,limit); 07948 07949 if ((fabs(t1[0]/tdelta[0]) <= REL_COMP_RES) && 07950 (fabs(t1[1]/tdelta[1]) <= REL_COMP_RES) && 07951 (fabs(t1[2]/tdelta[2]) <= REL_COMP_RES) && 07952 (fabs(t1[3]/tdelta[3]) <= REL_COMP_RES)) 07953 { 07954 for (ki=0;ki<2;ki++) gpos[ki] += t1[ki]; 07955 /* Evaluate 0.-2. derivatives of first surface */ 07956 s1421(psurf1,kder,gpos,&kleftt,&klefts,sval1,snorm1,&kstat); 07957 if (kstat < 0) goto error; 07958 07959 /* Get closest point in second surface. */ 07960 guess[0] = gpos[2]; 07961 guess[1] = gpos[3]; 07962 s1773(ppoint,psurf2,REL_COMP_RES,start,end,guess,gpos+2,&kstat); 07963 if (kstat < 0) goto error; 07964 break; 07965 } 07966 tprev = tdist; 07967 } 07968 07969 else 07970 { 07971 /* Not converging, half step length try again. */ 07972 07973 for (ki=0;ki<4;ki++) t1[ki] /= (double)2; 07974 } 07975 } 07976 07977 /* Iteration stopped, test if point is extremum */ 07978 /* Unsure about what i right here , angle between normals and difference vector ?? */ 07979 if (tdist <= tol) 07980 *jstat = 1; 07981 else 07982 *jstat = 0; 07983 07984 07985 /* Test if the iteration is close to a knot */ 07986 if (fabs(gpos[0] - psurf1->et1[kleftt])/tdelta[0] < tol) 07987 gpos[0] = psurf1->et1[kleftt]; 07988 else if (fabs(gpos[0] - psurf1->et1[kleftt+1])/tdelta[0] < tol) 07989 gpos[0] = psurf1->et1[kleftt+1]; 07990 07991 if (fabs(gpos[1] - psurf1->et2[klefts])/tdelta[1] < tol) 07992 gpos[1] = psurf1->et2[klefts]; 07993 else if (fabs(gpos[1] - psurf1->et2[klefts+1])/tdelta[1] < tol) 07994 gpos[1] = psurf1->et2[klefts+1]; 07995 07996 if (fabs(gpos[2] - psurf2->et1[kleftu])/tdelta[2] < tol) 07997 gpos[2] = psurf2->et1[kleftu]; 07998 else if (fabs(gpos[2] - psurf2->et1[kleftu+1])/tdelta[2] < tol) 07999 gpos[2] = psurf2->et1[kleftu+1]; 08000 08001 if (fabs(gpos[3] - psurf2->et2[kleftv])/tdelta[3] < tol) 08002 gpos[3] = psurf2->et2[kleftv]; 08003 else if (fabs(gpos[3] - psurf2->et2[kleftv+1])/tdelta[3] < tol) 08004 gpos[3] = psurf2->et2[kleftv+1]; 08005 08006 /* Iteration completed. */ 08007 goto out; 08008 08009 /* --------------------------------------------------------------------- */ 08010 /* Error in input. Dimension not equal to 3 */ 08011 err106: *jstat = -106; 08012 s6err("shsing",*jstat,kpos); 08013 goto out; 08014 08015 /* Error in input. One parameter interval colapsed. */ 08016 errsmall: *jstat = -200; 08017 s6err("shsing",*jstat,kpos); 08018 goto out; 08019 08020 /* Error in lower level routine. */ 08021 error : *jstat = kstat; 08022 s6err("shsing",*jstat,kpos); 08023 goto out; 08024 08025 out:if(ppoint) freePoint(ppoint); 08026 } 08027 08028 08029 08030 //=========================================================================== 08031 void s6findfac(double evecu[],double evecv[],double evecw[],double etang[], 08032 int idim,int isign,double *coef1,double *coef2,double *coef3,int *jstat) 08033 //=========================================================================== 08034 { 08035 08036 int kstat = 0; /* Status variable. */ 08037 int ki; /* Counter. */ 08038 double tdotuu; /* Scalar product of evecu and evecu. */ 08039 double tdotuv; /* Scalar product of evecu and evecv. */ 08040 double tdotutang; /* Scalar product of evecu and etang. */ 08041 double tdotvv; /* Scalar product of evecv and evecv. */ 08042 double tdotvtang; /* Scalar product of evecv and etang. */ 08043 double tdiv; /* Determinant of equation system. */ 08044 double sdum[3]; /* Help vector. */ 08045 08046 *jstat = 0; 08047 08048 /* Test input. */ 08049 08050 /* if (idim != 3) goto err104; */ 08051 08052 /* Set output to zero. */ 08053 08054 *coef1 = (double)0.0; 08055 *coef2 = (double)0.0; 08056 08057 /* Compute coefficients of equation system. */ 08058 08059 tdotuu = s6scpr(evecu,evecu,idim); 08060 tdotuv = s6scpr(evecu,evecv,idim); 08061 tdotutang = (double)isign*s6scpr(evecu,etang,idim); 08062 tdotvv = s6scpr(evecv,evecv,idim); 08063 tdotvtang = (double)isign*s6scpr(evecv,etang,idim); 08064 08065 tdiv = tdotuv*tdotuv - tdotuu*tdotvv; 08066 if (DEQUAL(tdiv,DZERO)) 08067 { 08068 if (DEQUAL(tdotuu,DZERO) && DEQUAL(tdotvv,DZERO)); 08069 else if (DEQUAL(tdotuu,DZERO)) 08070 *coef2 = s6length(etang,idim,&kstat)/sqrt(tdotvv); 08071 else 08072 *coef1 = s6length(etang,idim,&kstat)/sqrt(tdotuu); 08073 goto out; 08074 } 08075 08076 /* Compute the first two output factors. */ 08077 08078 *coef1 = (tdotvtang*tdotuv - tdotutang*tdotvv)/tdiv; 08079 *coef2 = (tdotutang*tdotuv - tdotvtang*tdotuu)/tdiv; 08080 08081 /* Find third output factor. */ 08082 08083 for (ki=0; ki<idim; ki++) 08084 sdum[ki] = (double)isign*etang[ki] - *coef1*evecu[ki] - *coef2*evecv[ki]; 08085 *coef3 = s6length(sdum,idim,&kstat)/s6length(evecw,idim,&kstat); 08086 08087 if (s6scpr(sdum,evecw,idim) < DZERO) (*coef3) *= -(double)1.0; 08088 08089 goto out; 08090 08091 08092 out : 08093 return; 08094 } 08095 08096 08097 //=========================================================================== 08098 int s1789_s9knot(double et[], int ik, int in, double ax1, double ax2, 08099 int *jmy, int *jstat) 08100 //=========================================================================== 08101 { 08102 int kstat = 0; /* Status variable. */ 08103 int kleft1 = 0; 08104 int kleft2 = 0; 08105 int kknot; 08106 double tref = et[in] - et[ik-1]; 08107 08108 /* Initialize input. */ 08109 08110 *jmy = 0; 08111 08112 /* Find position of the input parameter values in the given knot vector. */ 08113 08114 s1219(et, ik, in, &kleft1, ax1, &kstat); 08115 if (kstat < 0) goto error; 08116 08117 s1219(et, ik, in, &kleft2, ax2, &kstat); 08118 if (kstat < 0) goto error; 08119 08120 if (kleft1 != kleft2) 08121 { 08122 /* Not the same knot interval. */ 08123 08124 if (ax1 < ax2) (*jmy) = kleft1 + 1; 08125 else 08126 { 08127 (*jmy) = kleft1 - 1; 08128 while (DEQUAL(et[*jmy], et[kleft1])) (*jmy)--; 08129 } 08130 } 08131 08132 if (kleft1 == kleft2 || 08133 DEQUAL(et[*jmy]+tref, ax2+tref) || 08134 (DEQUAL(et[kleft1]+tref, ax1+tref) && kleft2 == (*jmy) && 08135 DEQUAL(et[kleft2]+tref, ax2+tref))) 08136 kknot = 0; /* No knot found between the parameter values. */ 08137 else kknot = 1; /* Knot with index (*jmy) found. */ 08138 08139 *jstat = 0; 08140 goto out; 08141 08142 /* Error in lower level routine. */ 08143 08144 error : *jstat = kstat; 08145 goto out; 08146 08147 out: 08148 return kknot; 08149 } 08150 08151 08152 //=========================================================================== 08153 void s1789_s9eval(double eders[],double enorms[],double etanc[], 08154 double ederc[],int idim, int *jstat) 08155 //=========================================================================== 08156 { 08157 int kstat = 0; /* Status variable. */ 08158 int ki; /* Counter. */ 08159 int ksign = 1; /* Parameter used in s6findfac. */ 08160 double tfac1,tfac2,tfac3; /* Factors found by s6findfac. */ 08161 08162 /* Copy position of surface to output array. */ 08163 08164 memcopy(ederc,eders,idim,DOUBLE); 08165 08166 /* Compute the factors used to express etanc by the derivatives and normal 08167 of the surface. */ 08168 08169 s6findfac(eders+idim,eders+2*idim,enorms,etanc,idim,ksign,&tfac1,&tfac2, 08170 &tfac3,&kstat); 08171 if (kstat < 0) goto error; 08172 08173 /* Compute first and second derivative of the curve in the surface. */ 08174 08175 for (ki=0; ki<idim; ki++) 08176 { 08177 ederc[idim+ki] = tfac1*eders[idim+ki] + tfac2*eders[2*idim+ki]; 08178 ederc[2*idim+ki] = tfac1*tfac1*eders[3*idim+ki] 08179 + (double)2.0*tfac1*tfac2*eders[4*idim+ki] + tfac2*tfac2*eders[5*idim+ki]; 08180 } 08181 08182 *jstat = 0; 08183 goto out; 08184 08185 /* Error in lower level routine. */ 08186 08187 error: 08188 *jstat = kstat; 08189 goto out; 08190 08191 out: 08192 return; 08193 } 08194 08195 08196 //=========================================================================== 08197 void s1789(SISLPoint *ppoint,SISLSurf *psurf,double aepsge, 08198 double epar1[],double epar2[],int *jstat) 08199 //=========================================================================== 08200 { 08201 int kstat; /* Status variable */ 08202 int ki; /* Counter. */ 08203 int kleft1=0; /* Left indicator for point calculation in 1. par. 08204 direction of surface. */ 08205 int kleft2=0; /* Left indicator for point calculation in 2. par dir.*/ 08206 int kknot1, kknot2; /* Indicates whether there is a knot between the 08207 input points in 1. and 2. parameter direction. */ 08208 int kmy1, kmy2; /* Index of an eventual knot. */ 08209 int kk1,kk2,kn1,kn2;/* Orders and nu,ber of vertices of surface */ 08210 int kdims; /* Dimension of space where the surface lies */ 08211 int kpos=0; /* Position of error */ 08212 int kders=2; /* Number of derivatives to be calculated on surface 08213 If step lenght is to be generated from surface, 08214 kders must be equal to 2. */ 08215 int kpar; /* Parameter value of constant parameter curve. */ 08216 double snorm[3]; /* Normal vector of surface */ 08217 double *st1; /* First knot direction of surface */ 08218 double *st2; /* Second knot direction of surface */ 08219 double sders[18]; /* Position, first and second derivatives of surface */ 08220 double tstep; /* Final step length */ 08221 double tlengthend; /* Length of 1st derivative at end of segment */ 08222 double tincre; /* Parameter value increment */ 08223 double tsmax; /* Local maximal step length based of boxsizes of objects */ 08224 double tdist; /* Distance */ 08225 double tref; /* Referance value in equality test. */ 08226 double sstart[2]; /* Lower boundary of parameter intervals */ 08227 double send[2]; /* Upper bounadry of parameter intervals */ 08228 double spos[2]; /* New iteration point on surface */ 08229 double spos1[2]; /* New iteration point on surface */ 08230 double spos2[2]; /* New iteration point on surface */ 08231 double sint[2]; /* Interval between test points in par. space. */ 08232 double snext[2]; /* Save previous intersection point. */ 08233 double sdiff[2]; /* Difference vector between input int. pts. */ 08234 double spardir[2]; /* Direction of coincidence curve in parameter area. */ 08235 double tbeta; /* Scaling factor between partial derivatives of sf. */ 08236 double stanc[2]; /* Direction of coincidence curve in surface. */ 08237 double sder2[10]; /* Information about curve in surface. */ 08238 double tdot; /* Scalar product to test direction of vectors. */ 08239 double td; /* Distance between current and last point. */ 08240 double s3dinf2[10]; /* Marching information to decide step length. */ 08241 SISLCurve *qc = SISL_NULL; /* Constant parameter curve. */ 08242 08243 *jstat = 0; 08244 08245 /* Make maximal step length based on box-size of surface */ 08246 08247 sh1992su(psurf,0,aepsge,&kstat); 08248 if (kstat < 0) goto error; 08249 08250 tsmax = MAX(psurf->pbox->e2max[0][0] - psurf->pbox->e2min[0][0], 08251 psurf->pbox->e2max[0][1] - psurf->pbox->e2min[0][1]); 08252 08253 /* Copy surface attributes to local parameters. */ 08254 08255 kdims = psurf -> idim; 08256 kk1 = psurf -> ik1; 08257 kk2 = psurf -> ik2; 08258 kn1 = psurf -> in1; 08259 kn2 = psurf -> in2; 08260 st1 = psurf -> et1; 08261 st2 = psurf -> et2; 08262 08263 /* Set reference value. */ 08264 08265 tref = MAX(st1[kn1]-st1[kk1-1],st2[kn2]-st2[kk2-1]); 08266 08267 /* Check dimension */ 08268 08269 if (ppoint->idim != kdims || (kdims != 2 && kdims != 3)) 08270 goto err105; 08271 08272 sstart[0] = st1[kk1-1]; 08273 sstart[1] = st2[kk2-1]; 08274 send[0] = st1[kn1]; 08275 send[1] = st2[kn2]; 08276 08277 /* Set start point for marching on surface */ 08278 08279 spos1[0] = epar1[0]; 08280 spos1[1] = epar1[1]; 08281 08282 /* Set difference vector between input points. */ 08283 08284 s6diff(epar2, epar1, 2, sdiff); 08285 08286 /* Evaluate start point of surface. */ 08287 08288 s1421(psurf,kders,spos1,&kleft1,&kleft2,sders,snorm,&kstat); 08289 if (kstat < 0) goto error; 08290 08291 /* While end not reached */ 08292 08293 td = s6dist(spos1, epar2, 2); 08294 while (td > REL_PAR_RES) 08295 { 08296 /* Compute direction of marching. The partial derivatives of the 08297 surface in this point must be almost parallel. Find the factor 08298 that makes the partial derivatives sum up to zero (approximately). */ 08299 08300 if (kdims == 2) 08301 { 08302 if (DEQUAL(sders[kdims]+tref,tref) && 08303 DEQUAL(sders[kdims+1]+tref,tref) && 08304 DEQUAL(sders[kdims+2]+tref,tref)) break; 08305 08306 if (sders[2] >= sders[3]) 08307 { 08308 if (DEQUAL(sders[4]+tref,sders[2]+tref)) 08309 tbeta = (double)0.5; 08310 else 08311 tbeta = (double)1/((double)1 - (sders[4]/sders[2])); 08312 } 08313 else 08314 { 08315 if (DEQUAL(sders[5]+tref,sders[3]+tref)) 08316 tbeta = (double)0.5; 08317 else 08318 tbeta = (double)1/((double)1 - (sders[5]/sders[3])); 08319 } 08320 08321 08322 spardir[0] = (double)1-tbeta; 08323 spardir[1] = tbeta; 08324 } 08325 else 08326 { 08327 spardir[0] = epar2[0]-epar1[0]; 08328 spardir[1] = epar2[1]-epar1[1]; 08329 } 08330 08331 tdot = s6norm(spardir, 2, spardir,&kstat); 08332 if (tdot < REL_PAR_RES) 08333 { 08334 *jstat = 0; 08335 goto out; 08336 } 08337 08338 for (ki=0; ki<kdims; ki++) 08339 stanc[ki] = spardir[0]*sders[kdims+ki] + spardir[1]*sders[2*kdims+ki]; 08340 08341 tdot = s6scpr(stanc, sdiff, kdims); 08342 if (tdot < DZERO) 08343 { 08344 stanc[0] *= -(double)1; 08345 stanc[1] *= -(double)1; 08346 } 08347 08348 /* Compute position, first and second derivative of the curve in the 08349 surface going through the evaluated point in this point. */ 08350 08351 s1789_s9eval(sders,snorm,stanc,sder2,kdims,&kstat); 08352 if (kstat < 0) goto error; 08353 08354 /* Calculate unit tangent and radius of curvature of curve in surface.*/ 08355 08356 s1307(sder2,kdims,s3dinf2,&kstat); 08357 if (kstat<0) goto error; 08358 08359 /* Calculate step length based on curvature */ 08360 08361 tstep = s1311(s3dinf2[3*kdims],aepsge,tsmax,&kstat); 08362 if (kstat<0) goto error; 08363 08364 tlengthend = s6length(sder2+kdims,kdims,&kstat); 08365 if (kstat<0) goto error; 08366 08367 /* Find candidate end point, make sure that no breaks in tangent or 08368 curvature exists between start and endpoints of the segment */ 08369 08370 /* Make step length equal to resolution if the length is zero */ 08371 08372 /* Find parameter value of candidate end point of segment */ 08373 08374 if (DEQUAL(tlengthend+tref,tref)) 08375 tincre = REL_PAR_RES; 08376 else 08377 tincre = tstep/tlengthend; 08378 08379 spos2[0] = spos1[0] + tincre*spardir[0]; 08380 spos2[1] = spos1[1] + tincre*spardir[1]; 08381 08382 /* Make sure not to jump out of the surface */ 08383 if ((epar2[0] > epar1[0] && spos2[0] >= epar2[0]) || 08384 (epar2[0] < epar1[0] && spos2[0] <= epar2[0]) || 08385 (epar2[1] > epar1[1] && spos2[1] >= epar2[1]) || 08386 (epar2[1] < epar1[1] && spos2[1] <= epar2[1])) 08387 { 08388 spos2[0] = epar2[0]; 08389 spos2[1] = epar2[1]; 08390 } 08391 08392 if (s6dist(spos1, spos2, kdims) > s6dist(spos1, epar2, kdims)) 08393 memcopy(spos2, epar2, 2, DOUBLE); 08394 08395 /* Check if any knot line exist within the step. */ 08396 08397 kknot1 = s1789_s9knot(st1, kk1, kn1, spos1[0], spos2[0], &kmy1, &kstat); 08398 if (kstat < 0) goto error; 08399 08400 kknot2 = s1789_s9knot(st2, kk2, kn2, spos1[1], spos2[1], &kmy2, &kstat); 08401 if (kstat < 0) goto error; 08402 08403 if ((kknot1 && !kknot2) || 08404 (kknot1 && kknot2 && spardir[1]*(st1[kmy1]-spos1[0]) < 08405 spardir[0]*(st2[kmy2]-spos1[1]))) 08406 { 08407 /* Pull back to knotline in first parameter direction. */ 08408 08409 spos2[0] = psurf->et1[kmy1]; /* Parameter value of knotline. */ 08410 spos2[1] = spos1[1] + (spos2[0]-spos1[0])*spardir[1]/spardir[0]; 08411 kpar = 1; 08412 } 08413 else if (kknot2) 08414 { 08415 /* Pull back to knot line in second parameter direction. */ 08416 08417 spos2[1] = psurf->et2[kmy2]; 08418 spos2[0] = spos1[0] + (spos2[1] - spos1[1])*spardir[0]/spardir[1]; 08419 kpar = 2; 08420 } 08421 else 08422 { 08423 /* No knot line. Decide in which parameter direction to iterate. */ 08424 08425 if (spardir[1]*fabs(st1[kmy1]-spos1[0]) < 08426 spardir[0]*fabs(st2[kmy2]-spos1[1])) 08427 kpar = 1; 08428 else 08429 kpar = 2; 08430 } 08431 08432 sint[0] = (spos2[0]-spos1[0])/(double)3; 08433 sint[1] = (spos2[1]-spos1[1])/(double)3; 08434 08435 for (ki=0, spos[0]=spos1[0]+sint[0], spos[1]=spos1[1]+sint[1]; 08436 ki<3; ki++, spos[0]+=sint[0], spos[1]+=sint[1]) 08437 { 08438 08439 if (kpar == 1) 08440 { 08441 /* Pick constant parameter curve in 1. par. dir. */ 08442 08443 s1437(psurf, spos[0], &qc, &kstat); 08444 if (kstat < 0) goto error; 08445 08446 /* Iterate down to the curve. */ 08447 08448 s1771(ppoint, qc, aepsge, qc->et[qc->ik-1], qc->et[qc->in], 08449 spos[1], &spos[1], &kstat); 08450 if (kstat < 0) goto error; 08451 } 08452 else 08453 { 08454 /* Pick constant parameter curve in 2. par. dir. */ 08455 08456 s1436(psurf, spos[1], &qc, &kstat); 08457 if (kstat < 0) goto error; 08458 08459 /* Iterate down to the curve. */ 08460 08461 s1771(ppoint, qc, aepsge, qc->et[qc->ik-1], qc->et[qc->in], 08462 spos[0], &spos[0], &kstat); 08463 if (kstat < 0) goto error; 08464 } 08465 08466 memcopy(snext, spos, 2, DOUBLE); 08467 08468 /* Calculate point and derivatives in surface */ 08469 08470 s1421(psurf,kders,spos,&kleft1,&kleft2,sders,snorm,&kstat); 08471 if (kstat<0) goto error; 08472 08473 /* Check if the input point and surface point are within positional 08474 tolerance. */ 08475 08476 tdist = s6dist(ppoint->ecoef,sders,kdims); 08477 08478 if (tdist>aepsge) 08479 { 08480 /* Points not within tolerances, no coincide. */ 08481 08482 goto war01; 08483 } 08484 08485 /* Test whether the marching has advanced. */ 08486 08487 if (s6dist(spos1, spos, 2) < REL_PAR_RES) goto war01; 08488 08489 /* Free memory occupied by local curve. */ 08490 08491 if (qc != SISL_NULL) freeCurve(qc); 08492 qc = SISL_NULL; 08493 } 08494 08495 /* Update start parameter of step. */ 08496 08497 spos1[kpar-1] = spos2[kpar-1]; 08498 spos1[2-kpar] = snext[2-kpar]; 08499 td = s6dist(spos1, epar2, 2); 08500 } 08501 08502 if (td > REL_PAR_RES) *jstat = 0; 08503 else *jstat = 1; 08504 08505 goto out; 08506 08507 /* Point and surface not within tolerance */ 08508 war01: *jstat = 0; 08509 goto out; 08510 08511 /* Error in input, dimension not equal to 2 or 3 */ 08512 08513 err105: *jstat = -105; 08514 s6err("s1789",*jstat,kpos); 08515 goto out; 08516 08517 /* Error in lower level function */ 08518 08519 error: *jstat = kstat; 08520 s6err("s1789",*jstat,kpos); 08521 goto out; 08522 08523 08524 out: 08525 if (qc != SISL_NULL) freeCurve(qc); 08526 08527 return; 08528 } 08529 08530 08531 //=========================================================================== 08532 void s1786_s9relax(s1786_fevalcProc fevalc1,s1786_fevalcProc fevalc2, 08533 SISLCurve *pc1,SISLCurve *pc2, 08534 int ider,double aepsge,double ax1,int *jleft1,double eder1[], 08535 double anext,double *cx2,int *jleft2,double eder2[],int *jstat) 08536 //=========================================================================== 08537 { 08538 int kstat = 0; /* Status variable. */ 08539 double tstart; /* Start parameter value of curve 2. */ 08540 double tend; /* End parameter value of curve 2. */ 08541 SISLPoint *qpoint = SISL_NULL; /* SISLPoint instance used to represent point on curve 1. */ 08542 08543 /* Find endpoints of the parameter interval of curve 2. */ 08544 08545 tstart = *(pc2->et + pc2->ik - 1); 08546 tend = *(pc2->et + pc2->in); 08547 08548 08549 /* Make point sderc at curve at ax1 */ 08550 08551 fevalc1(pc1,ider,ax1,jleft1,eder1,&kstat); 08552 08553 if (kstat<0) goto error; 08554 08555 /* Find closest point on curve 2 to eder1 */ 08556 08557 qpoint = newPoint(eder1,pc1->idim,0); 08558 if (qpoint==SISL_NULL) goto err101; 08559 08560 s1771(qpoint,pc2,aepsge,tstart,tend,anext,cx2,&kstat); 08561 if(kstat<0) goto error; 08562 08563 /* Calculate point and derivatives in second curve */ 08564 08565 fevalc2(pc2,ider,*cx2,jleft2,eder2,&kstat); 08566 08567 if (kstat<0) goto error; 08568 08569 *jstat = 0; 08570 goto out; 08571 08572 /* Error in space allocation. */ 08573 08574 err101 : 08575 *jstat = -101; 08576 goto out; 08577 08578 /* Error in lower level routine. */ 08579 08580 error : 08581 *jstat = kstat; 08582 goto out; 08583 08584 out : 08585 if (qpoint != SISL_NULL) freePoint(qpoint); 08586 08587 return; 08588 } 08589 08590 08591 //=========================================================================== 08592 void s1786(SISLCurve *pc1,SISLCurve *pc2,double aepsge,double epar1[], 08593 double epar2[],int *jstat) 08594 //=========================================================================== 08595 { 08596 int kstat; /* Status variable */ 08597 int ki; /* Counter. */ 08598 int kleftc1=0; /* Left indicator for point calculation of curve 1.*/ 08599 int kleftc2=0; /* Left indicator for point calculation of curve 2.*/ 08600 int kk1,kk2,kn1,kn2;/* Orders and number of vertices of curves */ 08601 int kdim; /* The dimension of the space in which the curves lie. */ 08602 int kpos=0; /* Position of error */ 08603 int kderc=2; /* Number of derivatives to be claculated on the curves */ 08604 int kdum; /* Temporary variable */ 08605 int kchange; /* Indicates which curve that is marched along. 08606 = 0 : First curve. 08607 = 1 : Second curve. */ 08608 int kknot; /* Indicates if the next knot in the marching direction 08609 is before or after the current knot. */ 08610 double s3dinf1[20]; /* Pointer to storage for point info of curve 1 08611 (10 dobules pr point when idim=3, 7 when idim=3) */ 08612 double s3dinf2[20]; /* Pointer to storage for point info of curve 2 08613 (10 dobules pr point when idim=3, 7 when idim=3) */ 08614 double *st1; /* Knot vector of first curve */ 08615 double *st2; /* Knot vector of second curve */ 08616 double tfirst1,tfirst2;/* First parameter value on curves */ 08617 double tend1,tend2; /* Last parameter on curves */ 08618 double sderc1[20]; /* Position, first and second derivatives on curve 1 */ 08619 double sderc2[20]; /* Position, first and second derivatives on curve 2 */ 08620 double tx,tx1,tx2; /* Parameter values of first curve. */ 08621 double ty,ty1,ty2; /* Parameter value of second curve. */ 08622 double tminstep; /* Referance value in parameter domain */ 08623 double tstep; /* Final step length */ 08624 double txstep,tystep; /* Step length */ 08625 double txmaxinc,tymaxinc; /* Maximal increment in parameter value along curve*/ 08626 double txlengthend,tylengthend; /* Length of 1st derivative at start of segment */ 08627 double txincre,tyincre; /* Parameter value increment */ 08628 double txmax,tymax; /* Local maximal step length */ 08629 double tdist; /* Distance */ 08630 double tpos; /* New iteration point on curve pc2 */ 08631 08632 /* Pointer to curve evaluator routine of 2. curve. */ 08633 08634 s1786_fevalcProc fevalc; 08635 /* 08636 #if defined(SISLNEEDPROTOTYPES) 08637 void (*fevalc)(SISLCurve *, int, double , int *, double [], int *); 08638 #else 08639 void (*fevalc)(); 08640 #endif 08641 */ 08642 /* UJK, aug 93, make min step in parameter domain based on the 08643 max parameter values */ 08644 tminstep = max(fabs(pc1->et[pc1->ik-1]),fabs(pc1->et[pc1->in])); 08645 tminstep += max(fabs(pc2->et[pc2->ik-1]),fabs(pc2->et[pc2->in])); 08646 tminstep *= REL_PAR_RES; 08647 08648 08649 /* Make maximal step length based on box-size of curve 1 */ 08650 08651 sh1992cu(pc1,0,aepsge,&kstat); 08652 if (kstat < 0) goto error; 08653 08654 txmax = MAX(pc1->pbox->e2max[0][0] - pc1->pbox->e2min[0][0], 08655 pc1->pbox->e2max[0][1] - pc1->pbox->e2min[0][1]); 08656 txmax = MAX(txmax,pc1->pbox->e2max[0][2] - pc1->pbox->e2min[0][2]); 08657 08658 /* Make maximal step length based on box-size of curve 2 */ 08659 08660 sh1992cu(pc2,0,aepsge,&kstat); 08661 if (kstat < 0) goto error; 08662 08663 tymax = MAX(pc2->pbox->e2max[0][0] - pc2->pbox->e2min[0][0], 08664 pc2->pbox->e2max[0][1] - pc2->pbox->e2min[0][1]); 08665 tymax = MAX(tymax,pc2->pbox->e2max[0][2] - pc2->pbox->e2min[0][2]); 08666 08667 /* Copy curve pc1 attributes to local parameters. */ 08668 08669 kdim = pc1 -> idim; 08670 kk1 = pc1 -> ik; 08671 kn1 = pc1 -> in; 08672 st1 = pc1 -> et; 08673 08674 /* Copy curve pc2 attributes to local parameters. */ 08675 08676 kk2 = pc2 -> ik; 08677 kn2 = pc2 -> in; 08678 st2 = pc2 -> et; 08679 08680 /* Check that dimensions are equal */ 08681 08682 if (kdim != pc2->idim || kdim > 3) goto err105; 08683 08684 /* Copy interval description into local variables */ 08685 08686 if ( epar1[0]<epar2[0] ) 08687 { 08688 tfirst1 = epar1[0]; 08689 tfirst2 = epar1[1]; 08690 tend1 = epar2[0]; 08691 tend2 = epar2[1]; 08692 } 08693 else 08694 { 08695 tfirst1 = epar2[0]; 08696 tfirst2 = epar2[1]; 08697 tend1 = epar1[0]; 08698 tend2 = epar1[1]; 08699 } 08700 08701 /* To make sure we do not start outside or end outside the curve we 08702 truncate tstart1 and tend1 to the knot interval of the curve */ 08703 08704 tfirst1 = MAX(tfirst1,st1[kk1-1]); 08705 tend1 = MIN(tend1,st1[kn1]); 08706 08707 /* To make sure we do not start outside or end outside the curve we 08708 truncate tstart2 and tend2 to the knot interval of the curve */ 08709 08710 if (tfirst2 <= tend2) 08711 { 08712 tfirst2 = MAX(tfirst2,st2[kk2-1]); 08713 tend2 = MIN(tend2,st2[kn2]); 08714 kknot = 1; 08715 } 08716 else 08717 { 08718 tfirst2 = MIN(tfirst2,st2[kn2]); 08719 tend2 = MAX(tend2,st2[kk2-1]); 08720 kknot = -1; 08721 } 08722 08723 /* Set curve evaluator of 2. curve. */ 08724 08725 fevalc = (kknot == 1) ? s1221 : s1227; 08726 08727 /* Store knot values at start of curve */ 08728 08729 tx1 = tfirst1; 08730 kdum = MAX(kk1,kk2); 08731 txmaxinc = (tend1-tfirst1)/(kdum*kdum); 08732 txmaxinc = MAX(txmaxinc, REL_PAR_RES); 08733 08734 /* Make start point and intital step length based on first curve */ 08735 08736 s1221(pc1,kderc,tx1,&kleftc1,sderc1,&kstat); 08737 if (kstat<0) goto error; 08738 08739 ty1 = tfirst2; 08740 tymaxinc = fabs(tend2-tfirst2)/(kdum*kdum); 08741 tymaxinc = MAX(tymaxinc, REL_PAR_RES); 08742 08743 /* Make start point and intital step length based on second curve */ 08744 08745 fevalc(pc2,kderc,ty1,&kleftc2,sderc2,&kstat); 08746 if (kstat<0) goto error; 08747 08748 /* While end not reached */ 08749 08750 08751 while (tx1 < tend1 && kknot*ty1 < kknot*tend2) 08752 { 08753 08754 /* Calculate unit tangent and radius of curvature of first curve. */ 08755 08756 s1307(sderc1,kdim,s3dinf1,&kstat); 08757 if (kstat<0) goto error; 08758 08759 /* Calculate step length based on curvature of first curve. */ 08760 08761 txstep = s1311(s3dinf1[3*kdim],aepsge,tymax,&kstat); 08762 if (kstat<0) goto error; 08763 08764 /* Remember length of start tangent, end of zero segment */ 08765 08766 txlengthend = s6length(sderc1+kdim,kdim,&kstat); 08767 if (kstat<0) goto error; 08768 08769 /* Calculate unit tangent and radius of curvature of second curve. */ 08770 08771 s1307(sderc2,kdim,s3dinf2,&kstat); 08772 if (kstat<0) goto error; 08773 08774 /* Calculate step length based on curvature */ 08775 08776 tystep = s1311(s3dinf2[3*kdim],aepsge,txmax,&kstat); 08777 if (kstat<0) goto error; 08778 08779 /* Remember length of start tangent, end of zero segment */ 08780 08781 tylengthend = s6length(sderc2+kdim,kdim,&kstat); 08782 if (kstat<0) goto error; 08783 08784 /* Find minimum step length. */ 08785 08786 tstep = MIN(txstep,tystep); 08787 kchange = (txstep <= tystep) ? 0 : 1; 08788 08789 /* Find candidate end point, make sure that no breaks in tangent or 08790 curvature exists between start and endpoints of the segment */ 08791 /* Compute increment in the parameter values. Use tminstep if the 08792 tangent has zero length. */ 08793 08794 if (DEQUAL(txlengthend,DZERO)) 08795 txincre = tminstep; 08796 else 08797 txincre = MIN(tstep/txlengthend,txmaxinc); 08798 08799 if (DEQUAL(tylengthend,DZERO)) 08800 tyincre = tminstep; 08801 else 08802 tyincre = MIN(tstep/tylengthend,tymaxinc); 08803 08804 /* Make sure that we don't pass any knots of curve 1. */ 08805 08806 if (tx1 + txincre > st1[kleftc1+1] + tminstep && 08807 tx1 < st1[kleftc1+1] - tminstep) 08808 { 08809 txincre = st1[kleftc1+1] - tx1; 08810 tstep = txincre*txlengthend; 08811 tyincre = (tylengthend > DZERO) ? tstep/tylengthend : tminstep; 08812 kchange = 0; 08813 } 08814 08815 /* Avoid passing second next knot of curve 2. */ 08816 08817 if (kknot*(ty1 + tyincre) > kknot*(st2[kleftc2+kknot]+tminstep) && 08818 kknot*ty1 > kknot*(st2[kleftc2+kknot]-tminstep)) 08819 { 08820 tyincre = kknot*(st2[kleftc2+kknot] - ty1); 08821 tstep = tyincre*tylengthend; 08822 txincre = (txlengthend > DZERO) ? tstep/txlengthend : tminstep; 08823 kchange = 1; 08824 } 08825 08826 /* Avoid passing next knot of curve 2. */ 08827 08828 if (kknot < 0 && (ty1 - tyincre < st2[kleftc2] - tminstep) && 08829 (ty1 < st2[kleftc2] + tminstep)) 08830 { 08831 tyincre = kknot*(st2[kleftc2+kknot] - ty1); 08832 tstep = tyincre*tylengthend; 08833 txincre = (txlengthend > DZERO) ? tstep/txlengthend : tminstep; 08834 kchange = 1; 08835 } 08836 08837 08838 /* Set endpoints of step. */ 08839 08840 tx2 = tx1 + txincre; 08841 ty2 = ty1 + kknot*tyincre; 08842 08843 for (tx=(tx1+tx2)/(double)2.0, ty=(ty1+ty2)/(double)2.0, ki=0; 08844 ki<2; ki++, tx=tx2, ty=ty2) 08845 { 08846 if (kchange == 0) 08847 { 08848 if (tx >= tend1) break; 08849 08850 /* March along first curve. Iterate down to the second. */ 08851 08852 s1786_s9relax(s1221,fevalc,pc1,pc2,kderc,aepsge,tx,&kleftc1,sderc1,ty, 08853 &tpos,&kleftc2,sderc2,jstat); 08854 if (kstat < 0) goto error; 08855 } 08856 else 08857 { 08858 /* UJK, 05.05.91 if (kknot*tx >= kknot*tend2) break; */ 08859 if (kknot*ty >= kknot*tend2) break; 08860 08861 /* March along second curve. Iterate down to the first. */ 08862 s1786_s9relax(fevalc,s1221,pc2,pc1,kderc,aepsge,ty,&kleftc2,sderc2,tx, 08863 &tpos,&kleftc1,sderc1,jstat); 08864 if (kstat < 0) goto error; 08865 } 08866 08867 /* Check if point on curve and surface are within positional and 08868 angular tolerances */ 08869 08870 tdist = s6dist(sderc1,sderc2,kdim); 08871 08872 if (tdist>aepsge) 08873 { 08874 /* Points not within tolerances, curve and surface do not 08875 coincide */ 08876 goto war00; 08877 } 08878 } 08879 08880 /* Update start parameter value of segment, and calculate right 08881 hand derivative */ 08882 08883 if (kchange == 0) 08884 { 08885 tx1 = tx2; 08886 ty1 = tpos; 08887 } 08888 else 08889 { 08890 tx1 = tpos; 08891 ty1 = ty2; 08892 } 08893 } 08894 08895 /* Curves within tolerance */ 08896 08897 /* Curves within tolerance. Test if the start- and endpoint of any 08898 of the curves are equal. */ 08899 08900 *jstat = (DEQUAL(tfirst1,tend1) || DEQUAL(tfirst2,tend2)) ? 0 : 1; 08901 goto out; 08902 08903 /* Curve and surface not within tolerance */ 08904 war00: *jstat = 0; 08905 goto out; 08906 08907 /* Error in input, dimension not equal to 2 or 3 */ 08908 08909 err105: *jstat = -105; 08910 s6err("S1786",*jstat,kpos); 08911 goto out; 08912 08913 /* Error in lower level function */ 08914 08915 error: *jstat = kstat; 08916 s6err("S1786",*jstat,kpos); 08917 goto out; 08918 08919 out: 08920 return; 08921 } 08922 08923 08924 //=========================================================================== 08925 void s1785(SISLCurve *pcurve,SISLSurf *psurf,double aepsge, 08926 double epar1[],double epar2[],int icur,int *jstat) 08927 //=========================================================================== 08928 { 08929 int kstat; /* Status variable */ 08930 int ki; /* Counter. */ 08931 int kleftc=0; /* Left indicator for point calculation */ 08932 int kleft1=0; /* Left indicator for point calculation in 1. par. 08933 direction of surface. */ 08934 int kleft2=0; /* Left indicator for point calculation in 2. par dir.*/ 08935 int kleft1prev,kleft2prev; /* Previous left indicators of surface. */ 08936 int khelp; /* Help index of knot vector. */ 08937 int kn; /* The number of B-splines, i.e., the dimension of 08938 the spline space associated with the knot 08939 vector. */ 08940 int kk; /* The polynomial order of the curve. */ 08941 int kk1,kk2,kn1,kn2;/* Orders and nu,ber of vertices of surface */ 08942 int kdimc; /* The dimension of the space in which the curve 08943 lies. Equivalently, the number of components 08944 of each B-spline coefficient. */ 08945 int kdims; /* Dimension of space where the surface lies */ 08946 int kpos=0; /* Position of error */ 08947 int kderc=2; /* Number of derivatives to be claculated on curve */ 08948 int kders=1; /* Number of derivatives to be calculated on surface 08949 If step lenght is to be generated from surface, 08950 kders must be equal to 2. */ 08951 int kdum; /* Temporary variable */ 08952 int kpar; /* Parameter value of constant parameter curve. */ 08953 double tclose1,tclose2; /* Parameter values of closest point between curves. */ 08954 double snorm[3]; /* Normal vector of surface */ 08955 double s3dinf1[10]; /* Pointer to storage for point info of curve 08956 (10 dobules prpoint when idim=3, 7 when idim=3) */ 08957 double *st; /* Pointer to the first element of the knot vector 08958 of the curve. The knot vector has [kn+kk] 08959 elements. */ 08960 double *st1; /* First knot direction of surface */ 08961 double *st2; /* Second knot direction of surface */ 08962 double sfirst[2]; /* Start parameter par in surface */ 08963 double slast[2]; /* End parameter par in surface */ 08964 double tfirst; /* Fist parameter on curve */ 08965 double tend; /* Last parameter on curve */ 08966 double sderc[9]; /* Position, first and second derivative of curve */ 08967 double sders[18]; /* Position, first and second derivatives of surface */ 08968 double tx,tx1,tx2; /* Parameter value */ 08969 double tcstep; /* Step length based on curvature of objects. */ 08970 double tstep; /* Final step length */ 08971 double tmaxinc; /* Maximal increment in parameter value along curve*/ 08972 double tlengthend; /* Length of 1st derivative at end of segment */ 08973 double tincre; /* Parameter value increment */ 08974 double tsmax,tcmax; /* Local maximal step length based of boxsizes of objects */ 08975 double tdist; /* Distance */ 08976 double tref; /* Referance value in equality test. */ 08977 double sstart[2]; /* Lower boundary of parameter intervals */ 08978 double send[2]; /* Upper bounadry of parameter intervals */ 08979 double snext[3]; /* Existing iteration point on surface */ 08980 double spos[3]; /* New iteration point on surface */ 08981 double snext2[2]; /* Help parameter values. */ 08982 SISLPoint *qpoint=SISL_NULL; 08983 SISLCurve *qc = SISL_NULL; /* Constant parameter curve. */ 08984 08985 *jstat = 0; 08986 08987 /* Make maximal step length based on box-size of surface */ 08988 08989 sh1992su(psurf,0,aepsge,&kstat); 08990 if (kstat < 0) goto error; 08991 08992 tsmax = MAX(psurf->pbox->e2max[0][0] - psurf->pbox->e2min[0][0], 08993 psurf->pbox->e2max[0][1] - psurf->pbox->e2min[0][1]); 08994 tsmax = MAX(tsmax,psurf->pbox->e2max[0][2] - psurf->pbox->e2min[0][2]); 08995 08996 /* Make maximal step length based on box-size of curve */ 08997 08998 sh1992cu(pcurve,0,aepsge,&kstat); 08999 if (kstat < 0) goto error; 09000 09001 tcmax = MAX(pcurve->pbox->e2max[0][0] - pcurve->pbox->e2min[0][0], 09002 pcurve->pbox->e2max[0][1] - pcurve->pbox->e2min[0][1]); 09003 tcmax = MAX(tcmax,pcurve->pbox->e2max[0][2] - pcurve->pbox->e2min[0][2]); 09004 09005 /* Copy curve attributes to local parameters. */ 09006 09007 kdimc = pcurve -> idim; 09008 kk = pcurve -> ik; 09009 kn = pcurve -> in; 09010 st = pcurve -> et; 09011 09012 /* Copy surface attributes to local parameters. */ 09013 09014 kdims = psurf -> idim; 09015 kk1 = psurf -> ik1; 09016 kk2 = psurf -> ik2; 09017 kn1 = psurf -> in1; 09018 kn2 = psurf -> in2; 09019 st1 = psurf -> et1; 09020 st2 = psurf -> et2; 09021 09022 /* Set reference value. */ 09023 09024 tref = MAX(st[kn]-st[kk-1],MAX(st1[kn1]-st1[kk1-1],st2[kn2]-st2[kk2-1])); 09025 09026 /* Check that dimensions are 3 */ 09027 09028 if (kdimc != 3 || kdims != 3) goto err105; 09029 09030 sstart[0] = st1[kk1-1]; 09031 sstart[1] = st2[kk2-1]; 09032 send[0] = st1[kn1]; 09033 send[1] = st2[kn2]; 09034 09035 /* Copy interval description into local variables */ 09036 09037 if (icur ==1) 09038 if ( epar1[0]<epar2[0] ) 09039 { 09040 sfirst[0] = epar1[1]; 09041 sfirst[1] = epar1[2]; 09042 slast[0] = epar2[1]; 09043 slast[1] = epar2[2]; 09044 tfirst = epar1[0]; 09045 tend = epar2[0]; 09046 } 09047 else 09048 { 09049 sfirst[0] = epar2[1]; 09050 sfirst[1] = epar2[2]; 09051 slast[0] = epar1[1]; 09052 slast[1] = epar1[2]; 09053 tfirst = epar2[0]; 09054 tend = epar1[0]; 09055 } 09056 else 09057 if ( epar1[2]<epar2[2] ) 09058 { 09059 sfirst[0] = epar1[0]; 09060 sfirst[1] = epar1[1]; 09061 slast[0] = epar2[0]; 09062 slast[1] = epar2[1]; 09063 tfirst = epar1[2]; 09064 tend = epar2[2]; 09065 } 09066 else 09067 { 09068 sfirst[0] = epar2[0]; 09069 sfirst[1] = epar2[1]; 09070 slast[0] = epar1[0]; 09071 slast[1] = epar1[1]; 09072 tfirst = epar2[2]; 09073 tend = epar1[2]; 09074 } 09075 09076 /* To make sure we do not start outside or end outside the curve we 09077 truncate tstart and tend to the knot interval of the curve */ 09078 09079 tfirst = MAX(tfirst,st[kk-1]); 09080 tend = MIN(tend,st[kn]); 09081 if (DEQUAL(tfirst,tend)) goto out; 09082 09083 /* Set start point of iteration on surface */ 09084 09085 spos[0] = sfirst[0]; 09086 spos[1] = sfirst[1]; 09087 09088 /* Store knot values at start of curve */ 09089 09090 tx2 = tfirst; 09091 kdum = MAX(kk1,kk2); 09092 kdum = MAX(kdum,kk); 09093 tmaxinc = (tend-tfirst)/(kdum*kdum); 09094 09095 /* Make start point of curve */ 09096 09097 s1221(pcurve,kderc,tx2,&kleftc,sderc,&kstat); 09098 if (kstat<0) goto error; 09099 09100 /* Make start point of surface. */ 09101 09102 s1421(psurf,kders,spos,&kleft1,&kleft2,sders,snorm,&kstat); 09103 if (kstat < 0) goto error; 09104 09105 /* While end not reached */ 09106 09107 while (tx2 < tend) 09108 { 09109 /* Save parameters of previous step. */ 09110 09111 tx1 = tx2; 09112 snext[0] = spos[0]; 09113 snext[1] = spos[1]; 09114 kleft1prev = kleft1; 09115 kleft2prev = kleft2; 09116 09117 /* Calculate unit tangent and radius of curvature of curve. */ 09118 09119 s1307(sderc,kdimc,s3dinf1,&kstat); 09120 if (kstat<0) goto error; 09121 09122 /* Calculate step length based on curvature */ 09123 09124 tcstep = s1311(s3dinf1[3*kdimc],aepsge,tsmax,&kstat); 09125 if (kstat<0) goto error; 09126 09127 /* Remember length of start tangent, end of zero segment */ 09128 09129 tlengthend = s6length(sderc+kdimc,kdimc,&kstat); 09130 if (kstat<0) goto error; 09131 09132 /* Compute position, first and second derivative of the curve in the 09133 surface going through the evaluated point in this point. 09134 09135 s1785_s9eval(sders,snorm,sderc+kdimc,sder2,kdims,&kstat); 09136 if (kstat < 0) goto error; 09137 09138 Calculate unit tangent and radius of curvature of curve in surface. 09139 09140 s1307(sder2,kdims,s3dinf2,&kstat); 09141 if (kstat<0) goto error; 09142 09143 Calculate step length based on curvature 09144 09145 tsstep = s1311(s3dinf2[3*kdims],aepsge,tcmax,&kstat); 09146 if (kstat<0) goto error; 09147 09148 Compute minimum step length. 09149 09150 tstep = MIN(tcstep,tsstep); */ 09151 09152 tstep = tcstep; 09153 09154 /* Find candidate end point, make sure that no breaks in tangent or 09155 curvature exists between start and endpoints of the segment */ 09156 09157 /* Make step length equal to resolution if the length is zero */ 09158 09159 /* Find parameter value of candidate end point of segment */ 09160 09161 if (DEQUAL(tlengthend,DZERO)) 09162 tincre = REL_PAR_RES; 09163 else 09164 tincre = tstep/tlengthend; 09165 09166 /* Make sure that we don't pass any knots of the curve. */ 09167 09168 tincre = MIN(tincre,tmaxinc); 09169 tx2 = MIN(tx1 + tincre,st[kleftc+1]); 09170 09171 for (ki=0, tx=(tx1+tx2)/(double)2.0; ki<2; ki++, tx=tx2) 09172 { 09173 if (tx >= tend) break; 09174 09175 /* Make point sderc at curve at tx */ 09176 09177 s1221(pcurve,kderc,tx,&kleftc,sderc,&kstat); 09178 if (kstat<0) goto error; 09179 09180 /* Find closest point on surface to sderc */ 09181 09182 qpoint = newPoint(sderc,kdimc,0); 09183 if (qpoint==SISL_NULL) goto err101; 09184 09185 snext2[0] = snext[0]; 09186 snext2[1] = snext[1]; 09187 s1773(qpoint,psurf,aepsge,sstart,send,snext2,spos,&kstat); 09188 if(kstat<0) goto error; 09189 09190 freePoint(qpoint); qpoint = SISL_NULL; 09191 09192 /* Calculate point and derivatives in surface */ 09193 09194 s1421(psurf,kders,spos,&kleft1,&kleft2,sders,snorm,&kstat); 09195 if (kstat<0) goto error; 09196 09197 /* Check if point on curve and surface are within positional and 09198 angular tolerances */ 09199 09200 tdist = s6dist(sderc,sders,kdimc); 09201 09202 if (tdist>aepsge) 09203 { 09204 /* Points not within tolerances, curve and surface do not 09205 coincide */ 09206 goto war01; 09207 } 09208 09209 /* Check if any parameter lines of the surface is crossed in the 1. 09210 parameter direction. */ 09211 09212 /* changed by Michael Metzger, Feb 1993 */ 09213 /* for (khelp=kleft1prev-1; DEQUAL(st1[khelp],st1[kleft1prev]); khelp--); */ 09214 for (khelp=kleft1prev-1; khelp >= 0 && DEQUAL(st1[khelp],st1[kleft1prev]); khelp--); 09215 if (kleft1 != kleft1prev && 09216 ((DNEQUAL(spos[0]+tref,st1[kleft1]+tref) && 09217 DNEQUAL(snext[0]+tref,st1[kleft1]+tref)) || 09218 kleft1 != kleft1prev+1) && 09219 ((DNEQUAL(snext[0]+tref,st1[kleft1prev]+tref) && 09220 DNEQUAL(spos[0]+tref,st1[kleft1prev]+tref)) || kleft1 != khelp)) 09221 { 09222 /* At least one parameter line is crossed. Fetch the constant parameter 09223 curve at the closest parameter line in the direction of the marching. */ 09224 09225 if (kleft1 > kleft1prev) kpar = kleft1prev + 1; 09226 else if (snext[0] != st1[kleft1prev]) kpar = kleft1prev; 09227 else kpar = khelp; 09228 09229 /* Pick constant parameter curve. */ 09230 09231 s1437(psurf,st1[kpar],&qc,&kstat); 09232 if (kstat < 0) goto error; 09233 09234 /* Find the closest point between the input curve and the constant 09235 parameter curve. */ 09236 09237 s1770(pcurve,qc,aepsge,tx1,st2[kk2-1],tx,st2[kn2],(tx1+tx)/(double)2.0, 09238 st2[kleft2],&tclose1,&tclose2,&kstat); 09239 if (kstat < 0) goto error; 09240 09241 /* Set new parameter values to the iteration. */ 09242 09243 spos[0] = st1[kpar]; 09244 spos[1] = tclose2; 09245 tx2 = tclose1; 09246 09247 /* Test midpoint of reduced step. First evaluate curve in midpoint. */ 09248 09249 tx = (tx1 + tx2)/(double)2.0; 09250 s1221(pcurve,kderc,tx,&kleftc,sderc,&kstat); 09251 if (kstat<0) goto error; 09252 09253 /* Find closest point on surface to sderc */ 09254 09255 qpoint = newPoint(sderc,kdimc,0); 09256 if (qpoint==SISL_NULL) goto err101; 09257 09258 snext2[0] = snext[0]; 09259 snext2[1] = snext[1]; 09260 s1773(qpoint,psurf,aepsge,sstart,send,snext2,snext2,&kstat); 09261 if(kstat<0) goto error; 09262 09263 freePoint(qpoint); qpoint = SISL_NULL; 09264 09265 /* Calculate point and derivatives in surface */ 09266 09267 s1421(psurf,kders,snext2,&kleft1,&kleft2,sders,snorm,&kstat); 09268 if (kstat<0) goto error; 09269 09270 /* Check if point on curve and surface are within positional and 09271 angular tolerances */ 09272 09273 tdist = s6dist(sderc,sders,kdimc); 09274 09275 if (tdist>aepsge) 09276 { 09277 /* Points not within tolerances, curve and surface do not 09278 coincide */ 09279 goto war01; 09280 } 09281 09282 /* Calculate point and derivatives in the curve in the endpoint of the step. */ 09283 09284 s1221(pcurve,kderc,tx2,&kleftc,sderc,&kstat); 09285 if (kstat<0) goto error; 09286 09287 /* Calculate point and derivatives in the surface. */ 09288 09289 s1421(psurf,kders,spos,&kleft1,&kleft2,sders,snorm,&kstat); 09290 if (kstat<0) goto error; 09291 09292 /* Check if point on curve and surface are within positional and 09293 angular tolerances */ 09294 09295 tdist = s6dist(sderc,sders,kdimc); 09296 09297 if (tdist>aepsge) 09298 { 09299 /* Points not within tolerances, curve and surface do not 09300 coincide */ 09301 goto war01; 09302 } 09303 09304 /* Mark that a new step is to be initiated. */ 09305 09306 ki = 2; 09307 09308 /* Free constant parameter curve. */ 09309 09310 if (qc != SISL_NULL) freeCurve(qc); qc = SISL_NULL; 09311 } 09312 09313 /* Check if any parameter lines of the surface is crossed in the 2. 09314 parameter direction. */ 09315 09316 /* changed by Michael Metzger, Feb 1993 */ 09317 /* for (khelp=kleft2prev-1; DEQUAL(st2[khelp],st2[kleft2prev]); khelp--); */ 09318 for (khelp=kleft2prev-1; khelp >= 0 && DEQUAL(st2[khelp],st2[kleft2prev]); khelp--); 09319 if (kleft2 != kleft2prev && 09320 ((DNEQUAL(spos[1]+tref,st2[kleft2]+tref) && 09321 DNEQUAL(snext[1]+tref,st2[kleft2]+tref)) || 09322 kleft2 != kleft2prev+1) && 09323 ((DNEQUAL(snext[1]+tref,st2[kleft2prev]+tref) && 09324 DNEQUAL(spos[1]+tref,st2[kleft2prev]+tref)) || 09325 kleft2 != khelp)) 09326 { 09327 /* At least one parameter line is crossed. Fetch the constant parameter 09328 curve at the closest parameter line in the direction of the marching. */ 09329 09330 if (kleft2 > kleft2prev) kpar = kleft2prev + 1; 09331 else if (snext[1] != st2[kleft2prev]) kpar = kleft2prev; 09332 else kpar = khelp; 09333 09334 /* Pick constant parameter curve. */ 09335 09336 s1436(psurf,st2[kpar],&qc,&kstat); 09337 if (kstat < 0) goto error; 09338 09339 /* Find the closest point between the input curve and the constant 09340 parameter curve. */ 09341 09342 s1770(pcurve,qc,aepsge,tx1,st1[kk1-1],tx,st1[kn1],(tx1+tx)/(double)2.0, 09343 st1[kleft1],&tclose1,&tclose2,&kstat); 09344 if (kstat < 0) goto error; 09345 09346 /* Set new parameter values to the iteration. */ 09347 09348 spos[0] = tclose2; 09349 spos[1] = st2[kpar]; 09350 tx2 = tclose1; 09351 09352 /* Test midpoint of reduced step. First evaluate curve in midpoint. */ 09353 09354 tx = (tx1 + tx2)/(double)2.0; 09355 s1221(pcurve,kderc,tx,&kleftc,sderc,&kstat); 09356 if (kstat<0) goto error; 09357 09358 /* Find closest point on surface to sderc */ 09359 09360 qpoint = newPoint(sderc,kdimc,0); 09361 if (qpoint==SISL_NULL) goto err101; 09362 09363 snext2[0] = snext[0]; 09364 snext2[1] = snext[1]; 09365 s1773(qpoint,psurf,aepsge,sstart,send,snext2,snext2,&kstat); 09366 if(kstat<0) goto error; 09367 09368 freePoint(qpoint); qpoint = SISL_NULL; 09369 09370 /* Calculate point and derivatives in surface */ 09371 09372 s1421(psurf,kders,snext2,&kleft1,&kleft2,sders,snorm,&kstat); 09373 if (kstat<0) goto error; 09374 09375 /* Check if point on curve and surface are within positional and 09376 angular tolerances */ 09377 09378 tdist = s6dist(sderc,sders,kdimc); 09379 09380 if (tdist>aepsge) 09381 { 09382 /* Points not within tolerances, curve and surface do not 09383 coincide */ 09384 goto war01; 09385 } 09386 09387 /* Calculate point and derivatives in the curve. */ 09388 09389 s1221(pcurve,kderc,tx2,&kleftc,sderc,&kstat); 09390 if (kstat<0) goto error; 09391 09392 /* Calculate point and derivatives in the surface. */ 09393 09394 s1421(psurf,kders,spos,&kleft1,&kleft2,sders,snorm,&kstat); 09395 if (kstat<0) goto error; 09396 09397 /* Check if point on curve and surface are within positional and 09398 angular tolerances */ 09399 09400 tdist = s6dist(sderc,sders,kdimc); 09401 09402 if (tdist>aepsge) 09403 { 09404 /* Points not within tolerances, curve and surface do not 09405 coincide */ 09406 goto war01; 09407 } 09408 09409 /* Mark that a new step is to be initiated. */ 09410 09411 ki = 2; 09412 09413 /* Free constant parameter curve. */ 09414 09415 if (qc != SISL_NULL) freeCurve(qc); qc = SISL_NULL; 09416 } 09417 } 09418 } 09419 09420 /* Curves within tolerance. Test on whether the start- and 09421 endpoint of the curve are identical. */ 09422 09423 *jstat = (DEQUAL(tfirst,tend)) ? 0 : 1; 09424 goto out; 09425 09426 /* Curve and surface not within tolerance */ 09427 war01: *jstat = 0; 09428 goto out; 09429 09430 /* Error in memory allocation */ 09431 09432 err101: *jstat = -101; 09433 s6err("S1785",*jstat,kpos); 09434 goto out; 09435 09436 /* Error in input, dimension not equal to 2 or 3 */ 09437 09438 err105: *jstat = -105; 09439 s6err("S1785",*jstat,kpos); 09440 goto out; 09441 09442 /* Error in lower level function */ 09443 09444 error: *jstat = kstat; 09445 s6err("S1785",*jstat,kpos); 09446 goto out; 09447 09448 09449 out: 09450 09451 return; 09452 } 09453 09454 09455 //=========================================================================== 09456 void s1880(int ipar1,int ipar2,int *jpt,SISLIntpt **vpoint,int *jlist, 09457 SISLIntlist **vlist,int *jpar,double **gpar1,double **gpar2, 09458 int *jcrv,SISLIntcurve ***wcrv,int *jstat) 09459 //=========================================================================== 09460 { 09461 int kpos = 0; /* Position of error. */ 09462 int ki,kj,kk; /* Counters. */ 09463 int kpoint; /* Number of points in an intersection list. */ 09464 int klst; /* Kind of intersection list. (See SISLIntlist). */ 09465 int ktype; /* Kind of intersection curve. (See SISLIntcurve). */ 09466 int kpt; /* Used to find number of single intersection points.*/ 09467 double *spar1,*spar2; /* Values of points belonging to an intersection 09468 curve in the parameter area of the objects 09469 involved in the intersection. */ 09470 double *stpar1,*stpar2,*stpar3; /* Pointers used to travers arrays 09471 containing parameter values. */ 09472 SISLIntcurve **ucrv; /* Pointer used to traverse *wcrv array. */ 09473 SISLIntlist **ulst; /* Pointer used to traverse vlist array. */ 09474 SISLIntpt *qpt; /* Pointer to an intersection point. */ 09475 SISLIntpt **upt; /* Pointer used to travers vpoint array. */ 09476 09477 /* Initiate output arrays. */ 09478 09479 *gpar1 = *gpar2 = SISL_NULL; *wcrv = SISL_NULL; 09480 09481 /* Allocate space for intersection curve array. */ 09482 09483 *jcrv = *jlist; 09484 *wcrv = newarray(*jlist,SISLIntcurve*); 09485 if ((*jcrv) > 0 && *wcrv == SISL_NULL) goto err101; 09486 09487 /* Transfer curve-information from vlist array to wcrv array. */ 09488 09489 ucrv = *wcrv; 09490 ulst = vlist; 09491 kpt = 0; 09492 for (ki=0; ki<(*jlist); ki++) 09493 { 09494 qpt = (*ulst) -> pfirst; 09495 09496 /* Allocate space for arrays containing parameter vlaues of points 09497 in intersection curves. */ 09498 09499 kpoint = (*ulst) -> inumb; 09500 if (kpoint == 0) goto err137; 09501 spar1 = newarray(ipar1*kpoint,double); 09502 spar2 = newarray(ipar2*kpoint,double); 09503 if ((ipar1 > 0 && spar1 == SISL_NULL) || 09504 (ipar2 > 0 && spar2 == SISL_NULL)) goto err101; 09505 09506 /* Collect parameter values of the points in this intersection list 09507 and distribute values to the objects in the intersection. */ 09508 09509 kj = 0; 09510 stpar1 = spar1; 09511 stpar2 = spar2; 09512 while (qpt != SISL_NULL && qpt -> ipar != -1) 09513 { 09514 stpar3 = qpt -> epar; 09515 for (kk=0; kk<ipar1; kk++) *(stpar1++) = *(stpar3++); 09516 for (kk=0; kk<ipar2; kk++) *(stpar2++) = *(stpar3++); 09517 qpt -> ipar = -1; 09518 qpt = qpt -> pcurve; 09519 kj++; 09520 } 09521 09522 /* Find kind of intersection curve. */ 09523 09524 klst = (*ulst) -> itype; 09525 if (klst == 0) ktype = 4; 09526 else if (klst == 1) ktype = 2; 09527 else if (klst == 2) ktype = 5; 09528 else if (klst == 3) ktype = 6; 09529 else if (klst == 4) ktype = 7; 09530 else if (klst == 5) ktype = 8; 09531 else goto err146; 09532 09533 /* Create new intersection curve. */ 09534 09535 *ucrv = newIntcurve(kj,ipar1,ipar2,spar1,spar2,ktype); 09536 if (*ucrv == SISL_NULL) goto err101; 09537 09538 kpt += kj; 09539 ucrv++; 09540 ulst++; 09541 } 09542 09543 /* Find number of single intersection points. */ 09544 09545 kpt = *jpt - kpt; 09546 09547 /* Create arrays to keep parameter values of intersection points. */ 09548 09549 *gpar1 = newarray(ipar1*kpt,double); 09550 *gpar2 = newarray(ipar2*kpt,double); 09551 if ((ipar1*kpt > 0 && *gpar1 == SISL_NULL) 09552 || (ipar2*kpt > 0 && *gpar2 == SISL_NULL)) goto err101; 09553 09554 /* Copy parameters of single intersection points into output-arrays. */ 09555 09556 kj = 0; 09557 upt = vpoint; 09558 stpar1 = *gpar1; 09559 stpar2 = *gpar2; 09560 for (ki=0; ki<(*jpt); ki++) 09561 { 09562 qpt = *upt; 09563 if (qpt != SISL_NULL) 09564 { 09565 if (qpt -> ipar != -1) 09566 { 09567 kj++; 09568 stpar3 = qpt -> epar; 09569 for (kk=0; kk<ipar1; kk++) *(stpar1++) = *(stpar3++); 09570 for (kk=0; kk<ipar2; kk++) *(stpar2++) = *(stpar3++); 09571 } 09572 09573 /* Free space occupied by current intersection point. */ 09574 09575 freeIntpt(qpt); 09576 } 09577 09578 upt++; 09579 } 09580 09581 *jpar = kj; 09582 09583 /* Adjust output arrays to correct length. */ 09584 09585 if (kj*ipar1 > 0) 09586 { 09587 if ((*gpar1 = increasearray(*gpar1,kj*ipar1,double)) == SISL_NULL) goto err101; 09588 } 09589 else 09590 { 09591 if (*gpar1 != SISL_NULL) freearray(*gpar1); 09592 *gpar1 = SISL_NULL; 09593 } 09594 if (kj*ipar2 > 0) 09595 { 09596 if ((*gpar2 = increasearray(*gpar2,kj*ipar2,double)) == SISL_NULL) goto err101; 09597 } 09598 else 09599 { 09600 if (*gpar2 != SISL_NULL) freearray(*gpar2); 09601 *gpar2 = SISL_NULL; 09602 } 09603 09604 /* Intersections copied to output format. */ 09605 09606 *jpt = 0; 09607 *jstat = 0; 09608 goto out; 09609 09610 /* Error in space allocation. */ 09611 09612 err101: *jstat = -101; 09613 s6err("s1880",*jstat,kpos); 09614 goto out; 09615 09616 /* Error in data-strucuture. Expected intersection point not found. */ 09617 09618 err137: *jstat = -137; 09619 s6err("s1880",*jstat,kpos); 09620 goto out; 09621 09622 /* Unknown kind of intersection type. */ 09623 09624 err146: *jstat = -146; 09625 s6err("s1880",*jstat,kpos); 09626 goto out; 09627 09628 out: return; 09629 } 09630 09631 09632 09633 //=========================================================================== 09634 SISLIntlist *newIntlist (SISLIntpt * pfirst, SISLIntpt * plast, int itype) 09635 //=========================================================================== 09636 { 09637 SISLIntlist *pnew; /* Local pointer to this instance. */ 09638 09639 /* Allocate space for the instance. */ 09640 09641 pnew = newarray (1, SISLIntlist); 09642 if (pnew == SISL_NULL) 09643 goto err101; 09644 09645 /* Initialize. */ 09646 09647 pnew->pfirst = pfirst; 09648 pnew->plast = plast; 09649 pnew->itype = itype; 09650 pnew->inumb = 2; 09651 09652 /* Tast done. */ 09653 09654 goto out; 09655 09656 /* Error in space allocation. Return zero. */ 09657 09658 err101:pnew = SISL_NULL; 09659 goto out; 09660 09661 out:return (pnew); 09662 } 09663 09664 09665 //=========================================================================== 09666 void s6decomp(double ea[],double gx[],double eb1[],double eb2[], 09667 double eb3[],int *jstat) 09668 //=========================================================================== 09669 { 09670 int kstat =0; /* Local status variable. */ 09671 int ki; /* Counter. */ 09672 int n1[3]; /* Array for use in lufac. */ 09673 double sc[9],se[3]; /* Matrix and help vector. */ 09674 09675 09676 /* Copy new bases into local matrix. */ 09677 09678 memcopy(sc,eb1,3,double); 09679 memcopy(sc+3,eb2,3,double); 09680 memcopy(sc+6,eb3,3,double); 09681 09682 09683 s6lufacp(sc,n1,3,&kstat); 09684 if (kstat < 0) goto error; 09685 else if (kstat > 0) goto warn1; 09686 09687 for (ki=0; ki<3; ki++) 09688 { 09689 se[0] = se[1] = se[2] = DZERO; 09690 se[ki] = (double)1; 09691 09692 s6lusolp(sc,se,n1,3,&kstat); 09693 if (kstat < 0) goto error; 09694 else if (kstat > 0) goto warn1; 09695 09696 gx[ki] = s6scpr(ea,se,3); 09697 } 09698 09699 /* Change of bases performed. */ 09700 09701 *jstat = 0; 09702 goto out; 09703 09704 /* Singular equation system. */ 09705 09706 warn1 : *jstat = 1; 09707 goto out; 09708 09709 /* Error in subrutines. */ 09710 09711 error: *jstat = kstat; 09712 s6err("s6decomp",*jstat,0); 09713 goto out; 09714 09715 out: ; 09716 } 09717 09718 09719 //=========================================================================== 09720 void s1788(SISLSurf *ps1,SISLSurf *ps2,double aepsge,double epar[], 09721 double gpar1[],double gpar2[],int *jstat) 09722 //=========================================================================== 09723 { 09724 int kpos=0; /* Position of error */ 09725 int kk1,kk2,kn1,kn2; /* Orders and numbers of vertices */ 09726 int kstat; /* Status variable */ 09727 int kmark1,kmark2,kclose,kmatch1,kmatch2; /* Flags */ 09728 int kcur,kgraph; /* Indicators telling to control type of output 09729 from marching */ 09730 double sval1[2]; /* Limits of parameter plane in first SISLdir */ 09731 double sval2[2]; /* Limits of parameter plane in second SISLdir */ 09732 double sval3[2]; /* Limits of parameter plane in third SISLdir */ 09733 double sval4[2]; /* Limits of parameter plane in fourth SISLdir */ 09734 double *st1,*st2; /* Knots and vertices of input surface */ 09735 double tmax; /* Box size */ 09736 double tepsge; 09737 double *spar11,*spar12;/* Pointers to arrays */ 09738 double *spar21,*spar22;/* Pointers to arrays */ 09739 09740 /* UJK, Nov 1990 */ 09741 /* double *spar=SISL_NULL; */ 09742 double *spar1=SISL_NULL; /* Pointer to allocated values for parameter values*/ 09743 double *spar2=SISL_NULL; /* Pointer to allocated values for parameter values*/ 09744 09745 SISLCurve *qcrv; /* Curve in parameter plane */ 09746 SISLIntcurve *qintcr=SISL_NULL; /* Intersection curve object */ 09747 09748 /* Find limits of parameter plane */ 09749 09750 kk1 = ps1 -> ik1; 09751 kk2 = ps1 -> ik2; 09752 kn1 = ps1 -> in1; 09753 kn2 = ps1 -> in2; 09754 st1 = ps1 -> et1; 09755 st2 = ps1 -> et2; 09756 sval1[0] = st1[kk1-1]; 09757 sval1[1] = st1[kn1]; 09758 sval2[0] = st2[kk2-1]; 09759 sval2[1] = st2[kn2]; 09760 09761 kk1 = ps2 -> ik1; 09762 kk2 = ps2 -> ik2; 09763 kn1 = ps2 -> in1; 09764 kn2 = ps2 -> in2; 09765 st1 = ps2 -> et1; 09766 st2 = ps2 -> et2; 09767 sval3[0] = st1[kk1-1]; 09768 sval3[1] = st1[kn1]; 09769 sval4[0] = st2[kk2-1]; 09770 sval4[1] = st2[kn2]; 09771 09772 09773 /* Make maximal step length based on box-size of surface */ 09774 09775 sh1992su(ps1,0,aepsge,&kstat); 09776 if (kstat < 0) goto error; 09777 09778 tmax = MAX(ps1->pbox->e2max[0][0] - ps1->pbox->e2min[0][0], 09779 ps1->pbox->e2max[0][1] - ps1->pbox->e2min[0][1]); 09780 tmax = MAX(tmax,ps1->pbox->e2max[0][2] - ps1->pbox->e2min[0][2]); 09781 09782 sh1992su(ps2,0,aepsge,&kstat); 09783 if (kstat < 0) goto error; 09784 09785 tmax = MAX(tmax,ps2->pbox->e2max[0][0] - ps2->pbox->e2min[0][0]); 09786 tmax = MAX(tmax,ps2->pbox->e2max[0][1] - ps2->pbox->e2min[0][1]); 09787 tmax = MAX(tmax,ps2->pbox->e2max[0][2] - ps2->pbox->e2min[0][2]); 09788 09789 tepsge = tmax * (double)0.01; 09790 09791 09792 kgraph = 0; 09793 kcur = 3; 09794 09795 /* Make an intersection curve object with the parameter value */ 09796 /* UJK, Nov 1990 */ 09797 /* if ((spar=newarray(4,DOUBLE))==SISL_NULL) goto err101; 09798 memcopy(spar,epar,4,DOUBLE); */ 09799 if ((spar1=newarray(2,DOUBLE))==SISL_NULL) goto err101; 09800 memcopy(spar1,epar,2,DOUBLE); 09801 if ((spar2=newarray(2,DOUBLE))==SISL_NULL) goto err101; 09802 memcopy(spar2,epar+2,2,DOUBLE); 09803 09804 /* UJK, Nov 1990 */ 09805 /* if((qintcr = newIntcurve(1,2,2,epar,epar+2,0)) == SISL_NULL) goto err101; */ 09806 if((qintcr = newIntcurve(1,2,2,spar1,spar2,0)) == SISL_NULL) goto err101; 09807 09808 kcur = 2; 09809 kgraph = 0; 09810 tmax = (double)0.0; 09811 09812 09813 s1310(ps1,ps2,qintcr,tepsge,tmax,kcur,kgraph,&kstat); 09814 09815 if (kstat==-185) goto war00; 09816 if (kstat<0) goto error; 09817 09818 /* Identify first and last parameter pair in the intersection curve */ 09819 09820 qcrv = qintcr -> ppar1; 09821 if (qcrv == SISL_NULL) goto war00; 09822 09823 spar11 = qcrv -> ecoef; 09824 spar21 = spar11 + 2*(qcrv->in)-2; 09825 09826 09827 qcrv = qintcr -> ppar2; 09828 if (qcrv == SISL_NULL) goto war00; 09829 09830 spar12 = qcrv -> ecoef; 09831 spar22 = spar12 + 2*(qcrv->in)-2; 09832 09833 /* Check if any of the points lie on the boundary */ 09834 09835 kmark1 = 0; 09836 if (spar11[0] == sval1[0] || spar11[0] == sval1[1] || 09837 spar11[1] == sval2[0] || spar11[1] == sval2[1] || 09838 spar12[0] == sval3[0] || spar12[0] == sval3[1] || 09839 spar12[1] == sval4[0] || spar12[1] == sval4[1] ) kmark1 = 1; 09840 09841 kmark2 = 0; 09842 if (spar21[0] == sval1[0] || spar21[0] == sval1[1] || 09843 spar21[1] == sval2[0] || spar21[1] == sval2[1] || 09844 spar22[0] == sval3[0] || spar22[0] == sval3[1] || 09845 spar22[1] == sval4[0] || spar22[1] == sval4[1] ) kmark2 = 1; 09846 09847 09848 /* Check if closed */ 09849 09850 kclose = 0; 09851 if (spar11[0] == spar21[0] && spar11[1] == spar21[1] && 09852 spar12[0] == spar22[0] && spar12[1] == spar22[1] ) kclose = 1; 09853 09854 /* Check if first points matches start point */ 09855 09856 kmatch1 = 0; 09857 if (DEQUAL(epar[0],spar11[0]) && DEQUAL(epar[1],spar11[1]) && 09858 DEQUAL(epar[2],spar12[0]) && DEQUAL(epar[3],spar12[1]) ) kmatch1 = 1; 09859 09860 /* Check if second points matches start point */ 09861 09862 kmatch2 = 0; 09863 if (DEQUAL(epar[0],spar21[0]) && DEQUAL(epar[1],spar21[1]) && 09864 DEQUAL(epar[2],spar22[0]) && DEQUAL(epar[3],spar22[1]) ) kmatch2 = 1; 09865 09866 09867 /* Check if any point matches start point */ 09868 09869 if (kmatch1 == 1 || kmatch2 == 1) 09870 { 09871 /* Start point matches one of the end points, status values in 09872 the range 11-19*/ 09873 09874 if (kmark1 == 1 && kmark2 == 1 && kclose == 0) 09875 { 09876 /* Open curve, status 11 */ 09877 *jstat = 11; 09878 if(kmatch1==1) 09879 goto copy; 09880 else 09881 goto invcopy; 09882 } 09883 else if (kmark1 ==1 || (kmark2 == 1 && kclose == 0)) 09884 { 09885 /* Open curve one point inside status 12 or 13 */ 09886 09887 if (kmark1 == 1 && kmatch1 == 1) 09888 { 09889 *jstat = 12; 09890 goto copy; 09891 } 09892 else if (kmark2 == 1 && kmatch2 == 1) 09893 { 09894 *jstat = 12; 09895 goto invcopy; 09896 } 09897 if (kmark1 == 1 && kmatch2 == 1) 09898 { 09899 *jstat = 13; 09900 goto invcopy; 09901 } 09902 if (kmark2 == 1 && kmatch1 == 1) 09903 { 09904 *jstat = 13; 09905 goto copy; 09906 } 09907 } 09908 else if (kclose == 0) 09909 { 09910 /* Both ends inside */ 09911 *jstat = 14; 09912 if(kmatch1==1) 09913 goto copy; 09914 else 09915 goto invcopy; 09916 } 09917 else if(kmatch1 == 1) 09918 { 09919 /* Closed curve, no singularity */ 09920 *jstat = 16; 09921 memcopy(gpar1, spar11,2,DOUBLE); 09922 memcopy(gpar1+2,spar12,2,DOUBLE); 09923 memcopy(gpar2, gpar1, 4,DOUBLE); 09924 goto out; 09925 } 09926 else 09927 { 09928 /* Closed curve, with singularity */ 09929 *jstat=17; 09930 memcopy(gpar1, epar, 4,DOUBLE); 09931 memcopy(gpar2, spar11,2,DOUBLE); 09932 memcopy(gpar2+2,spar12,2,DOUBLE); 09933 goto out; 09934 } 09935 } 09936 else 09937 { 09938 /* epar does not match produced end points, status messages in 09939 21-29 the range */ 09940 09941 if (kmark1 ==1 && kmark2 ==1 && kclose == 0) 09942 { 09943 /* Open curve, status 11 */ 09944 *jstat = 21; 09945 goto copy; 09946 } 09947 else if (kmark1 ==1 && kclose == 0) 09948 { 09949 /* Open curve one point inside status 12 */ 09950 *jstat=22; 09951 goto copy; 09952 } 09953 else if (kmark2 ==1 && kclose == 0) 09954 { 09955 /* Open curve one point inside status 12 */ 09956 *jstat=22; 09957 goto invcopy; 09958 } 09959 else if (kclose == 0) 09960 { 09961 /* Both ends inside */ 09962 *jstat=24; 09963 goto copy; 09964 } 09965 else if(kmatch1 == 1) 09966 { 09967 /* Closed curve, no singularity */ 09968 *jstat=26; 09969 memcopy(gpar1, spar11,2,DOUBLE); 09970 memcopy(gpar1+2,spar12,2,DOUBLE); 09971 memcopy(gpar2, gpar1, 4,DOUBLE); 09972 } 09973 else 09974 { 09975 /* Closed curve, with singularity */ 09976 *jstat = 27; 09977 memcopy(gpar1, epar, 4,DOUBLE); 09978 memcopy(gpar2 ,spar11,2,DOUBLE); 09979 memcopy(gpar2+2,spar12,2,DOUBLE); 09980 goto out; 09981 } 09982 } 09983 09984 /* Marching produced no curve */ 09985 09986 war00: 09987 *jstat = 0; 09988 memcopy(gpar1,epar,4,DOUBLE); 09989 memcopy(gpar2,epar,4,DOUBLE); 09990 goto out; 09991 09992 copy: 09993 memcopy(gpar1, spar11,2,DOUBLE); 09994 memcopy(gpar1+2,spar12,2,DOUBLE); 09995 memcopy(gpar2, spar21,2,DOUBLE); 09996 memcopy(gpar2+2,spar22,2,DOUBLE); 09997 goto out; 09998 09999 invcopy: 10000 memcopy(gpar1, spar21,2,DOUBLE); 10001 memcopy(gpar1+2,spar22,2,DOUBLE); 10002 memcopy(gpar2, spar11,2,DOUBLE); 10003 memcopy(gpar2+2,spar12,2,DOUBLE); 10004 goto out; 10005 10006 /* Error in space allocation */ 10007 err101: 10008 *jstat = -101; 10009 s6err("s1788",*jstat,kpos); 10010 goto out; 10011 10012 /* Error in lower level function */ 10013 error: 10014 *jstat = kstat; 10015 s6err("s1788",*jstat,kpos); 10016 goto out; 10017 10018 out: 10019 if (qintcr != SISL_NULL) freeIntcurve(qintcr); 10020 } 10021 10022 10023 //=========================================================================== 10024 void freeIntlist(SISLIntlist *plist) 10025 //=========================================================================== 10026 { 10027 /* Free space. */ 10028 10029 freearray(plist); 10030 10031 return; 10032 } 10033 10034 //=========================================================================== 10035 void s6idklist(SISLIntdat **pintdat,SISLIntlist *pintlist,int *jstat) 10036 //=========================================================================== 10037 { 10038 SISLIntpt *qkillpt,*qnext,*qdum1,*qdum2; 10039 10040 int ki,knum,kstat; 10041 10042 *jstat = 0; 10043 10044 /* We have to be sure that we have an intdat structure. */ 10045 10046 if ((*pintdat) == SISL_NULL) 10047 goto out; 10048 10049 if (pintlist == SISL_NULL) 10050 { 10051 *jstat = 1; 10052 goto out; 10053 } 10054 10055 /* Now we have to find the index in the vlist array in pintdat. */ 10056 10057 10058 for (ki=0,knum = -1; ki < (*pintdat)->ilist; ki++) 10059 if ((*pintdat)->vlist[ki] == pintlist) 10060 { 10061 knum = ki; 10062 break; 10063 } 10064 10065 if (knum == -1) 10066 /* Not in the pintdat list. */ 10067 *jstat = 1; 10068 else 10069 { 10070 pintlist->plast->pcurve = SISL_NULL; 10071 10072 /* Kill all points in the list. */ 10073 for (ki=0,qkillpt=pintlist->pfirst,qnext=qkillpt->pcurve; 10074 qnext!=SISL_NULL; 10075 qkillpt=qnext,qnext=qnext->pcurve) 10076 { 10077 s6idkpt(pintdat,&qkillpt,&qdum1,&qdum2,&kstat); 10078 if (kstat < 0) goto error; 10079 } 10080 s6idkpt(pintdat,&qkillpt,&qdum1,&qdum2,&kstat); 10081 if (kstat < 0) goto error; 10082 10083 /* Update pintdat. */ 10084 if ((*pintdat) != SISL_NULL) 10085 { 10086 (*pintdat)->vlist[knum] = (*pintdat)->vlist[(*pintdat)->ilist-1]; 10087 ((*pintdat)->ilist)--; 10088 (*pintdat)->vlist[(*pintdat)->ilist] = SISL_NULL; 10089 } 10090 freeIntlist(pintlist); 10091 } 10092 10093 goto out; 10094 10095 error : *jstat = kstat; 10096 s6err("s6idklist",*jstat,0); 10097 goto out; 10098 10099 out: ; 10100 } 10101 10102 10103 //=========================================================================== 10104 SISLIntcurve *newIntcurve (int ipoint, int ipar1, int ipar2, 10105 double *epar1, double *epar2, int itype) 10106 //=========================================================================== 10107 { 10108 SISLIntcurve *qnew; 10109 10110 /* Allocate space for the new Intcurve. */ 10111 10112 qnew = newarray (1, SISLIntcurve); 10113 if (qnew == SISL_NULL) 10114 goto err101; 10115 10116 /* Set variables of the intersection curve. */ 10117 10118 qnew->ipoint = ipoint; 10119 qnew->ipar1 = ipar1; 10120 qnew->ipar2 = ipar2; 10121 qnew->epar1 = epar1; 10122 qnew->epar2 = epar2; 10123 qnew->pgeom = SISL_NULL; 10124 qnew->ppar1 = SISL_NULL; 10125 qnew->ppar2 = SISL_NULL; 10126 qnew->itype = itype; 10127 10128 /* Task done. */ 10129 10130 goto out; 10131 10132 /* Error in space allocation. Return zero. */ 10133 10134 err101:qnew = SISL_NULL; 10135 goto out; 10136 10137 out:return (qnew); 10138 } 10139 10140 10141 //=========================================================================== 10142 void s1787(SISLSurf *ps,double alevel,double aepsge,double epar[], 10143 double gpar1[],double gpar2[],int *jstat) 10144 //=========================================================================== 10145 { 10146 int kdeg=1; /* Indicate that a plane is used */ 10147 int kk1,kk2,kn1,kn2; /* Orders and numbers of vertices */ 10148 int kstat; /* Status variable */ 10149 int kkm1,kkm2; /* Orders minus 1 */ 10150 int kincre; /* Number of doubles in first vertex direction */ 10151 int kpos=0; /* Position of error */ 10152 int ki,kj,kl,kstop; 10153 int kcur,kgraph; /* Indicators telling to control type of output 10154 from marching */ 10155 int kmark1,kmark2,kclose,kmatch1,kmatch2; /* Flags */ 10156 double tmax; /* Box size */ 10157 double tstart,tlength;/* Variables used in Marsdens identity */ 10158 double tfak; 10159 double tdum1; /* Max knot value used in DEQUAL comparing. */ 10160 double tdum2; /* Max knot value used in DEQUAL comparing. */ 10161 double tsum,*sp,*sq; 10162 double simpli[4]; /* Description of plane */ 10163 double *st1,*st2,*scoef; /* Knots and vertices of input surface */ 10164 double *s3coef=SISL_NULL; /* 3-D coeff */ 10165 10166 double tepsco = REL_COMP_RES; 10167 double tepsge; 10168 double sval1[2]; /* Limits of parameter plane in first SISLdir */ 10169 double sval2[2]; /* Limits of parameter plane in second SISLdir */ 10170 double *spar1,*spar2; /* Pointers to arrays */ 10171 double *spar=SISL_NULL; /* Pointer to allocated values for parameter values*/ 10172 SISLSurf *qs=SISL_NULL; /* 3-D version of surface */ 10173 SISLCurve *qcrv; /* Curve in parameter plane */ 10174 SISLIntcurve *qintcr=SISL_NULL;/* Intersection curve object */ 10175 kk1 = ps -> ik1; 10176 kk2 = ps -> ik2; 10177 kn1 = ps -> in1; 10178 kn2 = ps -> in2; 10179 st1 = ps -> et1; 10180 st2 = ps -> et2; 10181 scoef = ps -> ecoef; 10182 sval1[0] = st1[kk1-1]; 10183 sval1[1] = st1[kn1]; 10184 sval2[0] = st2[kk2-1]; 10185 sval2[1] = st2[kn2]; 10186 10187 /* Allocate array for 3-D representation of surface */ 10188 10189 if((s3coef = newarray(kn1*kn2*3,DOUBLE)) == SISL_NULL) goto err101; 10190 10191 sh1992su(ps,0,aepsge,&kstat); 10192 if (kstat < 0) goto error; 10193 10194 tmax = ps->pbox->e2max[0][0] - ps->pbox->e2min[0][0]; 10195 10196 /* Make description of plane */ 10197 10198 simpli[0] = (double)0.0; 10199 simpli[1] = (double)0.0; 10200 simpli[2] = (double)1.0; 10201 simpli[3] = -alevel; 10202 10203 /* Make 3-D description of the surface */ 10204 10205 10206 /* Make representation of coefficients from Marsdens identity for the 10207 * function f(t) = t, with the knot vector in first parameter direction 10208 * scaled to [0,tmax]. This will be used as the x-coordinate in the 3-D 10209 * representation */ 10210 10211 tstart = st1[kk1-1]; 10212 tlength = st1[kn1] - tstart; 10213 tfak = tmax/tlength; 10214 kkm1 = kk1 - 1; 10215 kincre = 3*kn1; 10216 10217 for (ki=0,kl=0,sp=s3coef ; ki<kn1 ; ki++,kl+=3,sp+=3) 10218 { 10219 tsum = (double)0.0; 10220 kstop = ki+kk1; 10221 for (kj=ki+1;kj<kstop;kj++) 10222 tsum +=st1[kj]; 10223 10224 tsum = (tsum/kkm1-tstart)*tfak; 10225 10226 10227 /* Copy x-coordinate to the other vertex rows */ 10228 /*UJK,changed from kj<kn to kj<kn2.*/ 10229 for (kj=0,sq=sp ; kj<kn2 ; kj++,sq+=kincre) *sq = tsum; 10230 10231 } 10232 10233 /* Make representation of coefficients from Marsdens identity for the 10234 * function f(t) = t, with the knot vector in second parameter direction 10235 * scaled to [0,tfak]. This will be used as the x-coordinate in the 3-D 10236 * representation */ 10237 10238 kkm2 = kk2 - 1; 10239 tstart = st2[kk2-1]; 10240 tlength = st2[kn2] - tstart; 10241 tfak = tmax/tlength; 10242 for (ki=0,sp=s3coef+1 ; ki< kn2 ; ki++) 10243 { 10244 tsum = (double)0.0; 10245 kstop = ki+kk2; 10246 for (kj=ki+1;kj<kstop;kj++) 10247 tsum +=st2[kj]; 10248 10249 tsum = (tsum/kkm2-tstart)*tfak; 10250 10251 /* Copy to remaining y-coordinates in first vertex row */ 10252 10253 for (kj=0 ; kj<kn1 ; kj++,sp+=3) *sp = tsum; 10254 10255 } 10256 10257 /* Copy z-coordinates */ 10258 10259 for (kj=0,sp=s3coef+2,sq=scoef ; kj < kn2 ; kj++) 10260 for (ki=0 ; ki<kn1 ; ki++,sp+=3,sq++) 10261 *sp = *sq; 10262 10263 /* Make 3-D surface */ 10264 10265 if((qs = newSurf(kn1,kn2,kk1,kk2,st1,st2,s3coef,1,3,1)) == SISL_NULL) goto err101; 10266 10267 kgraph = 0; 10268 kcur = 3; 10269 10270 /* Make an intersection curve object with the parameter value */ 10271 10272 if ((spar=newarray(2,DOUBLE))==SISL_NULL) goto err101; 10273 memcopy(spar,epar,2,DOUBLE); 10274 10275 if((qintcr = newIntcurve(1,2,0,spar,SISL_NULL,0)) == SISL_NULL) goto err101; 10276 10277 kcur = 2; 10278 kgraph = 0; 10279 tepsge = tmax*(double)0.01; 10280 s1313(qs,simpli,kdeg,tepsco,tepsge,tmax,qintcr,kcur,kgraph,&kstat); 10281 if (kstat==-185) goto war00; 10282 if (kstat<0) goto error; 10283 10284 /* Identify first and last parameter pair in the intersection curve */ 10285 10286 qcrv = qintcr -> ppar1; 10287 if (qcrv == SISL_NULL) goto war00; 10288 10289 spar1 = qcrv -> ecoef; 10290 spar2 = spar1 + 2*(qcrv->in)-2; 10291 /* Check if any of the points lie on the boundary */ 10292 10293 kmark1 = 0; 10294 tdum1 = (double)2.0*max(fabs(sval1[0]),fabs(sval1[1])); 10295 tdum2 = (double)2.0*max(fabs(sval2[0]),fabs(sval2[1])); 10296 10297 if (DEQUAL(spar1[0]+tdum1,sval1[0]+tdum1) || DEQUAL(spar1[0]+tdum1,sval1[1]+tdum1) || 10298 DEQUAL(spar1[1]+tdum2,sval2[0]+tdum2) || DEQUAL(spar1[1]+tdum2,sval2[1]+tdum2) ) 10299 kmark1 = 1; 10300 10301 kmark2 = 0; 10302 10303 if (DEQUAL(spar2[0]+tdum1,sval1[0]+tdum1) || DEQUAL(spar2[0]+tdum1,sval1[1]+tdum1) || 10304 DEQUAL(spar2[1]+tdum2,sval2[0]+tdum2) || DEQUAL(spar2[1]+tdum2,sval2[1]+tdum2) ) 10305 kmark2 = 1; 10306 10307 /* Check if closed */ 10308 10309 kclose = 0; 10310 if (spar1[0] == spar2[0] && spar1[1] == spar2[1]) kclose = 1; 10311 10312 /* Check if first points matches start point */ 10313 10314 kmatch1 = 0; 10315 if (DEQUAL(epar[0]+tdum1,spar1[0]+tdum1) && DEQUAL(epar[1]+tdum2,spar1[1]+tdum2) ) 10316 kmatch1 = 1; 10317 10318 /* Check if second points matches start point */ 10319 10320 kmatch2 = 0; 10321 if (DEQUAL(epar[0]+tdum1,spar2[0]+tdum1) && DEQUAL(epar[1]+tdum2,spar2[1]+tdum2) ) 10322 kmatch2 = 1; 10323 10324 /* Check if any point matches start point */ 10325 10326 if (kmatch1 == 1 || kmatch2 == 1) 10327 { 10328 /* Start point matches one of the end points, status values in 10329 the range 11-19*/ 10330 10331 if (kmark1 == 1 && kmark2 == 1 && kclose == 0) 10332 { 10333 /* Open curve, status 11 */ 10334 *jstat = 11; 10335 if(kmatch1==1) 10336 goto copy; 10337 else 10338 goto invcopy; 10339 } 10340 else if (kmark1 ==1 || (kmark2 == 1 && kclose == 0)) 10341 { 10342 /* Open curve one point inside status 12 or 13 */ 10343 10344 if (kmark1 == 1 && kmatch1 == 1) 10345 { 10346 *jstat = 12; 10347 goto copy; 10348 } 10349 else if (kmark2 == 1 && kmatch2 == 1) 10350 { 10351 *jstat = 12; 10352 goto invcopy; 10353 } 10354 if (kmark1 == 1 && kmatch2 == 1) 10355 { 10356 *jstat = 13; 10357 goto invcopy; 10358 } 10359 if (kmark2 == 1 && kmatch1 == 1) 10360 { 10361 *jstat = 13; 10362 goto copy; 10363 } 10364 } 10365 else if (kclose == 0) 10366 { 10367 /* Both ends inside */ 10368 *jstat = 14; 10369 if(kmatch1==1) 10370 goto copy; 10371 else 10372 goto invcopy; 10373 } 10374 else if(kmatch1 == 1) 10375 { 10376 /* Closed curve, no singularity */ 10377 *jstat = 16; 10378 memcopy(gpar1,spar1,2,DOUBLE); 10379 memcopy(gpar2,spar1,2,DOUBLE); 10380 goto out; 10381 } 10382 else 10383 { 10384 /* Closed curve, with singularity */ 10385 *jstat=17; 10386 memcopy(gpar1,epar ,2,DOUBLE); 10387 memcopy(gpar2,spar1,2,DOUBLE); 10388 goto out; 10389 } 10390 } 10391 else 10392 { 10393 /* epar does not match produced end points, status messages in 10394 21-29 the range */ 10395 10396 if (kmark1 ==1 && kmark2 ==1 && kclose == 0) 10397 { 10398 /* Open curve, status 11 */ 10399 *jstat = 21; 10400 memcopy(gpar1,spar1,2,DOUBLE); 10401 memcopy(gpar2,spar2,2,DOUBLE); 10402 goto out; 10403 } 10404 else if (kmark1 ==1 && kclose == 0) 10405 { 10406 /* Open curve one point inside status 12 */ 10407 *jstat=22; 10408 goto copy; 10409 } 10410 else if (kmark2 ==1 && kclose == 0) 10411 { 10412 /* Open curve one point inside status 12 */ 10413 *jstat=22; 10414 goto invcopy; 10415 } 10416 else if (kclose == 0) 10417 { 10418 /* Both ends inside */ 10419 *jstat=24; 10420 goto copy; 10421 } 10422 else if(kmatch1 == 1) 10423 { 10424 /* Closed curve, no singularity */ 10425 *jstat=26; 10426 memcopy(gpar1,spar1,2,DOUBLE); 10427 memcopy(gpar2,spar1,2,DOUBLE); 10428 } 10429 else 10430 { 10431 /* Closed curve, with singularity */ 10432 *jstat = 27; 10433 memcopy(gpar1,epar ,2,DOUBLE); 10434 memcopy(gpar2,spar1,2,DOUBLE); 10435 goto out; 10436 } 10437 } 10438 /* Marching produced no curve */ 10439 10440 war00: *jstat = 0; 10441 memcopy(gpar1,epar,2,DOUBLE); 10442 memcopy(gpar2,epar,2,DOUBLE); 10443 goto out; 10444 10445 copy: 10446 memcopy(gpar1,spar1,2,DOUBLE); 10447 memcopy(gpar2,spar2,2,DOUBLE); 10448 goto out; 10449 10450 invcopy: 10451 memcopy(gpar1,spar2,2,DOUBLE); 10452 memcopy(gpar2,spar1,2,DOUBLE); 10453 goto out; 10454 10455 /* Error in space allocation */ 10456 err101: 10457 *jstat = -101; 10458 s6err("s1787",*jstat,kpos); 10459 goto out; 10460 10461 /* Error in lower level function */ 10462 error: 10463 *jstat = kstat; 10464 s6err("s1787",*jstat,kpos); 10465 goto out; 10466 10467 out: 10468 if (s3coef != SISL_NULL) freearray(s3coef); 10469 if (qs != SISL_NULL) freeSurf (qs); 10470 if (qintcr != SISL_NULL) freeIntcurve(qintcr); 10471 } 10472 10473 10474 //=========================================================================== 10475 void s6idkpt(SISLIntdat **pintdat,SISLIntpt **pintpt,SISLIntpt **rtpt,SISLIntpt **rfpt, 10476 int *jstat) 10477 //=========================================================================== 10478 { 10479 int ki; /* Counters. */ 10480 int knum; 10481 10482 (*rtpt) = (*rfpt) = SISL_NULL; 10483 *jstat = 0; 10484 10485 /* We have to be sure that we have an intdat structure. */ 10486 10487 if ((*pintdat) == SISL_NULL) 10488 goto out; 10489 10490 if ((*pintpt) == SISL_NULL) 10491 { 10492 *jstat = 1; 10493 goto out; 10494 } 10495 10496 10497 /* Than we have to be sure that we do not have the intersection point 10498 before or an equal point. */ 10499 10500 for (knum = -1,ki=0; ki<(*pintdat)->ipoint; ki++) 10501 { 10502 if ((*pintdat)->vpoint[ki] == (*pintpt)) 10503 knum = ki; 10504 10505 if ((*pintdat)->vpoint[ki] == (*pintpt)->pcurve) 10506 (*rfpt) = (*pintdat)->vpoint[ki]; 10507 10508 if ((*pintdat)->vpoint[ki]->pcurve == (*pintpt)) 10509 (*rtpt) = (*pintdat)->vpoint[ki]; 10510 } 10511 10512 10513 if (knum == -1) 10514 *jstat = 1; 10515 else 10516 { 10517 (*pintdat)->vpoint[knum] = (*pintdat)->vpoint[(*pintdat)->ipoint-1]; 10518 ((*pintdat)->ipoint)--; 10519 (*pintdat)->vpoint[(*pintdat)->ipoint] = SISL_NULL; 10520 10521 if ((*rtpt) != SISL_NULL) 10522 (*rtpt) ->pcurve = SISL_NULL; 10523 10524 if ((*pintdat)->ipoint == 0) 10525 { 10526 freeIntdat(*pintdat); 10527 (*pintdat) = SISL_NULL; 10528 } 10529 } 10530 10531 freeIntpt(*pintpt); 10532 (*pintpt) = SISL_NULL; 10533 10534 out: ; 10535 } 10536 10537 10538 //=========================================================================== 10539 void s6idlis_s9psexamin(SISLSurf *ps1,double alevel, SISLIntdat **rintdat,int *jstat) 10540 //=========================================================================== 10541 { 10542 int kstat; 10543 int kdirstat; 10544 10545 unsigned char edg=0; 10546 SISLIntpt **uipt=SISL_NULL; 10547 SISLIntlist **uilst=SISL_NULL; 10548 10549 int ki,kj,kv,klnr,kpnr,klfs,klft,kdir,kpar; 10550 SISLIntpt *qpt1,*qpt2; 10551 SISLIntpt *qipt, *qp; 10552 10553 double tepsge, tmax,sedg[4]; 10554 double sval1[9],snorm1[3]; 10555 double epar1[2],epar2[2]; 10556 /* ALA && UJK 19.09.90 */ 10557 double ttol= 10000.0 * REL_COMP_RES; 10558 10559 tepsge = (double)0.001; 10560 10561 sedg[0] = ps1->et1[ps1->ik1-1]; 10562 sedg[1] = ps1->et1[ps1->in1]; 10563 sedg[2] = ps1->et2[ps1->ik2-1]; 10564 sedg[3] = ps1->et2[ps1->in2]; 10565 10566 10567 /* Init */ 10568 if (!(*rintdat)) goto out; 10569 if (ps1->idim != 1) goto err200; 10570 *jstat = 0; 10571 10572 10573 /* SISLCurve analyse section --------------------------------------------------*/ 10574 10575 if ((*rintdat)->ilist != 0) 10576 { 10577 /* Allocate array of pointers to the lists. */ 10578 klnr = (*rintdat)->ilist; 10579 if ((uilst = newarray(klnr,SISLIntlist *)) == SISL_NULL) goto err101; 10580 10581 /* Update the list array. */ 10582 10583 /* Get all open curves into array. */ 10584 for (kv=ki=0; ki<klnr; ki++) 10585 if ((*rintdat)->vlist[ki]->itype != 1) 10586 uilst[kv++] = (*rintdat)->vlist[ki]; 10587 10588 /* Correct number of curves.*/ 10589 klnr = kv; 10590 10591 /* Remove all open curves with endpoints on edges or singular 10592 endpoints from array.(they are ok.) */ 10593 for (ki=0; ki<klnr; ki++) 10594 { 10595 for (kj=0; kj<4; kj++) 10596 if (DEQUAL(uilst[ki]->pfirst->epar[(kj/2)],sedg[kj])) 10597 break; 10598 10599 10600 if (kj == 4) 10601 { 10602 /* Start point is NOT on edge, test if the point 10603 is a singular point. */ 10604 10605 klfs=klft=0; 10606 s1421(ps1,1,uilst[ki]->pfirst->epar,&klfs,&klft,sval1, 10607 snorm1,&kstat); 10608 if (kstat < 0) goto error; 10609 else if (kstat > 0 ) kj--; 10610 10611 tmax = sqrt(sval1[1]*sval1[1] + sval1[2]*sval1[2]); 10612 if ( tmax < ttol ) kj--; 10613 10614 } 10615 10616 10617 if (kj<4) 10618 { 10619 /* Start point is ok, test end point*/ 10620 for (kj=0; kj<4; kj++) 10621 if (DEQUAL(uilst[ki]->plast->epar[(kj/2)],sedg[kj])) 10622 break; 10623 10624 10625 if (kj == 4) 10626 { 10627 /* End point is NOT on edge, test if the point 10628 is a singular point. */ 10629 klfs=klft=0; 10630 s1421(ps1,1,uilst[ki]->plast->epar,&klfs,&klft,sval1, 10631 snorm1,&kstat); 10632 if (kstat < 0) goto error; 10633 else if (kstat > 0 ) kj--; 10634 10635 tmax = sqrt(sval1[1]*sval1[1] + sval1[2]*sval1[2]); 10636 if ( tmax < ttol ) kj--; 10637 10638 } 10639 10640 10641 if (kj<4) 10642 { 10643 /* Start point and end point is ok, remove it from the array*/ 10644 klnr--; 10645 if (ki<klnr) 10646 { 10647 uilst[ki] = uilst[klnr]; 10648 ki--; 10649 } 10650 10651 } 10652 } 10653 } 10654 10655 /* Now we only have curves with bad endpoints in the array. */ 10656 10657 for (ki=0; ki< klnr; ki++) 10658 { 10659 /* Now we kill all the points in the list except the 10660 end point that is an internal point . */ 10661 10662 for (kj=0; kj<4; kj++) 10663 if (DEQUAL(uilst[ki]->pfirst->epar[(kj/2)],sedg[kj])) 10664 break; 10665 10666 if (kj<4) 10667 { 10668 10669 /* The first point is on the edge, keep the last. */ 10670 qipt = uilst[ki]->pfirst; 10671 for (qp=qipt->pcurve; qipt != uilst[ki]->plast;qipt=qp,qp=qp->pcurve) 10672 { 10673 s6idkpt(rintdat,&qipt,&qpt1,&qpt2,&kstat); 10674 if (kstat < 0) goto error; 10675 } 10676 10677 qipt = uilst[ki]->plast; 10678 uilst[ki]->pfirst = uilst[ki]->plast = qipt; 10679 uilst[ki]->inumb = 1; 10680 } 10681 else 10682 { 10683 /* The first point is not on the edge, keep it. */ 10684 10685 for (qipt = uilst[ki]->pfirst->pcurve; qipt != SISL_NULL;qipt=qp) 10686 { 10687 s6idkpt(rintdat,&qipt,&qpt1,&qp,&kstat); 10688 if (kstat < 0) goto error; 10689 } 10690 qipt = uilst[ki]->pfirst; 10691 uilst[ki]->pfirst = uilst[ki]->plast = qipt; 10692 uilst[ki]->inumb = 1; 10693 } 10694 10695 /* March from point qipt */ 10696 s1787(ps1,alevel,tepsge,qipt->epar,epar1,epar2,&kstat); 10697 if (kstat<0) goto error; 10698 10699 if (kstat == 0) 10700 { 10701 /* No succes. */ 10702 /* Kill point and the list */ 10703 s6idklist(rintdat,uilst[ki],&kstat); 10704 if (kstat<0) goto error; 10705 10706 klnr--; 10707 if (ki < klnr) 10708 { 10709 uilst[ki] = uilst[klnr]; 10710 ki--; 10711 } 10712 10713 } 10714 else if (kstat == 11 || kstat == 12 || kstat == 13 || 10715 kstat == 14 || kstat == 21 || kstat == 22 || kstat == 24 ) 10716 { 10717 /* Making a new open curve with endpoint in epar1 and epar2.*/ 10718 10719 uilst[ki]->pfirst = newIntpt(2,epar1,DZERO); 10720 if (uilst[ki]->pfirst == SISL_NULL) goto err101; 10721 10722 s6idnpt(rintdat,&uilst[ki]->pfirst,0,&kstat); 10723 if (kstat < 0)goto error; 10724 10725 uilst[ki]->plast = newIntpt(2,epar2,DZERO); 10726 if (uilst[ki]->plast == SISL_NULL) goto err101; 10727 10728 s6idnpt(rintdat,&uilst[ki]->plast,0,&kstat); 10729 if (kstat < 0)goto error; 10730 10731 uilst[ki]->pfirst->pcurve = qipt; 10732 qipt->pcurve = uilst[ki]->plast; 10733 uilst[ki]->inumb = 3; 10734 uilst[ki]->itype = 4; 10735 } 10736 10737 else if (kstat == 16 || kstat == 17 || kstat == 26 || kstat == 27) 10738 { 10739 /* Making a new closed curve with pfirst and plast 10740 pointing on qipt.*/ 10741 10742 uilst[ki]->pfirst = uilst[ki]->plast = qipt; 10743 uilst[ki]->inumb = 1; 10744 uilst[ki]->itype = 1; 10745 qipt->pcurve = qipt; 10746 } 10747 } 10748 /* Now we check equality between the remaining curves in the array. */ 10749 for (ki=0;ki<klnr-1;ki++) 10750 for (kj=ki+1;kj<klnr;kj++) 10751 { 10752 if ((s6dist(uilst[ki]->pfirst->epar,uilst[kj]->pfirst->epar,2) 10753 < REL_COMP_RES && 10754 s6dist(uilst[ki]->plast->epar,uilst[kj]->plast->epar,2) 10755 < REL_COMP_RES) || 10756 (s6dist(uilst[ki]->pfirst->epar,uilst[kj]->plast->epar,2) 10757 < REL_COMP_RES && 10758 s6dist(uilst[ki]->plast->epar,uilst[kj]->pfirst->epar,2) 10759 < REL_COMP_RES)) 10760 /* The two curves has common start+end, remove the last one of them. */ 10761 { 10762 10763 s6idklist(rintdat,uilst[kj],&kstat); 10764 if (kstat<0) goto error; 10765 10766 klnr--; 10767 if (kj < klnr) 10768 { 10769 uilst[kj] = uilst[klnr]; 10770 kj--; 10771 } 10772 10773 } 10774 } 10775 10776 } 10777 10778 10779 /* End of curve analyse section -------------------------------------------*/ 10780 10781 /* SISLPoint analyse section --------------------------------------------------*/ 10782 10783 if ((*rintdat) && (*rintdat)->ipoint != 0) 10784 10785 /* Update the point array. */ 10786 { 10787 kpnr = (*rintdat)->ipoint; 10788 if ((uipt = newarray(kpnr,SISLIntpt *)) == SISL_NULL) goto err101; 10789 10790 10791 for (kv=ki=0; ki<kpnr; ki++) 10792 if ((*rintdat)->vpoint[ki]->pcurve == SISL_NULL) 10793 uipt[kv++] = (*rintdat)->vpoint[ki]; 10794 10795 for (ki=0; ki<kpnr; ki++) 10796 for (kj=0; kj<kv; kj++) 10797 if ((*rintdat)->vpoint[ki]->pcurve == uipt[kj]) 10798 { 10799 kv--; 10800 uipt[kj] = uipt[kv]; 10801 break; 10802 } 10803 10804 /* All single points found. */ 10805 kpnr = kv; 10806 10807 10808 /* Sorting out and killing all points but single touch points. */ 10809 10810 for (ki=0; ki<kpnr; ki++) 10811 { 10812 klfs=klft=0; 10813 s1421(ps1,1,uipt[ki]->epar,&klfs,&klft,sval1,snorm1,&kstat); 10814 if (kstat < 0) goto error; 10815 else if (kstat > 0 ) continue; 10816 10817 tmax = sqrt(sval1[1]*sval1[1] + sval1[2]*sval1[2]); 10818 if ( tmax < ttol ) continue; 10819 10820 10821 /* All singular points or degenerated points is ok. We 10822 then remove all other internal points. */ 10823 10824 for (kj=0,edg=0; kj<4; kj++) 10825 if (DEQUAL(uipt[ki]->epar[(kj/2)],sedg[kj])) 10826 edg |= 1<<kj; 10827 10828 if (edg == 0) 10829 { 10830 /* The point is removed. */ 10831 10832 s6idkpt(rintdat,&uipt[ki],&qpt1,&qpt2,&kstat); 10833 if (kstat < 0) goto error; 10834 10835 kpnr--; 10836 10837 if (ki < kpnr) 10838 { 10839 uipt[ki] = uipt[kpnr]; 10840 ki--; 10841 } 10842 10843 continue; 10844 } 10845 10846 /* Now we remove all edge points with in/out component. */ 10847 for (kpar=1,kj=0,kdir=kdirstat=0; kj<4; kj++) 10848 if ((edg & 1<<kj) == 1<<kj) 10849 { 10850 switch (kj) 10851 { 10852 case 0: 10853 if (fabs(sval1[1]/tmax) < ttol) 10854 kdir = 0; 10855 else 10856 kdir = (sval1[1] > DZERO ? 1 : -1); 10857 break; 10858 case 1: 10859 if (fabs(sval1[2]/tmax) < ttol) 10860 kdir = 0; 10861 else 10862 kdir = (sval1[2] > DZERO ? 1 : -1); 10863 break; 10864 case 2: 10865 if (fabs(sval1[1]/tmax) < ttol) 10866 kdir = 0; 10867 else 10868 kdir = (sval1[1] > DZERO ? -1 : 1); 10869 break; 10870 case 3: 10871 if (fabs(sval1[2]/tmax) < ttol) 10872 kdir = 0; 10873 else 10874 kdir = (sval1[2] > DZERO ? -1 : 1); 10875 } 10876 10877 if (kdir == 0) 10878 kpar = 0; 10879 else if (kdirstat != kdir) 10880 { 10881 if (kdirstat == 0) 10882 kdirstat = kdir; 10883 else 10884 { 10885 kdirstat = 10; 10886 break; 10887 } 10888 } 10889 } 10890 10891 if (kpar == 0 && kdirstat != 10) kdirstat = 0; 10892 10893 /* Test if the point is to be removed.*/ 10894 if (kdirstat == 1 || kdirstat == -1) 10895 { 10896 /* The point is removed. */ 10897 10898 s6idkpt(rintdat,&uipt[ki],&qpt1,&qpt2,&kstat); 10899 if (kstat < 0) goto error; 10900 10901 kpnr--; 10902 10903 if (ki < kpnr) 10904 { 10905 uipt[ki] = uipt[kpnr]; 10906 ki--; 10907 } 10908 10909 continue; 10910 } 10911 10912 } /* End of for ki= .... */ 10913 10914 } 10915 /* End of point analyse section ---------------------------------------------*/ 10916 10917 goto out; 10918 10919 /* Error in sub rutines. */ 10920 10921 error : 10922 *jstat = kstat; 10923 s6err("s6idlis_s9psexamin",*jstat,0); 10924 goto out; 10925 10926 /* Error in memory allocation. */ 10927 10928 err101 : 10929 *jstat = -101; 10930 s6err("s6idlis_s9psexamin",*jstat,0); 10931 goto out; 10932 10933 /* Error dimention. */ 10934 10935 err200 : 10936 *jstat = -200; 10937 s6err("s6idlis_s9psexamin",*jstat,0); 10938 goto out; 10939 10940 out: 10941 if (uipt != SISL_NULL) freearray(uipt); 10942 if (uilst != SISL_NULL) freearray(uilst); 10943 } 10944 10945 10946 //=========================================================================== 10947 void s6idlis_s9ssexamin(SISLSurf *ps1,SISLSurf *ps2, SISLIntdat **rintdat,int *jstat) 10948 //=========================================================================== 10949 { 10950 int kstat; 10951 int kdirstat; 10952 10953 unsigned char edg=0; 10954 SISLIntpt **uipt=SISL_NULL; 10955 SISLIntlist **uilst=SISL_NULL; 10956 10957 int ki,kj,kv,klnr,kpnr,klfs,klft,kdir,kpar; 10958 SISLIntpt *qpt1,*qpt2; 10959 SISLIntpt *qipt, *qp; 10960 10961 double tepsge, tang,sedg[8]; 10962 double sval1[9],sval2[9],snorm1[3],snorm2[3]; 10963 double stang[3],sdec1[3],sdec2[3]; 10964 double epar1[4],epar2[4]; 10965 10966 tepsge = (double)0.001; 10967 10968 sedg[0] = ps1->et1[ps1->ik1-1]; 10969 sedg[1] = ps1->et1[ps1->in1]; 10970 sedg[2] = ps1->et2[ps1->ik2-1]; 10971 sedg[3] = ps1->et2[ps1->in2]; 10972 sedg[4] = ps2->et1[ps2->ik1-1]; 10973 sedg[5] = ps2->et1[ps2->in1]; 10974 sedg[6] = ps2->et2[ps2->ik2-1]; 10975 sedg[7] = ps2->et2[ps2->in2]; 10976 10977 /* Init */ 10978 if (!(*rintdat)) goto out; 10979 if (ps1->idim != 3 || ps2->idim != 3) goto err200; 10980 *jstat = 0; 10981 10982 10983 /* SISLCurve analyse section --------------------------------------------------*/ 10984 if ((*rintdat)->ilist != 0) 10985 { 10986 /* Allocate array of pointers to the lists. */ 10987 klnr = (*rintdat)->ilist; 10988 if ((uilst = newarray(klnr,SISLIntlist *)) == SISL_NULL) goto err101; 10989 10990 /* Update the list array. */ 10991 10992 /* Get all open curves into array. */ 10993 for (kv=ki=0; ki<klnr; ki++) 10994 if ((*rintdat)->vlist[ki]->itype != 1) 10995 uilst[kv++] = (*rintdat)->vlist[ki]; 10996 10997 /* Correct number of curves.*/ 10998 klnr = kv; 10999 11000 /* Remove all open curves with endpoints on edges or singular 11001 endpoints from array.(they are ok.) */ 11002 for (ki=0; ki<klnr; ki++) 11003 { 11004 for (kj=0; kj<8; kj++) 11005 if (DEQUAL(uilst[ki]->pfirst->epar[(kj/2)],sedg[kj])) 11006 break; 11007 11008 11009 if (kj == 8) 11010 { 11011 /* Start point is NOT on edge, test if the point 11012 is a singular point. */ 11013 11014 klfs=klft=0; 11015 s1421(ps1,1,uilst[ki]->pfirst->epar,&klfs,&klft,sval1, 11016 snorm1,&kstat); 11017 if (kstat < 0) goto error; 11018 else if (kstat > 0 ) kj--; 11019 11020 klfs=klft=0; 11021 s1421(ps2,1,uilst[ki]->pfirst->epar+2,&klfs,&klft,sval2, 11022 snorm2,&kstat); 11023 if (kstat < 0) goto error; 11024 else if (kstat > 0 ) kj--; 11025 11026 tang = s6ang(snorm1,snorm2,3); 11027 if (tang < ANGULAR_TOLERANCE) kj--; 11028 } 11029 11030 11031 if (kj<8) 11032 { 11033 /* Start point is ok, test end point*/ 11034 for (kj=0; kj<8; kj++) 11035 if (DEQUAL(uilst[ki]->plast->epar[(kj/2)],sedg[kj])) 11036 break; 11037 11038 11039 if (kj == 8) 11040 { 11041 /* End point is NOT on edge, test if the point 11042 is a singular point. */ 11043 klfs=klft=0; 11044 s1421(ps1,1,uilst[ki]->plast->epar,&klfs,&klft,sval1, 11045 snorm1,&kstat); 11046 if (kstat < 0) goto error; 11047 else if (kstat > 0 ) kj--; 11048 11049 klfs=klft=0; 11050 s1421(ps2,1,uilst[ki]->plast->epar+2,&klfs,&klft,sval2, 11051 snorm2,&kstat); 11052 if (kstat < 0) goto error; 11053 else if (kstat > 0 ) kj--; 11054 11055 tang = s6ang(snorm1,snorm2,3); 11056 if (tang < ANGULAR_TOLERANCE) kj--; 11057 } 11058 11059 11060 if (kj<8) 11061 { 11062 /* Start point and end point is ok, remove it from the array*/ 11063 klnr--; 11064 if (ki<klnr) 11065 { 11066 uilst[ki] = uilst[klnr]; 11067 ki--; 11068 } 11069 11070 } 11071 } 11072 } 11073 11074 /* Now we only have curves with bad endpoints in the array. */ 11075 11076 for (ki=0; ki< klnr; ki++) 11077 { 11078 /* Now we kill all the points in the list except the 11079 end point that is an internal point . */ 11080 11081 for (kj=0; kj<8; kj++) 11082 if (DEQUAL(uilst[ki]->pfirst->epar[(kj/2)],sedg[kj])) 11083 break; 11084 11085 if (kj<8) 11086 { 11087 11088 /* The first point is on the edge, keep the last. */ 11089 qipt = uilst[ki]->pfirst; 11090 for (qp=qipt->pcurve; qipt != uilst[ki]->plast;qipt=qp,qp=qp->pcurve) 11091 { 11092 s6idkpt(rintdat,&qipt,&qpt1,&qpt2,&kstat); 11093 if (kstat < 0) goto error; 11094 } 11095 11096 qipt = uilst[ki]->plast; 11097 uilst[ki]->pfirst = uilst[ki]->plast = qipt; 11098 uilst[ki]->inumb = 1; 11099 } 11100 else 11101 { 11102 /* The first point is not on the edge, keep it. */ 11103 11104 for (qipt = uilst[ki]->pfirst->pcurve; qipt != SISL_NULL;qipt=qp) 11105 { 11106 s6idkpt(rintdat,&qipt,&qpt1,&qp,&kstat); 11107 if (kstat < 0) goto error; 11108 } 11109 11110 qipt = uilst[ki]->pfirst; 11111 uilst[ki]->pfirst = uilst[ki]->plast = qipt; 11112 uilst[ki]->inumb = 1; 11113 11114 } 11115 11116 /* March from point qipt */ 11117 s1788(ps1,ps2,tepsge,qipt->epar,epar1,epar2,&kstat); 11118 if (kstat<0) goto error; 11119 11120 if (kstat == 0) 11121 { 11122 /* No succes. */ 11123 /* Kill point and the list */ 11124 s6idklist(rintdat,uilst[ki],&kstat); 11125 if (kstat<0) goto error; 11126 klnr--; 11127 if (ki < klnr) 11128 { 11129 uilst[ki] = uilst[klnr]; 11130 ki--; 11131 } 11132 11133 } 11134 else if (kstat == 11 || kstat == 12 || kstat == 13 || 11135 kstat == 14 || kstat == 21 || kstat == 22 || kstat == 24 ) 11136 { 11137 /* Making a new open curve with endpoint in epar1 and epar2.*/ 11138 11139 uilst[ki]->pfirst = newIntpt(4,epar1,DZERO); 11140 if (uilst[ki]->pfirst == SISL_NULL) goto err101; 11141 11142 s6idnpt(rintdat,&uilst[ki]->pfirst,0,&kstat); 11143 if (kstat < 0)goto error; 11144 11145 uilst[ki]->plast = newIntpt(4,epar2,DZERO); 11146 if (uilst[ki]->plast == SISL_NULL) goto err101; 11147 11148 s6idnpt(rintdat,&uilst[ki]->plast,0,&kstat); 11149 if (kstat < 0)goto error; 11150 11151 uilst[ki]->pfirst->pcurve = qipt; 11152 qipt->pcurve = uilst[ki]->plast; 11153 uilst[ki]->inumb = 3; 11154 uilst[ki]->itype = 4; 11155 } 11156 11157 else if (kstat == 16 || kstat == 17 || kstat == 26 || kstat == 27) 11158 { 11159 /* Making a new closed curve with pfirst and plast 11160 pointing on qipt.*/ 11161 11162 uilst[ki]->pfirst = uilst[ki]->plast = qipt; 11163 uilst[ki]->inumb = 1; 11164 uilst[ki]->itype = 1; 11165 qipt->pcurve = qipt; 11166 11167 } 11168 } 11169 /* Now we check equality between the remaining curves in the array. */ 11170 for (ki=0;ki<klnr-1;ki++) 11171 for (kj=ki+1;kj<klnr;kj++) 11172 { 11173 if ((s6dist(uilst[ki]->pfirst->epar,uilst[kj]->pfirst->epar,4) 11174 < REL_COMP_RES && 11175 s6dist(uilst[ki]->plast->epar,uilst[kj]->plast->epar,4) 11176 < REL_COMP_RES) || 11177 (s6dist(uilst[ki]->pfirst->epar,uilst[kj]->plast->epar,4) 11178 < REL_COMP_RES && 11179 s6dist(uilst[ki]->plast->epar,uilst[kj]->pfirst->epar,4) 11180 < REL_COMP_RES)) 11181 /* The two curves has common start+end, remove the last one of them. */ 11182 { 11183 11184 s6idklist(rintdat,uilst[kj],&kstat); 11185 if (kstat<0) goto error; 11186 11187 klnr--; 11188 if (kj < klnr) 11189 { 11190 uilst[kj] = uilst[klnr]; 11191 kj--; 11192 } 11193 11194 } 11195 } 11196 11197 } 11198 11199 11200 /* End of curve analyse section -------------------------------------------*/ 11201 11202 /* SISLPoint analyse section --------------------------------------------------*/ 11203 11204 if ((*rintdat) && (*rintdat)->ipoint != 0) 11205 /* Update the point array. */ 11206 { 11207 kpnr = (*rintdat)->ipoint; 11208 if ((uipt = newarray(kpnr,SISLIntpt *)) == SISL_NULL) goto err101; 11209 11210 11211 for (kv=ki=0; ki<kpnr; ki++) 11212 if ((*rintdat)->vpoint[ki]->pcurve == SISL_NULL) 11213 uipt[kv++] = (*rintdat)->vpoint[ki]; 11214 11215 for (ki=0; ki<kpnr; ki++) 11216 for (kj=0; kj<kv; kj++) 11217 if ((*rintdat)->vpoint[ki]->pcurve == uipt[kj]) 11218 { 11219 kv--; 11220 uipt[kj] = uipt[kv]; 11221 break; 11222 } 11223 11224 /* All single points found. */ 11225 kpnr = kv; 11226 11227 11228 /* Sorting out and killing all points but single touch points. */ 11229 11230 for (ki=0; ki<kpnr; ki++) 11231 { 11232 klfs=klft=0; 11233 s1421(ps1,1,uipt[ki]->epar,&klfs,&klft,sval1,snorm1,&kstat); 11234 if (kstat < 0) goto error; 11235 else if (kstat > 0 ) continue; 11236 11237 if (s6length(snorm1,3,&kstat) <= REL_COMP_RES) continue; 11238 11239 klfs=klft=0; 11240 s1421(ps2,1,uipt[ki]->epar+2,&klfs,&klft,sval2,snorm2,&kstat); 11241 if (kstat < 0) goto error; 11242 else if (kstat > 0 ) continue; 11243 11244 if (s6length(snorm2,3,&kstat) <= REL_COMP_RES) continue; 11245 11246 tang = s6ang(snorm1,snorm2,3); 11247 if (tang < ANGULAR_TOLERANCE) continue; 11248 11249 11250 /* All singular points or degenerated points is ok. We 11251 then remove all other internal points. */ 11252 11253 for (kj=0,edg=0; kj<8; kj++) 11254 if (DEQUAL(uipt[ki]->epar[(kj/2)],sedg[kj])) 11255 edg |= 1<<kj; 11256 11257 if (edg == 0) 11258 { 11259 /* The point is removed. */ 11260 11261 s6idkpt(rintdat,&uipt[ki],&qpt1,&qpt2,&kstat); 11262 if (kstat < 0) goto error; 11263 11264 kpnr--; 11265 11266 if (ki < kpnr) 11267 { 11268 uipt[ki] = uipt[kpnr]; 11269 ki--; 11270 } 11271 11272 continue; 11273 } 11274 11275 11276 s6crss(snorm1,snorm2,stang); 11277 11278 s6decomp(stang,sdec1,sval1+3,sval1+6,snorm1,&kstat); 11279 if (kstat < 0) goto error; 11280 else if (kstat > 0 ) continue; 11281 11282 s6decomp(stang,sdec2,sval2+3,sval2+6,snorm2,&kstat); 11283 if (kstat < 0) goto error; 11284 else if (kstat > 0 ) continue; 11285 11286 for (kpar=1,kdir=kdirstat=0,kj=0; kj<8; kj++) 11287 if ((edg & 1<<kj) == 1<<kj) 11288 { 11289 switch (kj) 11290 { 11291 case 0: tang = s6ang(stang,sval1+3,3); 11292 kdir = (sdec1[1] > DZERO ? 1 : -1); 11293 break; 11294 case 4: tang = s6ang(stang,sval2+3,3); 11295 kdir = (sdec2[1] > DZERO ? 1 : -1); 11296 break; 11297 case 1: tang = s6ang(stang,sval1+6,3); 11298 kdir = (sdec1[0] > DZERO ? -1 : 1); 11299 break; 11300 case 5: tang = s6ang(stang,sval2+6,3); 11301 kdir = (sdec2[0] > DZERO ? -1 : 1); 11302 break; 11303 case 2: tang = s6ang(stang,sval1+3,3); 11304 kdir = (sdec1[1] > DZERO ? -1 : 1); 11305 break; 11306 case 6: tang = s6ang(stang,sval2+3,3); 11307 kdir = (sdec2[1] > DZERO ? -1 : 1); 11308 break; 11309 case 3: tang = s6ang(stang,sval1+6,3); 11310 kdir = (sdec1[0] > DZERO ? 1 : -1); 11311 break; 11312 case 7: tang = s6ang(stang,sval2+6,3); 11313 kdir = (sdec2[0] > DZERO ? 1 : -1); 11314 } 11315 11316 if (tang < ANGULAR_TOLERANCE) kdir = 0; 11317 11318 if (kdir == 0) 11319 kpar = 0; 11320 else if (kdirstat != kdir) 11321 { 11322 if (kdirstat == 0) 11323 kdirstat = kdir; 11324 else 11325 { 11326 kdirstat = 10; 11327 break; 11328 } 11329 } 11330 } 11331 11332 if (kpar == 0 && kdirstat != 10) kdirstat = 0; 11333 11334 /* Test if the point is to be removed.*/ 11335 if (kdirstat == 1 || kdirstat == -1) 11336 { 11337 /* The point is removed. */ 11338 11339 s6idkpt(rintdat,&uipt[ki],&qpt1,&qpt2,&kstat); 11340 if (kstat < 0) goto error; 11341 11342 kpnr--; 11343 11344 if (ki < kpnr) 11345 { 11346 uipt[ki] = uipt[kpnr]; 11347 ki--; 11348 } 11349 11350 continue; 11351 } 11352 11353 } /* End of for ki= .... */ 11354 11355 } 11356 /* End of point analyse section ---------------------------------------------*/ 11357 11358 11359 goto out; 11360 11361 /* Error in sub rutines. */ 11362 11363 error : *jstat = kstat; 11364 s6err("s6idlis_s9ssexamin",*jstat,0); 11365 goto out; 11366 11367 /* Error in memory allocation. */ 11368 11369 err101 : *jstat = -101; 11370 s6err("s6idlis_s9ssexamin",*jstat,0); 11371 goto out; 11372 11373 /* Error dimention. */ 11374 11375 err200 : *jstat = -200; 11376 s6err("s6idlis_s9ssexamin",*jstat,0); 11377 goto out; 11378 11379 out: 11380 if (uipt != SISL_NULL) freearray(uipt); 11381 if (uilst != SISL_NULL) freearray(uilst); 11382 } 11383 11384 11385 //=========================================================================== 11386 void s6idlis(SISLObject *po1,SISLObject *po2,SISLIntdat **pintdat,int *jstat) 11387 //=========================================================================== 11388 { 11389 int kstat; /* Local status variable. */ 11390 int kpos=0; /* Position of error. */ 11391 int kj,ki1,ki2; /* Counters */ 11392 int ktype; /* To indicate type of list. */ 11393 SISLIntpt *pt; /* to traverse list of points. */ 11394 11395 *jstat = 0; 11396 11397 /* If we do not have any intersection data we just return. */ 11398 11399 if ((*pintdat) == SISL_NULL) goto out; 11400 11401 /* We first destroy existing intersection lists. */ 11402 11403 for (kj=0; kj<(*pintdat)->ilist; kj++) freeIntlist((*pintdat)->vlist[kj]); 11404 11405 11406 /* Then we split lists with internal junction points. We have to 11407 be sure that all junction points are end points in the lists. */ 11408 11409 for (kj=0; kj<(*pintdat)->ipoint; kj++) 11410 if ((*pintdat)->vpoint[kj]->iinter == 2) 11411 { 11412 if ((*pintdat)->vpoint[kj]->pcurve != SISL_NULL) 11413 { 11414 for (ki1=0; ki1<(*pintdat)->ipoint; ki1++) 11415 if ((*pintdat)->vpoint[ki1]->pcurve == (*pintdat)->vpoint[kj]) 11416 break; 11417 11418 if (ki1<(*pintdat)->ipoint) 11419 { 11420 pt = copyIntpt((*pintdat)->vpoint[kj]); 11421 11422 s6idnpt(pintdat,&pt,0,&kstat); 11423 if (kstat < 0) goto error; 11424 11425 pt->pcurve = (*pintdat)->vpoint[kj]->pcurve; 11426 11427 (*pintdat)->vpoint[kj]->pcurve = SISL_NULL; 11428 } 11429 } 11430 } 11431 11432 11433 /* At least we can traverse all intersection points to look for 11434 start points to lists. If a point have a next point 11435 and no other point pointing on itself. It is a start point. */ 11436 11437 for (ki1=0,ki2=0; ki1 < (*pintdat)->ipoint; ki1++) 11438 if ((*pintdat)->vpoint[ki1]->pcurve != SISL_NULL) 11439 { 11440 for (kj=0; kj<(*pintdat)->ipoint; kj++) 11441 if ((*pintdat)->vpoint[kj]->pcurve == (*pintdat)->vpoint[ki1]) 11442 break; 11443 11444 if (kj == (*pintdat)->ipoint) 11445 { 11446 /* To be sure that list array is big enough. */ 11447 11448 if (ki2 == (*pintdat)->ilmax) 11449 { 11450 (*pintdat)->ilmax += 20; 11451 11452 if (((*pintdat)->vlist = increasearray((*pintdat)->vlist, 11453 (*pintdat)->ilmax,SISLIntlist *)) == SISL_NULL) 11454 11455 goto err101; 11456 } 11457 11458 11459 /* Finding the last point in the list, and number of points. */ 11460 11461 kj = 0; 11462 for (pt=(*pintdat)->vpoint[ki1];pt->pcurve!=SISL_NULL; 11463 pt=pt->pcurve,kj++); 11464 11465 11466 /* Computing type of point, junctions in the end points. */ 11467 11468 ktype = 0; 11469 11470 if ((*pintdat)->vpoint[ki1]->iinter == 2) 11471 ktype = 2; 11472 11473 if (pt->iinter == 2) 11474 ktype = (ktype == 2 ? 4 : 3); 11475 11476 11477 /* Making a new list structure. */ 11478 11479 if (((*pintdat)->vlist[ki2] = newIntlist((*pintdat)->vpoint[ki1], 11480 pt,ktype)) == SISL_NULL) goto err101; 11481 11482 (*pintdat)->vlist[ki2]->inumb = kj + 1; 11483 ki2++; 11484 11485 } 11486 } 11487 11488 /*------------------------------------------------------------------*/ 11489 11490 /* We also have to find closed lists. */ 11491 11492 /* Mark found list elements: */ 11493 for (ki1=0; ki1 < ki2; ki1++) 11494 for (pt=(*pintdat)->vlist[ki1]->pfirst;pt!=SISL_NULL;pt=pt->pcurve) 11495 pt->iinter += 10; 11496 11497 /* Now travers the point array untill we find an unmarked point. 11498 This point has to be a single (unconnected) one or a member 11499 of a closed connection. Mark points in the closed connection and 11500 establish a new list. */ 11501 11502 for (ki1=0; ki1 < (*pintdat)->ipoint; ki1++) 11503 { 11504 if ((*pintdat)->vpoint[ki1]->iinter>=10) 11505 /* Unmark point. */ 11506 (*pintdat)->vpoint[ki1]->iinter -= 10; 11507 11508 else if ((*pintdat)->vpoint[ki1]->pcurve != SISL_NULL) 11509 { 11510 /* It has to be a closed connection, travers all elements. */ 11511 kj = 1; 11512 for (pt=(*pintdat)->vpoint[ki1]->pcurve;pt!=(*pintdat)->vpoint[ki1]; 11513 pt=pt->pcurve) 11514 { 11515 if (pt == SISL_NULL) goto err105; 11516 /* Mark found list elements: */ 11517 pt->iinter += 10; 11518 kj++; 11519 } 11520 11521 /*Create new list element. */ 11522 11523 /* To be sure that list array is big enough. */ 11524 if (ki2 == (*pintdat)->ilmax) 11525 { 11526 (*pintdat)->ilmax += 20; 11527 11528 if (((*pintdat)->vlist = increasearray((*pintdat)->vlist, 11529 (*pintdat)->ilmax,SISLIntlist *)) == SISL_NULL) 11530 goto err101; 11531 } 11532 11533 /* Closed curves will have no singularities: */ 11534 ktype = 1; 11535 11536 /* Making a new list structure. */ 11537 if (((*pintdat)->vlist[ki2] = 11538 newIntlist((*pintdat)->vpoint[ki1]->pcurve, 11539 (*pintdat)->vpoint[ki1],ktype)) == SISL_NULL) 11540 goto err101; 11541 (*pintdat)->vlist[ki2]->inumb = kj; 11542 ki2++; 11543 11544 } 11545 } 11546 11547 (*pintdat)->ilist = ki2; 11548 11549 /*------------------------------------------------------------------*/ 11550 11551 /* A final check if the geometry found is ok. */ 11552 11553 if (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE && po1->s1->idim == 3) 11554 { 11555 s6idlis_s9ssexamin(po1->s1,po2->s1,pintdat,&kstat); 11556 if (kstat < 0) goto error; 11557 } 11558 else if (po1->iobj == SISLPOINT && po2->iobj == SISLSURFACE && po1->p1->idim == 1) 11559 { 11560 s6idlis_s9psexamin(po2->s1,po1->p1->ecoef[0],pintdat,&kstat); 11561 if (kstat < 0) goto error; 11562 } 11563 else if (po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT && po2->p1->idim == 1) 11564 { 11565 s6idlis_s9psexamin(po1->s1,po2->p1->ecoef[0],pintdat,&kstat); 11566 if (kstat < 0) goto error; 11567 } 11568 11569 goto out; 11570 11571 /* Error in space allocation. */ 11572 11573 err101: *jstat = -101; 11574 s6err("s6idlis",*jstat,kpos); 11575 goto out; 11576 11577 /* Error in vpoint array. */ 11578 11579 err105: *jstat = -105; 11580 s6err("s6idlis",*jstat,kpos); 11581 goto out; 11582 11583 /* Error in sub function. */ 11584 11585 error: *jstat = kstat; 11586 s6err("s6idlis",*jstat,kpos); 11587 goto out; 11588 11589 out: ; 11590 11591 } 11592 11593 //=========================================================================== 11594 void s1252_s6dir(double *cdiff,double acoef,double eval[],double astart, double aend) 11595 //=========================================================================== 11596 { 11597 double t1,t2,t3,t4,t5,t6; /* Constants in equation. */ 11598 double tmax; /* Max values in equation. */ 11599 double ttol=(double)1e-10; /* Relative tolerance in equation. */ 11600 11601 /* Dummy statements to avoid warning. */ 11602 t1=acoef; 11603 t2=astart; 11604 t3=aend; 11605 11606 11607 t1 = eval[1]; 11608 t2 = eval[2]; 11609 t3 = eval[3]/(double)2.0; 11610 11611 tmax = max(fabs(t1),fabs(t2)); 11612 tmax = max(fabs(t3),tmax); 11613 11614 if (DEQUAL(tmax,DZERO)) *cdiff = DZERO; 11615 else if (fabs(t3)/tmax < ttol) /* The second degree part is degenerated. */ 11616 { 11617 if (fabs(t2) == DZERO ) *cdiff = DZERO; 11618 else *cdiff = (-t1/t2); 11619 } 11620 else 11621 { 11622 /* An ordinary second degree equation. */ 11623 t4 = t2*t2 - (double)4*t3*t1; 11624 if (t4 < DZERO) 11625 { 11626 /* Use linear equation. */ 11627 if (fabs(t2) == DZERO ) *cdiff = DZERO; 11628 else *cdiff = (-t1/t2); 11629 } 11630 11631 else 11632 { 11633 t6 = sqrt(t4); 11634 t5 = (-t2 + t6)/((double)2*t3); 11635 t6 = (-t2 - t6)/((double)2*t3); 11636 t4 = min(fabs(t5),fabs(t6)); 11637 11638 /* We have two solutions and we want to use the one 11639 with the one with smallest value. */ 11640 11641 if (t4 == DZERO) 11642 { 11643 /* Use linear equation. */ 11644 if (fabs(t2) == DZERO ) *cdiff = DZERO; 11645 else *cdiff = (-t1/t2); 11646 } 11647 else if (fabs(t5) <= fabs(t6)) *cdiff = t5; 11648 else *cdiff = t6; 11649 } 11650 } 11651 } 11652 11653 11654 //=========================================================================== 11655 void s1252_s6corr(double *gdn,double acoef,double et[], int in,int ik,int *ileft,int *jdir) 11656 //=========================================================================== 11657 { 11658 int kmult,kstat; 11659 11660 /* Make sure the point is inside the interval */ 11661 11662 *gdn = MAX(et[ik-1]-acoef,*gdn); 11663 *gdn = MIN(et[in] -acoef,*gdn); 11664 11665 if (acoef+*gdn<et[*ileft] && acoef>et[*ileft]) 11666 { 11667 *gdn = MAX(et[*ileft]-acoef,*gdn); 11668 } 11669 11670 else if(acoef<et[*ileft+1] && acoef+*gdn>et[*ileft+1]) 11671 { 11672 /* We cross a knot value */ 11673 11674 *gdn = MIN(et[*ileft+1]-acoef,*gdn); 11675 } 11676 11677 /* Make sure that we calculate the left or right handed derivatives */ 11678 11679 if (*gdn>=0) 11680 { 11681 *jdir = 1; 11682 } 11683 else 11684 { 11685 *jdir = -1; 11686 } 11687 11688 kmult = s6knotmult(et,ik,in,ileft,acoef,&kstat); 11689 11690 if (acoef==et[*ileft]) 11691 { 11692 11693 if(kmult>ik-2) 11694 { 11695 if (*jdir == -1) 11696 { 11697 *jdir = -2; 11698 } 11699 else 11700 { 11701 *jdir = 2; 11702 } 11703 } 11704 } 11705 } 11706 11707 11708 //=========================================================================== 11709 void s1252(SISLCurve *pcurve,double aepsge,double astart,double *cpos,int *jstat) 11710 //=========================================================================== 11711 { 11712 int kstat = 0; /* Local status variable. */ 11713 int kpos = 0; /* Position of error. */ 11714 int kleft=0; /* Variables used in the evaluator. */ 11715 int kder=3; /* Order of derivatives to be calulated */ 11716 int kdim; /* Dimension of space the curves lie in */ 11717 int knbit; /* Number of iterations */ 11718 int kn,kk; /* Number of vertices and order */ 11719 int kdir=1; /* Direction of derivative to be calculated */ 11720 double tstart,tend; /* Ends of parameter interval of first curve. */ 11721 double tdelta; /* Parameter interval of the curves. */ 11722 double tdist=DZERO; /* Distance between position and origo. */ 11723 double td; /* Distances between old and new parameter value */ 11724 double tnext; /* Parameter-value of expression in first curve. */ 11725 double tprev; /* Previous difference between the curves. */ 11726 double sval[4]; /* Value ,first and second derivative on function */ 11727 double *st; /* Knot vector */ 11728 double ref; /* Refferance value for equality test. */ 11729 11730 /* Test input. */ 11731 11732 if (pcurve->idim != 1) goto err106; 11733 11734 kdim = pcurve -> idim; 11735 11736 /* Fetch endpoints and the intervals of parameter interval of curves. */ 11737 11738 st = pcurve->et; 11739 kn = pcurve->in; 11740 kk = pcurve->ik; 11741 11742 tstart = *(pcurve->et + pcurve->ik - 1); 11743 tend = *(pcurve->et + pcurve->in); 11744 tdelta = tend - tstart; 11745 if (tdelta == DZERO) tdelta = fabs(tend); 11746 if (tdelta == DZERO) tdelta = (double)1.0; 11747 11748 /* Initiate variables. */ 11749 11750 tnext = astart; 11751 11752 /* Evaluate 0-1.st derivatives of function */ 11753 11754 s1221(pcurve,kder,tnext,&kleft,sval,&kstat); 11755 if (kstat < 0) goto error; 11756 11757 tprev = sval[0]; 11758 11759 /* Evaluate step */ 11760 11761 s1252_s6dir(&td,tnext,sval,tstart,tend); 11762 11763 /* Correct if we not are inside the parameter intervall. */ 11764 11765 s1252_s6corr(&td,tnext,st,kn,kk,&kleft,&kdir); 11766 11767 /* Iterate to find the intersection point. */ 11768 11769 for (knbit = 0; knbit < 20; knbit++) 11770 { 11771 11772 /* If the tnext is a break point test if it is a local maximum */ 11773 11774 if (kdir == -2 || kdir == 2) 11775 { 11776 double tder1,tder2; 11777 /* Break point, test if local maximum */ 11778 11779 s1221(pcurve,kder,tnext,&kleft,sval,&kstat); 11780 if (kstat < 0) goto error; 11781 tder2 = sval[1]; 11782 11783 s1227(pcurve,kder,tnext,&kleft,sval,&kstat); 11784 if (kstat < 0) goto error; 11785 tder1 = sval[1]; 11786 11787 /* Test if top point */ 11788 11789 if (tder1>=DZERO && tder2<=DZERO) break; 11790 11791 /* Not a top point */ 11792 } 11793 11794 11795 /* Evaluate 0-1.st derivatives of both curves, dependent of the 11796 sign of td we calculate derivatives from the right or the left */ 11797 11798 if (kdir>=1) 11799 { 11800 s1221(pcurve,kder,tnext+td,&kleft,sval,&kstat); 11801 if (kstat < 0) goto error; 11802 } 11803 else 11804 { 11805 s1227(pcurve,kder,tnext+td,&kleft,sval,&kstat); 11806 if (kstat < 0) goto error; 11807 } 11808 11809 tdist = sval[0]; 11810 if (fabs(tdist) < (double)1.0) ref = (double)2.0; 11811 else ref = DZERO; 11812 11813 if (tdist >= tprev || DEQUAL(ref+tdist,ref+tprev)) 11814 { 11815 tnext += td; 11816 11817 /* Evaluate step */ 11818 s1252_s6dir(&td,tnext,sval,tstart,tend); 11819 s1252_s6corr(&td,tnext,st,kn,kk,&kleft,&kdir); 11820 11821 if (fabs(td/tdelta) <= REL_COMP_RES) break; 11822 11823 tprev = tdist; 11824 11825 } 11826 11827 /* Not converging, correct and try again. */ 11828 11829 else 11830 { 11831 11832 td /= (double)2; 11833 if (fabs(td/tdelta) <= REL_COMP_RES) break; 11834 } 11835 11836 11837 } 11838 11839 11840 /* Iteration stopped, test if point founds found is within resolution */ 11841 11842 if (tdist <= aepsge) 11843 *jstat = 1; 11844 else 11845 *jstat = 2; 11846 11847 /*ujk,july 89:*/ 11848 /* Test if the iteration is close to a knot */ 11849 if (DEQUAL(tnext,pcurve->et[kleft])) 11850 *cpos = pcurve->et[kleft]; 11851 else if (DEQUAL(tnext,pcurve->et[kleft+1])) 11852 *cpos = pcurve->et[kleft+1]; 11853 else 11854 *cpos = tnext; 11855 11856 /* Iteration completed. */ 11857 11858 goto out; 11859 11860 11861 /* Error in input. Conflicting dimensions. */ 11862 11863 err106: *jstat = -106; 11864 s6err("S1252",*jstat,kpos); 11865 goto out; 11866 11867 /* Error in lower level routine. */ 11868 11869 error : *jstat = kstat; 11870 s6err("S1252",*jstat,kpos); 11871 goto out; 11872 11873 out:; 11874 } 11875 11876 11877 //=========================================================================== 11878 void s1119(double *ecoef,double *et1,double *et2,int ik1,int in1,int ik2, 11879 int in2,int *jsimple,int *jind1,int *jind2,int *jstat) 11880 //=========================================================================== 11881 { 11882 int ki,kj; /* Counters. */ 11883 int ksimple; /* Indicates if simple case. */ 11884 int ksimple1; /* Indicates if simple case. */ 11885 int ksimple2; /* Indicates if simple case. */ 11886 int ksign; /* Number of direction changes in line/column. */ 11887 int kconvex1; /* Flag, if true, we have no interior min 11888 in first direction.*/ 11889 int kconcav1; /* Flag, if true, we have no interior max 11890 in first direction.*/ 11891 int kconvex2; /* Flag, if true, we have no interior min 11892 in second direction.*/ 11893 int kconcav2; /* Flag, if true, we have no interior max 11894 in second direction.*/ 11895 int kbez; /* Flagging for bezier case. */ 11896 double tfirst; /* First non-zero difference between two adjacent vertices. */ 11897 double tprev; /* Previous difference between two adjacent vertices. */ 11898 double tdiff; /* Current difference between two adjacent vertices. */ 11899 double *s1; /* Pointer used to traverse array of vertices. */ 11900 11901 /* First we search for interior knotmultiplicity in 11902 both parameter directions*/ 11903 *jind1 = 0; 11904 ksimple1 = 1; 11905 if (in1 > 1) 11906 for (ki=ik1+1; ki<in1 && ksimple1; ki++) 11907 { 11908 if (et1[ki] == et1[ki+ik1-1]) 11909 { 11910 *jind1 = ki; 11911 ksimple1 = 0; 11912 } 11913 } 11914 11915 *jind2 = 0; 11916 ksimple2 = 1; 11917 if (in2 > 1) 11918 for (ki=ik2+1; ki<in2 && ksimple2; ki++) 11919 { 11920 if (et2[ki] == et2[ki+ik2-1]) 11921 { 11922 *jind2 = ki; 11923 ksimple2 = 0; 11924 } 11925 } 11926 11927 11928 ksimple = ksimple1 && ksimple2; 11929 kbez = (((ik1 == in1) && (ik2 == in2)) ? 1 : 0); 11930 11931 /* Count number of direction changes in first parameter direction. */ 11932 /* Notify that we cannot accept equal coeffisient neighbours when 11933 we are in a none-bezier case. */ 11934 11935 kconcav1 = kconvex1 = 1; 11936 11937 if (in1 > 1) 11938 for (s1=ecoef,kj=0; kj<in2 && ksimple; kj++) 11939 { 11940 ksign = 0; 11941 tfirst = DZERO; 11942 11943 for (ki=0; ki<in1-1 && ksimple; ki++,s1++) 11944 { 11945 tdiff = *(s1+1) - *s1; 11946 if (DEQUAL(tdiff,DZERO) ) 11947 { 11948 if (kbez == 0) ksimple = 0; 11949 } 11950 else if (DEQUAL(tfirst,DZERO) ) 11951 { 11952 /* First none-zero vector, save it. */ 11953 tfirst = tdiff; 11954 tprev = tdiff; 11955 } 11956 11957 else if (tprev*tdiff < DZERO) 11958 { 11959 tprev = tdiff; 11960 ksign++; 11961 if (ksign > 1) ksimple = 0; 11962 } 11963 } 11964 11965 11966 if (kbez == 0) 11967 { 11968 /* We permit status simple case only in bezier case. 11969 However, if the surface is strictly concav in one 11970 parameter direction, we have found 11971 the max on the edges. */ 11972 kconvex1 = 0; 11973 kconcav1 = ((tfirst < DZERO) && kconcav1); 11974 } 11975 else 11976 { 11977 11978 kconvex1 = (((ksign == 0) || 11979 (ksign == 1 && tfirst >= DZERO)) && kconvex1); 11980 kconcav1 = (((ksign == 0) || 11981 (ksign == 1 && tfirst <= DZERO)) && kconcav1); 11982 } 11983 11984 ksimple = ((kconvex1 || kconcav1) && ksimple); 11985 s1++; 11986 11987 } 11988 11989 /* Count number of direction changes in second parameter direction. */ 11990 kconcav2 = kconvex2 = 1; 11991 if (in2 > 1) 11992 for (kj=0; kj<in1 && ksimple; kj++) 11993 { 11994 ksign = 0; 11995 tfirst = DZERO; 11996 s1 = ecoef + kj; 11997 11998 for (ki=0; ki<in2-1 && ksimple; ki++,s1+=in1) 11999 { 12000 tdiff = *(s1+in1) - *s1; 12001 if (DEQUAL(tdiff,DZERO) ) 12002 { 12003 if (kbez == 0) ksimple = 0; 12004 } 12005 else if (DEQUAL(tfirst,DZERO) ) 12006 { 12007 /* First none-zero vector, save it. */ 12008 tfirst = tdiff; 12009 tprev = tdiff; 12010 } 12011 12012 else if (tprev*tdiff < DZERO) 12013 { 12014 tprev = tdiff; 12015 ksign++; 12016 if (ksign > 1) ksimple = 0; 12017 } 12018 } 12019 12020 if (kbez == 0) 12021 { 12022 /* We permit status simple case only in bezier case. 12023 However, if the surface is strictly concav in one 12024 parameter direction, we have found 12025 the max on the edges. */ 12026 kconvex2 = 0; 12027 kconcav2 = ((tfirst < DZERO) && kconcav2); 12028 } 12029 else 12030 { 12031 12032 kconvex2 = (((ksign == 0) || 12033 (ksign == 1 && tfirst >= DZERO)) && kconvex2); 12034 kconcav2 = (((ksign == 0) || 12035 (ksign == 1 && tfirst <= DZERO)) && kconcav2); 12036 } 12037 ksimple = ((kconvex2 || kconcav2) && ksimple); 12038 } 12039 12040 /* Simple case test performed. */ 12041 12042 if (ksimple) 12043 { 12044 if (kconvex1 && kconvex2) 12045 *jsimple = 1; 12046 else 12047 *jsimple = 0; 12048 } 12049 else 12050 *jsimple = 2; 12051 *jstat = 0; 12052 12053 return; 12054 } 12055 12056 //=========================================================================== 12057 void s1162(SISLObject *po1,double *cmax,double aepsge, SISLIntdat **pintdat, 12058 SISLEdge *vedge[2], int ilevel,int inum,int *jstat) 12059 //=========================================================================== 12060 { 12061 int klevel; /* Local - Debt in recursion with. */ 12062 int knumedge; /* Local - Number of max. on the edges*/ 12063 int kpos = 0; /* Position of error. */ 12064 int kstat = 0; /* Local error status. */ 12065 int ksimple = 0; /* Local simple case status. */ 12066 int kdiv = 0; /* Parameter direction of subdivsion. */ 12067 int knum; /* Number of edges in subproblems. */ 12068 int ki; /* Counter. */ 12069 int kind1,kind2; /* Index two knots with multiplicity. */ 12070 SISLObject *uob1[4]; /* Pointers to subdivided object. */ 12071 SISLObject *qdum; /* Pointer to dummy object. */ 12072 SISLEdge **uedge=SISL_NULL; /* Pointer to array (to be allocated) 12073 of edges to use in subproblems. */ 12074 SISLIntpt *up[2]; 12075 SISLPtedge *qpt0,*qpt1; 12076 12077 /*Init*/ 12078 knumedge = inum; 12079 klevel = ilevel; 12080 12081 for (ki=0;ki<4;ki++) uob1[ki] = SISL_NULL; 12082 if ((qdum = newObject(SISLPOINT)) == SISL_NULL) goto err101; 12083 12084 /* Initiate no maximum.*/ 12085 *jstat = 0; 12086 12087 /* Test if maximum is possible (perform box-test). */ 12088 s1190(po1,cmax,aepsge,&kstat); 12089 if (kstat < 0) goto error; 12090 12091 /* We may have four different values on kstat. 12092 kstat = 1 : The SISLbox is beyond level value. 12093 kstat = 2 : The object is of constant value. 12094 kstat = 3 : The object is beyond one of its corners. 12095 kstat = 0 : No conclusion.*/ 12096 12097 if (kstat == 1); 12098 12099 /* No max is possible */ 12100 12101 else if (kstat == 2) 12102 { 12103 /* The geometry is of constant value. Since it is not taken by 12104 the SISLbox test and the edges already are treated in s1161, 12105 we just connect the point on the edges. */ 12106 12107 12108 if (vedge[0] != SISL_NULL && vedge[0]->iedge == 2) 12109 { 12110 /* Only curves has to do connect */ 12111 12112 qpt0=vedge[0]->prpt[0]; 12113 qpt1=vedge[0]->prpt[1]; 12114 if (qpt0 != SISL_NULL && qpt1 != SISL_NULL) 12115 { 12116 12117 up[0] = qpt0->ppt; 12118 up[1] = qpt1->ppt; 12119 s6idcon(pintdat,&up[0],&up[1],&kstat); 12120 if (kstat<0) goto error; 12121 } 12122 } 12123 } 12124 12125 else if (kstat == 3); 12126 12127 12128 /* Maximum for the object is a corner value, it has been found 12129 while treating the edges. */ 12130 12131 12132 else 12133 { 12134 /* Simple Case test (more than one maximum possible?) */ 12135 if(po1->iobj ==SISLCURVE) 12136 12137 s1119(po1->c1->ecoef,po1->c1->et,po1->c1->et, 12138 po1->c1->ik,po1->c1->in, 12139 1,1,&ksimple,&kind1,&kind2,&kstat); 12140 12141 else 12142 s1119(po1->s1->ecoef,po1->s1->et1,po1->s1->et2, 12143 po1->s1->ik1,po1->s1->in1, 12144 po1->s1->ik2,po1->s1->in2,&ksimple,&kind1,&kind2,&kstat); 12145 if (kstat < 0) goto error; 12146 12147 /* We may have three different values on ksimple. 12148 ksimple = 0 : Not possible with interior max. 12149 ksimple = 1 : Simpel case 12150 ksimple = 2 : Not simpel case.*/ 12151 12152 if (ksimple == 0) 12153 *jstat = 0; 12154 12155 else if (ksimple == 1) 12156 { 12157 /* Simple Case, uppdate maximum list. */ 12158 12159 s1162_s9update(po1,cmax,aepsge,pintdat,vedge,&kstat); 12160 if (kstat < 0) goto error; 12161 *jstat = kstat; 12162 12163 } 12164 else 12165 { 12166 /* Check for interval maximum.*/ 12167 12168 s1162_s9con(po1,cmax,aepsge,pintdat,vedge,&klevel,&knumedge,&kstat); 12169 if (kstat < 0) goto error; 12170 12171 /* We may have two different values on kstat. 12172 kstat = 0 : No intervall maximum. 12173 kstat = 1 : More than 2 maximum found on the edges. 12174 (bezier case only). 12175 kstat = 2 : Intervall maximum found. 12176 kstat = 3 : Simple case */ 12177 12178 if (kstat == 3) 12179 /* Simple Case, uppdate maximum list. */ 12180 { 12181 12182 s1162_s9update(po1,cmax,aepsge,pintdat,vedge,&kstat); 12183 if (kstat < 0) goto error; 12184 *jstat = kstat; 12185 } 12186 12187 else if (kstat == 2) 12188 12189 *jstat = kstat; /*Uppdating maximum found. */ 12190 12191 else 12192 { 12193 /* Find number of possible subdivision directions. 12194 kdiv may have 4 difference values : 12195 kdiv = 0 : Subdivision not possible. 12196 kdiv = 1 : Subdivision in first parameter direction. 12197 kdiv = 2 : Subdivision in second parameter direction. 12198 kdiv = 3 : Subdivision in both parameter directions. */ 12199 12200 s1162_s9num(po1,&kdiv,&kstat); 12201 if (kstat < 0) goto error; 12202 12203 12204 if(kdiv == 0) 12205 { 12206 /* Microcase in parameter plane.*/ 12207 12208 s1162_s9mic(po1,qdum,pintdat,vedge,&kstat); 12209 if (kstat < 0) goto error; 12210 else *jstat = kstat; 12211 } 12212 else 12213 { 12214 /* We do not have simpel case and it is possible to 12215 subdivide. We therfor subdivide and uppdate the 12216 edge maximum and then do a recurcive call 12217 to treat the sub problems. Curves are subdivided 12218 into two, surfaces into four. We can therfor get 12219 up to four recursive calls.*/ 12220 12221 /* Computing total number of subobjects in sub problems. */ 12222 knum = (kdiv<3 ? 2:4); 12223 12224 /***** Treating objects on sub problems. *****/ 12225 12226 if (kdiv > 0) /* New objects for subdivision of po1. */ 12227 { 12228 for (ki=0;ki<knum;ki++) 12229 { 12230 if ((uob1[ki] = newObject(po1->iobj)) == SISL_NULL) 12231 goto err101; 12232 12233 /*Initiate o1 pointer to point to top level object.*/ 12234 12235 uob1[ki]->o1 = po1->o1; 12236 } 12237 12238 /* Subdivide the po1 object. */ 12239 12240 s1162_s9div(po1,cmax,aepsge,kdiv,kind1,kind2, 12241 uob1,pintdat,vedge,klevel,&kstat); 12242 if (kstat < 0) goto error; 12243 *jstat = max(*jstat,kstat); 12244 12245 } 12246 12247 /***** Treating edges on sub problems. *****/ 12248 12249 12250 /* Making array of pointers to edge object 12251 to the sub problems. */ 12252 if ((uedge = new0array(2*knum,SISLEdge *)) == SISL_NULL) 12253 goto err101; 12254 12255 /* Making new edge object to sub problems. */ 12256 for (ki=0; ki<2*knum; ki+=2) 12257 { 12258 12259 if ((uedge[ki] = newEdge(vedge[0]->iedge)) == SISL_NULL) 12260 goto err101; 12261 /* No edge for the dummy point: */ 12262 uedge[ki+1] = SISL_NULL; 12263 12264 } 12265 12266 12267 /***** Recursion. *****/ 12268 for (ki=0;ki<knum;ki+=1) 12269 { 12270 12271 /* Uppdate edge maximum on sub problems. */ 12272 s1162_s9edge(uob1+ki, &qdum, 1, 1, *pintdat, 12273 uedge+2*ki, &kstat); 12274 if (kstat < 0) goto error; 12275 12276 s1162(uob1[ki],cmax,aepsge,pintdat, 12277 uedge+2*ki,klevel,knumedge,&kstat); 12278 if (kstat < 0) goto error; 12279 else *jstat = max(*jstat, kstat); 12280 } 12281 } 12282 } 12283 } 12284 } 12285 12286 /* Intersections in the inner found. */ 12287 12288 goto out; 12289 12290 /* Error in space allocation. */ 12291 err101: *jstat = -101; 12292 s6err("s1162",*jstat,kpos); 12293 goto out; 12294 12295 /* Error in lower level routine. */ 12296 error : *jstat = kstat; 12297 s6err("s1162",*jstat,kpos); 12298 goto out; 12299 12300 /* Free the space that is allocated. */ 12301 12302 out: 12303 if (qdum != SISL_NULL) freeObject(qdum); 12304 12305 for (ki=0;ki<4;ki++) 12306 if (uob1[ki] != SISL_NULL) freeObject(uob1[ki]); 12307 12308 if (uedge != SISL_NULL) 12309 { 12310 /* 26.10.92 UJK/ BEOrd13969 */ 12311 /* for (ki=0;ki<knum;ki++) */ 12312 for (ki=0;ki<2*knum;ki++) 12313 if (uedge[ki] != SISL_NULL) freeEdge(uedge[ki]); 12314 12315 freearray(uedge); 12316 } 12317 } 12318 12319 12320 12321 //=========================================================================== 12322 void s1162_s9mic(SISLObject *po1,SISLObject *po2,SISLIntdat **rintdat, 12323 SISLEdge *vedge[],int *jstat) 12324 //=========================================================================== 12325 { 12326 int kpos = 0; /* Position of error. */ 12327 int kstat=0; /* Local error status. */ 12328 int kpoint; /* Number of intpt on edges. */ 12329 double *spar = SISL_NULL; /* Array to store parameter values. */ 12330 SISLIntpt **up = SISL_NULL; /* Array of poiners to intersection point. */ 12331 12332 12333 /* Initiate to now new intersection point. */ 12334 12335 12336 *jstat = 0; 12337 12338 12339 /* Compute number of intersection points on edges. */ 12340 12341 if (vedge[0] == SISL_NULL ) 12342 kpoint = 0; 12343 else 12344 kpoint = vedge[0]->ipoint; 12345 12346 if (vedge[1] != SISL_NULL ) 12347 kpoint += vedge[1]->ipoint; 12348 12349 12350 if (kpoint == 0 ) 12351 { 12352 int kpar = 0; 12353 SISLIntpt *qt; 12354 12355 12356 /* There is not any intersection points on the edges. 12357 We therfor make one new intersection point with parameter 12358 values in senter of each object. */ 12359 12360 12361 /* Number of parameter values of object 1. */ 12362 12363 if (po1->iobj == SISLCURVE) kpar = 1; 12364 else if (po1->iobj == SISLSURFACE) kpar = 2; 12365 12366 12367 /* Number of parameter values of object 2. */ 12368 12369 if (po2->iobj == SISLCURVE) kpar++; 12370 else if (po2->iobj == SISLSURFACE) kpar += 2; 12371 12372 12373 /* Allocate array to store midpoint parameter values. */ 12374 12375 if ((spar = newarray(kpar,double)) == SISL_NULL) 12376 goto err101; 12377 12378 12379 /* Compute midpoint parameter values. */ 12380 12381 if (po1->iobj == SISLCURVE) 12382 { 12383 spar[0] = (po1->c1->et[po1->c1->ik - 1] + 12384 po1->c1->et[po1->c1->in])*(double)0.5; 12385 kpar = 1; 12386 } 12387 else if (po1->iobj == SISLSURFACE) 12388 { 12389 spar[0] = (po1->s1->et1[po1->s1->ik1 - 1] + 12390 po1->s1->et1[po1->s1->in1])*(double)0.5; 12391 spar[1] = (po1->s1->et2[po1->s1->ik2 - 1] + 12392 po1->s1->et2[po1->s1->in2])*(double)0.5; 12393 kpar = 2; 12394 } 12395 12396 if (po2->iobj == SISLCURVE) 12397 { 12398 spar[kpar] = (po2->c1->et[po2->c1->ik - 1] + 12399 po2->c1->et[po2->c1->in])*(double)0.5; 12400 kpar++; 12401 } 12402 else if (po2->iobj == SISLSURFACE) 12403 { 12404 spar[kpar] = (po2->s1->et1[po2->s1->ik1 - 1] + 12405 po2->s1->et1[po2->s1->in1])*(double)0.5; 12406 spar[kpar+1] = (po2->s1->et2[po2->s1->ik2 - 1] + 12407 po2->s1->et2[po2->s1->in2])*(double)0.5; 12408 kpar += 2; 12409 } 12410 12411 *jstat = 1; /* Mark intersection found. */ 12412 12413 12414 /* Makeing intersection point. */ 12415 12416 qt = newIntpt(kpar,spar,DZERO); 12417 if (qt == SISL_NULL) goto err101; 12418 12419 /* Uppdating pintdat. */ 12420 12421 s6idnpt(rintdat,&qt,1,&kstat); 12422 if (kstat < 0) goto error; 12423 } 12424 else if (kpoint > 1) 12425 { 12426 int kn,kn1,ki,kj; 12427 SISLPtedge *qpt; 12428 12429 12430 /* We have more than one intersection point on the edges, 12431 we therfor conect these points to each other. */ 12432 12433 /* Allacate array of pointers to these points. */ 12434 12435 if ((up = newarray(kpoint,SISLIntpt *)) == SISL_NULL) goto err101; 12436 12437 12438 /* Uppdate the array. */ 12439 12440 for (kn=0,kn1=0; kn<2; kn++) 12441 if (vedge[kn] != SISL_NULL && vedge[kn]->ipoint > 0) 12442 for(kj=0; kj<vedge[kn]->iedge; kj++) 12443 for(qpt=vedge[kn]->prpt[kj]; qpt != SISL_NULL; qpt=qpt->pnext,kn1++) 12444 up[kn1] = qpt->ppt; 12445 12446 12447 /* Connect the points to each other. */ 12448 12449 for (ki=1; ki<kpoint; ki++) 12450 { 12451 s6idcon(rintdat,&up[ki-1],&up[ki],&kstat); 12452 if (kstat<0) goto error; 12453 } 12454 } 12455 12456 goto out; 12457 12458 /* Error in space allocation. */ 12459 12460 err101: *jstat = -101; 12461 s6err("s1162_s9mic",*jstat,kpos); 12462 goto out; 12463 12464 /* Error in lower level routine. */ 12465 12466 error : *jstat = kstat; 12467 s6err("s1162_s9mic",*jstat,kpos); 12468 goto out; 12469 12470 out: if (spar != SISL_NULL) freearray(spar); 12471 if (up != SISL_NULL) freearray(up); 12472 } 12473 12474 //=========================================================================== 12475 void s1162_s9num(SISLObject *po,int *jdiv,int *jstat) 12476 //=========================================================================== 12477 { 12478 *jstat = 0; 12479 if (po->iobj == SISLPOINT) *jdiv = 0; 12480 else if (po->iobj == SISLCURVE) 12481 { 12482 if(s1791(po->c1->et,po->c1->ik,po->c1->in)) *jdiv = 1; 12483 else *jdiv = 0; 12484 } 12485 else if (po->iobj == SISLSURFACE) 12486 { 12487 if(s1791(po->s1->et1,po->s1->ik1,po->s1->in1)) *jdiv = 1; 12488 else *jdiv = 0; 12489 12490 if(s1791(po->s1->et2,po->s1->ik2,po->s1->in2)) *jdiv += 2; 12491 } 12492 else 12493 { 12494 12495 /* Error. Kind of object does not exist. */ 12496 12497 *jstat = -121; 12498 s6err("s1162_s9num",*jstat,0); 12499 } 12500 } 12501 12502 //=========================================================================== 12503 void s1162_s9edge(SISLObject *vob1[],SISLObject *vob2[], int iobj1,int iobj2, 12504 SISLIntdat *pintdat,SISLEdge *wedge[],int *jstat) 12505 //=========================================================================== 12506 { 12507 int kpos = 0; /* Position of error. */ 12508 int kstat=0; /* Local error status. */ 12509 int ki1,ki2,kj,kn; /* Counters. */ 12510 int kedg; /* Number of edges. */ 12511 int kpar; /* Parameter number. */ 12512 double tpar; /* Parameter value at edge. */ 12513 12514 12515 for (kn=0,ki1=0; ki1<iobj1; ki1++) 12516 for (ki2=0; ki2<iobj2; ki2++,kn+=2) 12517 { 12518 kedg = (vob1[ki1]->iobj == SISLPOINT ?0:(vob1[ki1]->iobj == SISLCURVE ?2:4)); 12519 12520 for (kj=0; kj<kedg; kj++) 12521 { 12522 if (vob1[ki1]->iobj == SISLCURVE) 12523 { 12524 tpar = (kj == 0 ? vob1[ki1]->c1->et[vob1[ki1]->c1->ik-1] : 12525 vob1[ki1]->c1->et[vob1[ki1]->c1->in]); 12526 kpar = 1; 12527 } 12528 else if (kj == 0) 12529 { 12530 tpar = vob1[ki1]->s1->et2[vob1[ki1]->s1->ik2-1]; 12531 kpar = 2; 12532 } 12533 else if (kj == 1) 12534 { 12535 tpar = vob1[ki1]->s1->et1[vob1[ki1]->s1->in1]; 12536 kpar = 1; 12537 } 12538 else if (kj == 2) 12539 { 12540 tpar = vob1[ki1]->s1->et2[vob1[ki1]->s1->in2]; 12541 kpar = 2; 12542 } 12543 else 12544 { 12545 tpar = vob1[ki1]->s1->et1[vob1[ki1]->s1->ik1-1]; 12546 kpar = 1; 12547 } 12548 12549 12550 s6idedg(vob1[ki1],vob2[ki2],1,kpar,tpar,pintdat, 12551 &(wedge[kn]->prpt[kj]),&(wedge[kn]->ipoint),&kstat); 12552 if (kstat < 0) goto error; 12553 } 12554 12555 kedg = (vob2[ki2]->iobj == SISLPOINT ?0:(vob2[ki2]->iobj == SISLCURVE ?2:4)); 12556 12557 for (kj=0; kj<kedg; kj++) 12558 { 12559 if (vob2[ki2]->iobj == SISLCURVE) 12560 { 12561 tpar = (kj == 0 ? vob2[ki2]->c1->et[vob2[ki2]->c1->ik-1] : 12562 vob2[ki2]->c1->et[vob2[ki2]->c1->in]); 12563 kpar = 1; 12564 } 12565 else if (kj == 0) 12566 { 12567 tpar = vob2[ki2]->s1->et2[vob2[ki2]->s1->ik2-1]; 12568 kpar = 2; 12569 } 12570 else if (kj == 1) 12571 { 12572 tpar = vob2[ki2]->s1->et1[vob2[ki2]->s1->in1]; 12573 kpar = 1; 12574 } 12575 else if (kj == 2) 12576 { 12577 tpar = vob2[ki2]->s1->et2[vob2[ki2]->s1->in2]; 12578 kpar = 2; 12579 } 12580 else 12581 { 12582 tpar = vob2[ki2]->s1->et1[vob2[ki2]->s1->ik1-1]; 12583 kpar = 1; 12584 } 12585 12586 12587 s6idedg(vob1[ki1],vob2[ki2],2,kpar,tpar,pintdat, 12588 &(wedge[kn+1]->prpt[kj]),&(wedge[kn+1]->ipoint),&kstat); 12589 if (kstat < 0) goto error; 12590 } 12591 } 12592 12593 *jstat = 0; 12594 12595 goto out; 12596 12597 /* Error in lower level routine. */ 12598 12599 error : *jstat = kstat; 12600 s6err("s1162_s9edge",*jstat,kpos); 12601 goto out; 12602 12603 out: ; 12604 } 12605 12606 //=========================================================================== 12607 void s1162_s9con(SISLObject *po1,double *cmax,double aepsge,SISLIntdat **pintdat, 12608 SISLEdge *vedge[],int *jlevel,int *jnum,int *jstat) 12609 //=========================================================================== 12610 { 12611 SISLIntpt *qintpt,*up[10]; 12612 SISLPtedge *qpt; 12613 12614 int kstat; /* Local status. */ 12615 /*guen int kpos; */ /* Local status counter. */ 12616 /*guen changed into:*/ 12617 int kpos = 0; /* Local status counter. */ 12618 int kk1; /* Local SURFACE attribute. */ 12619 int kk2; /* Local SURFACE attribute. */ 12620 int kn1; /* Local SURFACE attribute. */ 12621 int kn2; /* Local SURFACE attribute. */ 12622 int ki,kj; /* Local counter. */ 12623 int kfound; /* Local flag in loop. */ 12624 int knum = 0; /* Local number of max on edge. */ 12625 int klevel = 0; /* Local level. */ 12626 int kleft1 = 0; /* Local input parameter s1421 */ 12627 int kleft2 = 0; /* Local input parameter s1421 */ 12628 int kder = 1; /* Local input parameter s1421 */ 12629 12630 double spar[2]; /* Parameter value */ 12631 double spar1[2]; /* Parameter value */ 12632 double smidle[2];/* middle parameter value */ 12633 double *sval=SISL_NULL;/* Values from s1421. */ 12634 double *snorm=SISL_NULL;/* Values from s1421. */ 12635 12636 12637 kstat = 0; 12638 12639 if (po1->iobj == SISLSURFACE) 12640 { 12641 if ((po1->s1->in1 == po1->s1->ik1) && (po1->s1->in2 == po1->s1->ik2)) 12642 /* Bezier case for surface */ 12643 { 12644 12645 /*-------------------------------------------------------*/ 12646 /* Count number of max on the edges. */ 12647 kk1 = po1->s1->ik1; 12648 kk2 = po1->s1->ik2; 12649 kn1 = po1->s1->in1; 12650 kn2 = po1->s1->in2; 12651 12652 for (kj=0,knum=0;kj<vedge[0]->iedge;kj++) 12653 { 12654 qpt = vedge[0]->prpt[kj]; 12655 while(qpt != SISL_NULL) 12656 { 12657 qintpt = qpt->ppt; 12658 for (ki=0,kfound=0;ki<knum && kfound == 0;ki++) 12659 if (qintpt == up[ki]) kfound = 1; 12660 12661 if (kfound == 0) 12662 { 12663 if (knum > 9) goto out; 12664 up[knum]=qintpt; 12665 knum++; 12666 } 12667 12668 qpt = qpt->pnext; 12669 } 12670 12671 } 12672 12673 /*---------------------------------------------------------*/ 12674 12675 if (knum > 0 ) 12676 /* Number of max on the edges more than 1. */ 12677 { 12678 klevel = *jlevel; 12679 12680 if (klevel == 0 || knum !=*jnum) 12681 /* No continuation of suspected singulear point, 12682 start a new one. */ 12683 { 12684 kstat = 1; 12685 klevel = 1; 12686 } 12687 else if (klevel < 2) 12688 /* Continuation of suspected singulear point. */ 12689 { 12690 kstat = 1; 12691 klevel += 1; 12692 } 12693 else if (knum < 2 ) 12694 /* Simple Case */ 12695 { 12696 kstat = 3; 12697 klevel += 1; 12698 } 12699 else 12700 { 12701 12702 /*--------------------------------------------------*/ 12703 /* Connection case. */ 12704 12705 /* Allocate local used memory */ 12706 12707 sval = newarray(4,double); 12708 if (sval == SISL_NULL) goto err101; 12709 snorm = sval + 3; 12710 12711 for (kj=0;kj<knum-1;kj++) 12712 { 12713 spar[0] = up[kj]->epar[0]; 12714 spar[1] = up[kj]->epar[1]; 12715 12716 for (ki=kj+1;ki<knum;ki++) 12717 { 12718 /* First we linearize. */ 12719 spar1[0] = up[ki]->epar[0]; 12720 spar1[1] = up[ki]->epar[1]; 12721 smidle[0] = (spar[0] + spar1[0])/(double)2.0; 12722 smidle[1] = (spar[1] + spar1[1])/(double)2.0; 12723 12724 /* Evaluate 0-1.st derivatives of surface */ 12725 12726 s1421(po1->s1,kder,smidle,&kleft1,&kleft2, 12727 sval,snorm,&kstat); 12728 if (kstat < 0) goto error; 12729 if (fabs(sval[0]-*cmax) < aepsge) 12730 { 12731 /* Connect. */ 12732 s6idcon(pintdat,&up[kj],&up[ki],&kstat); 12733 if (kstat<0) goto error; 12734 } 12735 12736 } 12737 } 12738 12739 12740 kstat = 2; 12741 /*------------------------------------------*/ 12742 12743 12744 } 12745 } 12746 } 12747 } 12748 12749 goto out; 12750 12751 /* Error in allocation */ 12752 err101: kstat = -101; 12753 s6err("s1162_s9con",kstat,kpos); 12754 goto out; 12755 12756 /* Error in lower level routine. */ 12757 error : s6err("s1162_s9con",kstat,kpos); 12758 goto out; 12759 12760 out: if (sval != SISL_NULL) freearray(sval); 12761 *jlevel = klevel; 12762 *jnum = knum; 12763 *jstat = kstat; 12764 12765 } 12766 12767 //=========================================================================== 12768 void s1162_s9update(SISLObject *po1,double *cmax,double aepsge, 12769 SISLIntdat **pintdat,SISLEdge *vedge[2],int *jstat) 12770 //=========================================================================== 12771 { 12772 int i, kj, ki; /* Counters. */ 12773 int kpos = 0; /* Position of error. */ 12774 int kstat= 0; /* Local status */ 12775 int kk1, kk2, kn1, kn2; /* Local number of knots and vertices. */ 12776 int kmax, kind1, kind2; /* Indexes of the maximum vertice. */ 12777 int kleft = 0; /* Used in s1221 . */ 12778 int kleft2 = 0; /* Used in s1424 . */ 12779 int kconn = 0; /* Connection flag. */ 12780 int knum = 0; /* Number of max on the edge. */ 12781 int kfound = 0; /* Flag. */ 12782 12783 double tstart, tend; /* Start, end values for curve parameter. */ 12784 double sstart[2], send[2]; /* Start, end values for surface parameter. */ 12785 double tpar; /* The parameter vallue for 12786 subdivision of a curve. */ 12787 double spar[2]; /* The parameter vallue for subdivision 12788 of a surface. */ 12789 double tmax, tmin; /* Local max and min value for the 12790 vertices of object. */ 12791 double tval; /* The value of the geometry at the found point.*/ 12792 12793 12794 SISLObject *qop=SISL_NULL,*qcuo = SISL_NULL;/* Help pointers */ 12795 SISLIntdat *qintdat=SISL_NULL; /* Local max data. */ 12796 SISLIntdat *qintdat1=SISL_NULL; /* Local for double upgrading. */ 12797 SISLIntpt *qintpt,*up[3]; 12798 SISLPtedge *qpt; 12799 12800 /* Init */ 12801 *jstat = 0; 12802 if (po1 == SISL_NULL || po1->iobj == SISLPOINT) goto out; 12803 if ((qop = newObject(SISLPOINT)) == SISL_NULL) goto err101; 12804 12805 if (po1->iobj == SISLCURVE) 12806 { 12807 kk1 = po1->c1->ik; 12808 kn1 = po1->c1->in; 12809 kmax = po1->c1->pbox->imax; 12810 tmax = po1->c1->pbox->emax[0]; 12811 tmin = po1->c1->pbox->emin[0]; 12812 12813 tstart = po1->c1->et[kk1-1]; 12814 tend = po1->c1->et[kn1]; 12815 12816 /* Try to find an inner ekstremal point by iteration. */ 12817 12818 12819 /* First get a good starting point for the iteration. */ 12820 tpar = 0; 12821 for (i=kmax+1;i<kmax+kk1;i++) 12822 tpar += po1->c1->et[i]; 12823 12824 tpar /= kk1 - 1; 12825 12826 s1252(po1->c1,aepsge,tpar,&tpar,&kstat); 12827 if (kstat < 0) goto error; 12828 12829 /* Test if the found point is at start or end. */ 12830 if(DEQUAL(tpar,tstart) || DEQUAL(tpar,tend)) goto out; 12831 12832 12833 /* Evaluate curve at parameter value. */ 12834 kleft = 0; 12835 s1221(po1->o1->c1,0,tpar,&kleft,&tval,&kstat); 12836 if (kstat < 0) goto error; 12837 12838 /* Here we are ready to examine if we really found a new max point.*/ 12839 if ((qop->p1 = newPoint(&tval,1,1)) == SISL_NULL) goto err101; 12840 12841 s1161(qop,cmax,aepsge,&qintdat,&kstat); 12842 if (kstat < 0) goto error; 12843 12844 if (kstat == 2) 12845 /* New maximum found, delete old ones */ 12846 if (*pintdat != SISL_NULL) 12847 { 12848 freeIntdat(*pintdat); 12849 *pintdat = SISL_NULL; 12850 } 12851 12852 if ( kstat ) 12853 { 12854 /* Maximum found, add it to the list */ 12855 *jstat = max(*jstat,kstat); /* Mark maximum found. */ 12856 12857 /* Set parameter parameter value of curve. */ 12858 s6idput(pintdat,qintdat,0,tpar,&kstat); 12859 if (kstat < 0) goto error; 12860 } 12861 12862 } 12863 else if (po1->iobj == SISLSURFACE) 12864 { 12865 12866 12867 kk1 = po1->s1->ik1; 12868 kn1 = po1->s1->in1; 12869 kk2 = po1->s1->ik2; 12870 kn2 = po1->s1->in2; 12871 kmax = po1->s1->pbox->imax; 12872 tmax = po1->s1->pbox->emax[0]; 12873 tmin = po1->s1->pbox->emin[0]; 12874 12875 sstart[0] = po1->s1->et1[kk1-1]; 12876 sstart[1] = po1->s1->et2[kk2-1]; 12877 12878 send[0] = po1->s1->et1[kn1]; 12879 send[1] = po1->s1->et2[kn2]; 12880 12881 12882 /* Get the two dimensional index of the greatest vertice. */ 12883 kind2 = kmax/kk1; 12884 kind1 = kmax - kind2*kk1; 12885 12886 12887 /*-----------------------------------------------------------*/ 12888 /* Count number of max on the edges. */ 12889 12890 for (kj=0,knum=0;kj<vedge[0]->iedge&&knum<3;kj++) 12891 { 12892 qpt = vedge[0]->prpt[kj]; 12893 while(qpt != SISL_NULL && knum<3) 12894 { 12895 qintpt = qpt->ppt; 12896 for (ki=0,kfound=0;ki<knum && kfound == 0;ki++) 12897 if (qintpt == up[ki]) kfound = 1; 12898 12899 if (kfound == 0) 12900 { 12901 up[knum]=qintpt; 12902 knum++; 12903 } 12904 12905 qpt = qpt->pnext; 12906 } 12907 12908 } 12909 12910 /* Try if connection is possible.*/ 12911 if (knum == 2) 12912 { 12913 /* if on same edge, they are be connected before 12914 (when in simple case.)*/ 12915 if ((DEQUAL(up[0]->epar[0],sstart[0]) && 12916 DEQUAL(up[1]->epar[0],sstart[0]))|| 12917 (DEQUAL(up[0]->epar[0],send[0]) && 12918 DEQUAL(up[1]->epar[0],send[0])) || 12919 (DEQUAL(up[0]->epar[1],sstart[1]) && 12920 DEQUAL(up[1]->epar[1],sstart[1]))|| 12921 (DEQUAL(up[0]->epar[1],send[1]) && 12922 DEQUAL(up[1]->epar[1],send[1]))) 12923 kconn = 0; 12924 12925 else 12926 { 12927 /* Pick out two curves between the parameter 12928 value on the edges. */ 12929 kconn = 0; 12930 ki = 0; 12931 if (fabs(up[0]->epar[0]-up[1]->epar[0]) < 12932 fabs(up[0]->epar[1]-up[1]->epar[1])) 12933 ki =1; 12934 12935 tpar = (double)0.25*up[0]->epar[ki] + 12936 (double)0.75*up[1]->epar[ki]; 12937 if ((qcuo = newObject(SISLCURVE)) == SISL_NULL) goto err101; 12938 if (ki==0) 12939 s1437(po1->s1,tpar,&(qcuo->c1),&kstat); 12940 else 12941 s1436(po1->s1,tpar,&(qcuo->c1),&kstat); 12942 if (kstat < 0) goto error; 12943 12944 s1161(qcuo,cmax,aepsge,&qintdat,&kstat); 12945 if (kstat < 0) goto error; 12946 12947 if (kstat == 1) 12948 { 12949 freeCurve(qcuo->c1); 12950 qcuo->c1 = SISL_NULL; 12951 12952 tpar = (double)0.75*up[0]->epar[ki] + 12953 (double)0.25*up[1]->epar[ki]; 12954 if (ki==0) 12955 s1437(po1->s1,tpar,&(qcuo->c1),&kstat); 12956 else 12957 s1436(po1->s1,tpar,&(qcuo->c1),&kstat); 12958 if (kstat < 0) goto error; 12959 12960 s1161(qcuo,cmax,aepsge,&qintdat,&kstat); 12961 if (kstat < 0) goto error; 12962 12963 if (kstat == 1) 12964 { 12965 /* Connect. */ 12966 kconn = 1; 12967 s6idcon(pintdat,&up[0],&up[1],&kstat); 12968 if (kstat<0) goto error; 12969 } 12970 } 12971 } 12972 } 12973 12974 12975 if (kconn == 0) 12976 { 12977 /* No connection is done. */ 12978 12979 /* Try to find an inner ekstremal point by iteration. */ 12980 12981 /* First get a good starting point for the iteration. */ 12982 spar[0] = 0; 12983 for (i=kind1+1;i<kind1+kk1;i++) 12984 spar[0] += po1->s1->et1[i]; 12985 12986 spar[0] /= kk1 - 1; 12987 12988 spar[1] = 0; 12989 for (i=kind2+1;i<kind2+kk2;i++) 12990 spar[1] += po1->s1->et2[i]; 12991 12992 spar[1] /= kk2 - 1; 12993 12994 12995 /* Create a point greater than the surface */ 12996 if ((qop->p1 = newPoint(&tmax,1,1)) == SISL_NULL) goto err101; 12997 12998 /* Iterate using aepsge=tmax-tmin to ensure covergence. */ 12999 s1173(qop->p1,po1->o1->s1,aepsge,sstart,send,spar,spar,&kstat); 13000 if (kstat < 0) goto error; 13001 13002 /* Test if the found point is at start or end. */ 13003 if(DEQUAL(spar[0],sstart[0]) || 13004 DEQUAL(spar[0],send[0]) || 13005 DEQUAL(spar[1],sstart[1]) || 13006 DEQUAL(spar[1],send[1])) goto out; 13007 13008 /* Evaluate surface at parameter value. */ 13009 kleft = 0; 13010 kleft2 = 0; 13011 s1424(po1->o1->s1,0,0,spar,&kleft,&kleft2,&tval,&kstat); 13012 if (kstat < 0) goto error; 13013 13014 /* Here we are ready to examine if we really found a max point.*/ 13015 freePoint(qop->p1); 13016 qop->p1 = SISL_NULL; 13017 if ((qop->p1 = newPoint(&tval,1,1)) == SISL_NULL) goto err101; 13018 13019 s1161(qop,cmax,aepsge,&qintdat,&kstat); 13020 if (kstat < 0) goto error; 13021 13022 if (kstat == 2) 13023 /* New maximum found, delete old ones */ 13024 if (*pintdat != SISL_NULL) 13025 { 13026 freeIntdat(*pintdat); 13027 *pintdat = SISL_NULL; 13028 } 13029 13030 if ( kstat ) 13031 { 13032 /* Maximum found, add them to the list */ 13033 13034 *jstat = max(*jstat,kstat); /* Mark maximum found. */ 13035 13036 /* Special treatment for putting two 13037 new parameters into pintdat from qintdat. */ 13038 s6idput(&qintdat1,qintdat,0,spar[0],&kstat); 13039 if (kstat < 0) goto error; 13040 s6idput(pintdat,qintdat1,1,spar[1],&kstat); 13041 if (kstat < 0) goto error; 13042 13043 } 13044 } 13045 } 13046 13047 13048 goto out; 13049 13050 /* -------------------ERROR SECTION----------------------------*/ 13051 13052 /* Error in space allocation. */ 13053 err101: *jstat = -101; 13054 s6err("s1162_s9update",*jstat,kpos); 13055 goto out; 13056 13057 /* Error in lower level routine. */ 13058 error : *jstat = kstat; 13059 13060 out: 13061 if (qcuo != SISL_NULL) 13062 { 13063 if (qcuo->c1 != SISL_NULL) 13064 { 13065 freeCurve(qcuo->c1); 13066 qcuo->c1 = SISL_NULL; 13067 } 13068 freeObject(qcuo); 13069 qcuo = SISL_NULL; 13070 } 13071 13072 if (qop != SISL_NULL) 13073 { 13074 if (qop->p1 != SISL_NULL) 13075 { 13076 freePoint(qop->p1); 13077 qop->p1 = SISL_NULL; 13078 } 13079 freeObject(qop); 13080 qop = SISL_NULL; 13081 } 13082 if (qintdat != SISL_NULL) 13083 { 13084 freeIntdat(qintdat); 13085 qintdat = SISL_NULL; 13086 } 13087 if (qintdat1 != SISL_NULL) 13088 { 13089 freeIntdat(qintdat1); 13090 qintdat1 = SISL_NULL; 13091 } 13092 } 13093 13094 //=========================================================================== 13095 void s1162_s9div(SISLObject *po1,double *cmax,double aepsge,int idiv,int iind1, 13096 int iind2,SISLObject *wob[],SISLIntdat **pintdat,SISLEdge *vedge[2], 13097 int ilevel,int *jstat) 13098 //=========================================================================== 13099 { 13100 13101 SISLPtedge *qpt; 13102 13103 int ki, kj,i; /* Counters. */ 13104 int kpos = 0; /* Position of error. */ 13105 int kstat= 0; /* Local status */ 13106 int kk1, kk2, kn1, kn2; /* Local number of knots and vertices. */ 13107 int kmax, kind1, kind2; /* Indexes of the maximum vertice. */ 13108 double tstart, tend; /* Start,end and middle values for curve parameter.*/ 13109 double sstart[2], send[2],tmidle;/* Start, end values for surface parameter*/ 13110 double tpar, tparold; /* The parameter vallue for subdivision curve.*/ 13111 double spar[2],sparold[2]; /* The parameter vallue for subdivision 13112 of a surface. */ 13113 double *tmax, *tmin;/* Local max and min value for the vertices of object.*/ 13114 double sdiff[2]; /* The length of parameter intervall for surface. */ 13115 double smin[2]; /* The lower allowed limit in the prameter intervall 13116 for subdividing a surface. */ 13117 double smax[2]; /* The upper allowed limit in the prameter intervall 13118 for subdividing a surface. */ 13119 SISLSurf *qs1=SISL_NULL; /* Help pointers while subdividing */ 13120 SISLSurf *qs2=SISL_NULL; /* Help pointers while subdividing */ 13121 SISLObject *qop = SISL_NULL;/* Help pointers while subdividing */ 13122 SISLObject *qoc = SISL_NULL;/* Help pointers while subdividing */ 13123 SISLIntdat *qintdat=SISL_NULL;/* Local max data for the new edges. */ 13124 13125 13126 13127 /* Init */ 13128 *jstat = 0; 13129 if ((qop = newObject(SISLPOINT)) == SISL_NULL) goto err101; 13130 13131 if (po1 == SISL_NULL || po1->iobj == SISLPOINT) 13132 /* Nothing to do. */ 13133 ; 13134 else if (po1->iobj == SISLCURVE) 13135 { 13136 kk1 = po1->c1->ik; 13137 kn1 = po1->c1->in; 13138 kmax = po1->c1->pbox->imax; 13139 tmax = po1->c1->pbox->emax; 13140 tmin = po1->c1->pbox->emin; 13141 13142 tstart = po1->c1->et[kk1-1]; 13143 tend = po1->c1->et[kn1]; 13144 13145 /* If we got problems with subdiv in max points, remove as comment: */ 13146 /* kmax = 0; */ 13147 13148 13149 /* ------------------Determination of sudiv parameter value-----------*/ 13150 if (iind1 != 0) 13151 /* We subdivide in an interior knot with multiplicity. */ 13152 tpar = po1->c1->et[iind1]; 13153 13154 else if (kmax == 0 || kmax == kn1-1) 13155 /*The greatest coeff is the first or last, divide in middlepoint. */ 13156 tpar = s1792(po1->c1->et,kk1, kn1); 13157 13158 13159 else 13160 /* Try to find an inner subdivision (ekstremal) point by iteration. */ 13161 { 13162 13163 /* First get a good starting point for the iteration. */ 13164 tpar = 0; 13165 for (i=kmax+1;i<kmax+kk1;i++) 13166 tpar += po1->c1->et[i]; 13167 13168 tpar /= kk1 - 1; 13169 tparold = tpar; 13170 13171 /*Iterate using Newton. */ 13172 s1252(po1->c1,aepsge,tpar,&tpar,&kstat); 13173 if (kstat < 0) goto error; 13174 13175 /* Test if the found point is at start or end. */ 13176 if(DEQUAL(tpar,tstart) || DEQUAL(tpar,tend)) 13177 /*Try Schoenbergs approximation to max vertice. */ 13178 { 13179 tpar = tparold; 13180 13181 if(DEQUAL(tpar,tstart) || DEQUAL(tpar,tend)) 13182 /*Divide in middlepoint. */ 13183 tpar = s1792(po1->c1->et,kk1,kn1); 13184 } 13185 } 13186 /* ------------------Subdivision -------------------------------- */ 13187 13188 /* Subdivide the curve at the given parameter value. */ 13189 s1231(po1->c1,tpar,&(wob[0]->c1),&(wob[1]->c1),&kstat); 13190 if (kstat < 0) goto error; 13191 13192 13193 /* Pick out end point from a curve. */ 13194 s1438(wob[0]->c1,1,&(qop->p1),&tpar,&kstat); 13195 if (kstat < 0) goto error; 13196 13197 13198 /* Examin if the subdividing point is a max. */ 13199 s1161(qop,cmax,aepsge,&qintdat,&kstat); 13200 if (kstat < 0) goto error; 13201 13202 if (kstat == 2) 13203 /* New maximum found, delete old ones */ 13204 if (*pintdat != SISL_NULL) 13205 { 13206 13207 freeIntdat(*pintdat); 13208 *pintdat = SISL_NULL; 13209 } 13210 13211 if (kstat) 13212 { 13213 /* Maximum found, add them to the list */ 13214 13215 *jstat = max(*jstat,kstat); /* Mark maximum found. */ 13216 13217 /* Put maximum found on edges into pintdat. */ 13218 13219 /* Set parameter border values of object. */ 13220 s6idput(pintdat,qintdat,0,tpar,&kstat); 13221 if (kstat < 0) goto error; 13222 13223 if (qintdat != SISL_NULL) 13224 { 13225 freeIntdat(qintdat); 13226 qintdat = SISL_NULL; 13227 } 13228 } 13229 } 13230 else if (po1->iobj == SISLSURFACE) 13231 { 13232 kk1 = po1->s1->ik1; 13233 kn1 = po1->s1->in1; 13234 kk2 = po1->s1->ik2; 13235 kn2 = po1->s1->in2; 13236 kmax = po1->s1->pbox->imax; 13237 tmax = po1->s1->pbox->emax; 13238 tmin = po1->s1->pbox->emin; 13239 13240 sstart[0] = po1->s1->et1[kk1-1]; 13241 sstart[1] = po1->s1->et2[kk2-1]; 13242 13243 send[0] = po1->s1->et1[kn1]; 13244 send[1] = po1->s1->et2[kn2]; 13245 13246 sdiff[0] = send[0] - sstart[0]; 13247 sdiff[1] = send[1] - sstart[1]; 13248 smin[0] = sstart[0] + (double)0.01*sdiff[0]; 13249 smin[1] = sstart[1] + (double)0.01*sdiff[1]; 13250 smax[0] = send[0] - (double)0.01*sdiff[0]; 13251 smax[1] = send[1] - (double)0.01*sdiff[0]; 13252 13253 kind2 = kmax/kn1; 13254 kind1 = kmax - kind2*kn1; 13255 13256 13257 /* If we got problems with subdiv in max points, remove as comment: */ 13258 /* kind1 = 0; */ 13259 13260 /* ------------------Determination of sudiv parameter value-------*/ 13261 if (iind1 != 0 || iind2 != 0 || ilevel > 0) 13262 { 13263 if (ilevel > 0) 13264 /* We are forced to subdivide in middlepoint. */ 13265 { 13266 spar[0] = s1792(po1->s1->et1,kk1, kn1); 13267 spar[1] = s1792(po1->s1->et2,kk2, kn2); 13268 } 13269 13270 else 13271 /*We have knot multiplicity at least in one parameter direction. 13272 Subdivide in interior knot multiplicity. If the other parameter 13273 direction is without multiplicities, subdivide in middlepoint.*/ 13274 { 13275 if (iind1 != 0) 13276 spar[0] = po1->s1->et1[iind1]; 13277 else 13278 spar[0] = s1792(po1->s1->et1,kk1, kn1); 13279 13280 if (iind2 != 0 ) 13281 spar[1] = po1->s1->et2[iind2]; 13282 else 13283 spar[1] = s1792(po1->s1->et2,kk2, kn2); 13284 } 13285 } 13286 13287 13288 else if (kind1 == 0 || kind1 == kn1-1 || kind2 == 0 || kind2 == kn2-1) 13289 { 13290 13291 /*The greatest coeff is on the edge. 13292 Examin the edge for max and divide 13293 in these parameter values. If more than one max, 13294 use the one closest to the middlepoint*/ 13295 13296 tmidle = s1792(po1->s1->et1,kk1, kn1); 13297 spar[0] = sstart[0]; 13298 13299 for (kj=0;kj<3;kj+=2) 13300 { 13301 qpt = vedge[0]->prpt[kj]; 13302 while (qpt != SISL_NULL) 13303 { 13304 if (fabs(qpt->ppt->epar[0] - tmidle) < 13305 fabs(spar[0] - tmidle)) 13306 spar[0] = qpt->ppt->epar[0]; 13307 qpt = qpt->pnext; 13308 } 13309 } 13310 if (DEQUAL(spar[0],sstart[0]) || DEQUAL(spar[0],send[0])) 13311 spar[0] = tmidle; 13312 13313 tmidle = s1792(po1->s1->et2,kk2, kn2); 13314 spar[1] = sstart[1]; 13315 13316 for (kj=1;kj<4;kj+=2) 13317 { 13318 qpt = vedge[0]->prpt[kj]; 13319 while (qpt != SISL_NULL) 13320 { 13321 if (fabs(qpt->ppt->epar[0] - tmidle) < 13322 fabs(spar[1] - tmidle)) 13323 spar[1] = qpt->ppt->epar[1]; 13324 qpt = qpt->pnext; 13325 } 13326 } 13327 if (DEQUAL(spar[1],sstart[1]) || DEQUAL(spar[1],send[1])) 13328 spar[1] = tmidle; 13329 } 13330 13331 13332 else 13333 /* Try to find an inner subdivision (ekstremal) point by iteration. */ 13334 { 13335 13336 /* First get a good starting point for the iteration. */ 13337 spar[0] = 0; 13338 for (i=kind1+1;i<kind1+kk1;i++) 13339 spar[0] += po1->s1->et1[i]; 13340 13341 spar[0] /= kk1 - 1; 13342 sparold[0] = spar[0]; 13343 13344 spar[1] = 0; 13345 for (i=kind2+1;i<kind2+kk2;i++) 13346 spar[1] += po1->s1->et2[i]; 13347 13348 spar[1] /= kk2 - 1; 13349 sparold[1] = spar[1]; 13350 13351 13352 /* Create a point greater than the surface */ 13353 if ((qop->p1 = newPoint(tmax,1,1)) == SISL_NULL) goto err101; 13354 13355 /* Iterate using Newton. */ 13356 s1173(qop->p1,po1->o1->s1,aepsge,sstart,send,spar,spar,&kstat); 13357 freePoint(qop->p1); 13358 qop->p1 = SISL_NULL; 13359 if (kstat < 0) goto error; 13360 13361 /* Test if the found point is near one edge. */ 13362 if(spar[0] < smin[0] ||spar[0] > smax[0] 13363 || spar[1] < smin[1] ||spar[1] > smax[1]) 13364 { 13365 /*Try Schoenberg. */ 13366 spar[0] = sparold[0]; 13367 spar[1] = sparold[1]; 13368 13369 if(spar[0] < smin[0] ||spar[0] > smax[0] 13370 || spar[1] < smin[1] ||spar[1] > smax[1]) 13371 { 13372 /*Divide in middlepoint. */ 13373 spar[0] = s1792(po1->s1->et1,kk1,kn1); 13374 spar[1] = s1792(po1->s1->et2,kk2,kn2); 13375 } 13376 } 13377 13378 13379 } 13380 13381 13382 /* ------------------Subdivision ------------------------------*/ 13383 /* Now we have found the parameters for subdivision, divide! */ 13384 13385 if ((qoc = newObject(SISLCURVE)) == SISL_NULL) 13386 goto err101; 13387 13388 for (ki=0; ki<(idiv<3 ? 1:3); ki++) 13389 { 13390 13391 if (idiv == 1) 13392 { 13393 s1711(po1->s1,1,spar[0],&(wob[0]->s1),&(wob[1]->s1),&kstat); 13394 if (kstat < 0) goto error; 13395 13396 /* Pick out edge curve from a surface. */ 13397 13398 s1435(wob[0]->s1,1,&(qoc->c1),spar,&kstat); 13399 if (kstat < 0) goto error; 13400 } 13401 else if (idiv == 2) 13402 { 13403 s1711(po1->s1,2,spar[1],&(wob[0]->s1),&(wob[1]->s1),&kstat); 13404 if (kstat < 0) goto error; 13405 13406 /* Pick out edge curve from a surface. */ 13407 13408 s1435(wob[0]->s1,2,&(qoc->c1),spar+1,&kstat); 13409 if (kstat < 0) goto error; 13410 } 13411 else if (ki == 0) 13412 { 13413 s1711(po1->s1,1,spar[0],&qs1,&qs2,&kstat); 13414 if (kstat < 0) goto error; 13415 13416 /* Pick out edge curve from a surface. */ 13417 13418 s1435(qs1,1,&(qoc->c1),spar,&kstat); 13419 if (kstat < 0) goto error; 13420 } 13421 else if (ki == 1) 13422 { 13423 s1711(qs1,2,spar[1],&(wob[0]->s1),&(wob[1]->s1),&kstat); 13424 if (kstat < 0) goto error; 13425 13426 /* Pick out edge curve from a surface. */ 13427 13428 s1435(wob[0]->s1,2,&(qoc->c1),spar+1,&kstat); 13429 if (kstat < 0) goto error; 13430 } 13431 else /* if (ki == 2) */ 13432 { 13433 s1711(qs2,2,spar[1],&(wob[2]->s1),&(wob[3]->s1),&kstat); 13434 if (kstat < 0) goto error; 13435 13436 /* Pick out edge curve from a surface. */ 13437 13438 s1435(wob[2]->s1,2,&(qoc->c1),spar+1,&kstat); 13439 if (kstat < 0) goto error; 13440 } 13441 13442 13443 /* Examine the new edge for max. */ 13444 13445 s1161(qoc, cmax, aepsge, &qintdat, &kstat); 13446 if (kstat < 0) goto error; 13447 13448 freeCurve(qoc->c1); 13449 qoc->c1 = SISL_NULL; 13450 13451 13452 if (kstat == 2) 13453 /* New maximum found, delete old ones */ 13454 if (*pintdat != SISL_NULL) 13455 { 13456 freeIntdat(*pintdat); 13457 *pintdat = SISL_NULL; 13458 } 13459 13460 if (kstat) 13461 { 13462 /* Maximum found, add them to the list */ 13463 13464 *jstat = max(kstat,*jstat); /* Mark maximum found. */ 13465 13466 /* Put maximum found on edges into pintdat. */ 13467 13468 /* Test if we can pick the second subdivision parameter 13469 from a max on subdiv curve.*/ 13470 if(ki==0 && qintdat->vpoint[0]->epar[0] > smin[1] 13471 && qintdat->vpoint[0]->epar[0] < smax[1] ) 13472 spar[1]=qintdat->vpoint[0]->epar[0]; 13473 13474 13475 /* Set parameter border values of object. */ 13476 s6idput(pintdat,qintdat,(ki==0 ? 0:1),spar[(ki==0 ? 0:1)],&kstat); 13477 if (kstat < 0) goto error; 13478 13479 if (qintdat != SISL_NULL) 13480 { 13481 freeIntdat(qintdat); 13482 qintdat = SISL_NULL; 13483 } 13484 13485 } 13486 13487 /* End of for (ki=/..............) */ 13488 } 13489 13490 } 13491 goto out; 13492 13493 /* -------------------ERROR SECTION------------------------------------*/ 13494 13495 /* Error in space allocation. */ 13496 err101: *jstat = -101; 13497 s6err("s1162_s9div",*jstat,kpos); 13498 goto out; 13499 13500 /* Error in lower level routine. */ 13501 error : *jstat = kstat; 13502 s6err("s1162_s9div",*jstat,kpos); 13503 goto out; 13504 /* -------------------END OF ERROR SECTION----------------------------*/ 13505 13506 out: 13507 if (qop != SISL_NULL) freeObject(qop); 13508 if (qoc != SISL_NULL) freeObject(qoc); 13509 if (qs1 != SISL_NULL) freeSurf(qs1); /* PFU 15/07-94 */ 13510 if (qs2 != SISL_NULL) freeSurf(qs2); /* PFU 15/07-94 */ 13511 } 13512 13513 13514 13515 //=========================================================================== 13516 SISLIntpt *hp_copyIntpt (SISLIntpt * ppt) 13517 //=========================================================================== 13518 { 13519 SISLIntpt *qcopy; /* Local pointer to copied intersection point. */ 13520 13521 /* Create copy. */ 13522 13523 qcopy = hp_newIntpt (ppt->ipar, ppt->epar, ppt->adist, ppt->iinter, 13524 ppt->left_obj_1[0], ppt->right_obj_1[0], 13525 ppt->left_obj_2[0], ppt->right_obj_2[0], 13526 ppt->size_1, ppt->size_2, ppt->geo_data_1, 13527 ppt->geo_data_2); 13528 if (qcopy == SISL_NULL) 13529 goto err101; 13530 13531 /* Copy made. */ 13532 13533 goto out; 13534 13535 /* Error in space allocation. Return zero. */ 13536 13537 err101:goto out; 13538 13539 out:return (qcopy); 13540 } 13541 13542 13543 //=========================================================================== 13544 SISLIntpt *copyIntpt (SISLIntpt * ppt) 13545 //=========================================================================== 13546 { 13547 SISLIntpt *qcopy; /* Local pointer to copied intersection point. */ 13548 13549 /* Create copy. */ 13550 13551 qcopy = newIntpt (ppt->ipar, ppt->epar, ppt->adist); 13552 if (qcopy == SISL_NULL) 13553 goto err101; 13554 13555 /* Set remaining parameter. */ 13556 13557 qcopy->iinter = ppt->iinter; 13558 13559 /* Copy made. */ 13560 13561 goto out; 13562 13563 /* Error in space allocation. Return zero. */ 13564 13565 err101:goto out; 13566 13567 out:return (qcopy); 13568 } 13569 13570 13571 //=========================================================================== 13572 void s6idcon_s9endturn(SISLIntdat *pintdat,SISLIntpt *pt) 13573 //=========================================================================== 13574 { 13575 register int ki; 13576 13577 while(1) 13578 { 13579 for (ki=0; ki < pintdat->ipoint; ki++) 13580 if (pintdat->vpoint[ki]->pcurve == pt) 13581 break; 13582 13583 if (ki < pintdat->ipoint) 13584 pt = pintdat->vpoint[ki]; 13585 else 13586 break; 13587 } 13588 13589 s6idcon_s9turn(pt); 13590 } 13591 13592 13593 //=========================================================================== 13594 void s6idcon_s9turn(SISLIntpt *pt) 13595 //=========================================================================== 13596 { 13597 register SISLIntpt *pt1,*pt2;/* Help pointer to traverse lists.*/ 13598 13599 pt1 = pt->pcurve; 13600 pt2 = pt1->pcurve; 13601 pt->pcurve = SISL_NULL; 13602 pt1->pcurve = pt; 13603 13604 while (pt2 != SISL_NULL) 13605 { 13606 pt = pt1; 13607 pt1 = pt2; 13608 pt2 = pt2->pcurve; 13609 pt1->pcurve = pt; 13610 } 13611 } 13612 13613 13614 //=========================================================================== 13615 void s6idcon(SISLIntdat **pintdat,SISLIntpt **pintpt1,SISLIntpt **pintpt2,int *jstat) 13616 //=========================================================================== 13617 { 13618 int kstat; /* Local status variable. */ 13619 /*guen int kpos; */ /* Position of error. */ 13620 /*guen changed into:*/ 13621 int kpos=0; /* Position of error. */ 13622 13623 int kfirst1,kfirst2; /* To mark if the point is first in the list. */ 13624 int ki1,ki2; /* Counters */ 13625 SISLIntpt *qpt1,*qpt2; 13626 13627 13628 /* First we have to be sure that pintdat contain the two points. */ 13629 13630 s6idnpt(pintdat,pintpt1,1,&kstat); 13631 if (kstat < 0) goto error; 13632 13633 s6idnpt(pintdat,pintpt2,1,&kstat); 13634 if (kstat < 0) goto error; 13635 13636 13637 qpt1 = *pintpt1; 13638 qpt2 = *pintpt2; 13639 13640 13641 /* Then we have to be sure that we do not have the same points as 13642 copies, junction points. */ 13643 13644 if (qpt1->iinter == 2 || qpt2->iinter == 2) 13645 { 13646 if (qpt1->iinter == 2 && qpt2->iinter == 2) 13647 { 13648 for (ki1=0; ki1 < qpt1->ipar; ki1++) 13649 if (qpt1->epar[ki1] != qpt2->epar[ki1]) break; 13650 13651 if (ki1 == qpt1->ipar) 13652 { 13653 *jstat = 3; 13654 goto out; 13655 } 13656 } 13657 13658 if (qpt1->iinter == 2) 13659 { 13660 for (ki1=0; ki1 < (*pintdat)->ipoint; ki1++) 13661 { 13662 for (ki2=0; ki2 < qpt1->ipar; ki2++) 13663 if (qpt1->epar[ki2] != (*pintdat)->vpoint[ki1]->epar[ki2]) 13664 break; 13665 13666 if (ki2 == qpt1->ipar) 13667 { 13668 /* UJK && ALA 19.09.90 qpt1 changed to qpt2. */ 13669 13670 if (qpt2->pcurve == (*pintdat)->vpoint[ki1] || 13671 (*pintdat)->vpoint[ki1]->pcurve == qpt2) 13672 { 13673 /* The points are already connected. */ 13674 *jstat = 1; 13675 goto out; 13676 } 13677 } 13678 } 13679 } 13680 13681 if (qpt2->iinter == 2) 13682 { 13683 for (ki1=0; ki1 < (*pintdat)->ipoint; ki1++) 13684 { 13685 for (ki2=0; ki2 < qpt2->ipar; ki2++) 13686 if (qpt2->epar[ki2] != (*pintdat)->vpoint[ki1]->epar[ki2]) 13687 break; 13688 13689 if (ki2 == qpt2->ipar) 13690 { 13691 /* UJK && ALA 19.09.90 qpt2 changed to qpt1. */ 13692 if (qpt1->pcurve == (*pintdat)->vpoint[ki1] || 13693 (*pintdat)->vpoint[ki1]->pcurve == qpt1) 13694 { 13695 /* The points are already connected. */ 13696 *jstat = 1; 13697 goto out; 13698 } 13699 } 13700 } 13701 } 13702 } 13703 13704 13705 13706 if (qpt1 == qpt2) 13707 /* There is only one point. */ 13708 *jstat = 2; 13709 if (qpt1->pcurve == qpt2 || qpt2->pcurve == qpt1) 13710 /* The points are already connected. */ 13711 *jstat = 1; 13712 else 13713 { 13714 /* We have to be sure that if one of the points is in the end of 13715 a list than this point is the first point. */ 13716 13717 if (qpt1->pcurve != SISL_NULL && qpt2->pcurve == SISL_NULL) 13718 { 13719 SISLIntpt *pt; 13720 13721 pt = qpt1; 13722 qpt1 = qpt2; 13723 qpt2 = pt; 13724 } 13725 13726 /* Computing the index of the point pointing to the first point. */ 13727 13728 for (ki1=0; ki1<(*pintdat)->ipoint; ki1++) 13729 if ((*pintdat)->vpoint[ki1]->pcurve == qpt1) 13730 break; 13731 13732 if ( ki1 < (*pintdat)->ipoint) 13733 kfirst1 = 0; 13734 else 13735 kfirst1 = 1; 13736 13737 /* Computing the index of the point pointing to the sescond point. */ 13738 13739 for (ki2=0; ki2<(*pintdat)->ipoint; ki2++) 13740 if ((*pintdat)->vpoint[ki2]->pcurve == qpt2) 13741 break; 13742 13743 if ( ki2 < (*pintdat)->ipoint) 13744 kfirst2 = 0; 13745 else 13746 kfirst2 = 1; 13747 13748 /* If the first point is not at end, than we have to 13749 reorganize the first list. */ 13750 13751 if (qpt1->pcurve != SISL_NULL) 13752 { 13753 if (kfirst1) 13754 s6idcon_s9turn(qpt1); /* First point is at start. */ 13755 else /* First point is internal. */ 13756 { 13757 /* We have a junction point. We therfor make a copy of 13758 this point, and set this copy to the first point. */ 13759 13760 qpt1->iinter = 2; 13761 13762 if((qpt1 = copyIntpt(qpt1)) == SISL_NULL) goto err101; 13763 13764 s6idnpt(pintdat,&qpt1,0,&kstat); 13765 if (kstat < 0) goto error; 13766 } 13767 } 13768 13769 13770 if (kfirst2) /*Second point is at start.*/ 13771 qpt1->pcurve = qpt2; 13772 else if (qpt2->pcurve == SISL_NULL) /* Second point is at end. */ 13773 { 13774 s6idcon_s9endturn(*pintdat,qpt2); 13775 qpt1->pcurve = qpt2; 13776 } 13777 else /* Second point is an internal point. */ 13778 { 13779 /* We have a junction point. We therfor make a copy of 13780 this point, and set the first point to point to this copy. */ 13781 13782 qpt2->iinter = 2; 13783 13784 if((qpt2 = copyIntpt(qpt2)) == SISL_NULL) goto err101; 13785 13786 s6idnpt(pintdat,&qpt2,0,&kstat); 13787 if (kstat < 0) goto error; 13788 13789 qpt1->pcurve = qpt2; 13790 } 13791 *jstat = 0; 13792 } 13793 13794 goto out; 13795 13796 13797 /* Error in space allocation. */ 13798 13799 err101: *jstat = -101; 13800 s6err("s6idcon",*jstat,kpos); 13801 goto out; 13802 13803 /* Error in sub function. */ 13804 13805 error: *jstat = kstat; 13806 s6err("s6idcon",*jstat,kpos); 13807 goto out; 13808 13809 out: ; 13810 } 13811 13812 13813 //=========================================================================== 13814 void s6idput(SISLIntdat **rintdat,SISLIntdat *pintdat,int inr,double apar,int *jstat) 13815 //=========================================================================== 13816 { 13817 int kstat; /* Local status variable. */ 13818 /*guen int kpos; */ /* Position of error. */ 13819 /*guen changed into: */ 13820 int kpos=0; /* Position of error. */ 13821 int ki,kj; /* Counters */ 13822 int kant; /* Number of parameters in new points. */ 13823 double *spar = SISL_NULL; /* Storing uppdated parametervalues. */ 13824 SISLIntpt **uintpt = SISL_NULL; /* Pointers to new intersection points. */ 13825 13826 13827 /* We have to be sure that we have an intdat structure. */ 13828 13829 if (pintdat == SISL_NULL) 13830 { 13831 *jstat = 0; 13832 goto out; 13833 } 13834 13835 /* Computing number of new parameter direction. */ 13836 13837 kant = pintdat->vpoint[0]->ipar + 1; 13838 13839 13840 if (inr<0 || inr>=kant) goto err191; 13841 13842 13843 /* Allocating an array for intersection points. */ 13844 13845 if ((uintpt = newarray(pintdat->ipoint,SISLIntpt *)) == SISL_NULL) 13846 goto err101; 13847 13848 /* Allocating an array for parametervalues. */ 13849 13850 if ((spar = newarray(kant,double)) == SISL_NULL) 13851 goto err101; 13852 13853 13854 /* Making copies of all intersection points. */ 13855 13856 for (ki=0; ki<pintdat->ipoint; ki++) 13857 { 13858 /* First we have to insert the missing parameter value. */ 13859 13860 for(kj=0; kj<inr; kj++) spar[kj] = pintdat->vpoint[ki]->epar[kj]; 13861 spar[kj] = apar; 13862 for(kj++; kj<kant; kj++) spar[kj] = pintdat->vpoint[ki]->epar[kj-1]; 13863 13864 13865 /* UJK,01-91 bringing over the adist value ! */ 13866 uintpt[ki] = newIntpt(kant,spar,pintdat->vpoint[ki]->adist); 13867 } 13868 13869 13870 /* Than we can insert all new intersection points in rintdat. */ 13871 13872 for (ki=0; ki<pintdat->ipoint; ki++) 13873 { 13874 s6idnpt(rintdat,&uintpt[ki],1,&kstat); 13875 if (kstat < 0) goto error; 13876 } 13877 13878 /* Than we can uppdate all pcurve pointers (lists). */ 13879 13880 for (ki=0; ki<pintdat->ipoint; ki++) 13881 if (pintdat->vpoint[ki]->pcurve != SISL_NULL) 13882 { 13883 for (kj=0;kj<pintdat->ipoint;kj++) 13884 if (pintdat->vpoint[ki]->pcurve == pintdat->vpoint[kj]) 13885 break; 13886 13887 if (kj == pintdat->ipoint) goto err190; 13888 13889 s6idcon(rintdat,&uintpt[ki],&uintpt[kj],&kstat); 13890 if (kstat < 0) goto error; 13891 } 13892 13893 13894 *jstat = 0; 13895 goto out; 13896 13897 13898 /* Error in inserted parameter number. */ 13899 13900 err191: *jstat = -191; 13901 s6err("s6idput",*jstat,kpos); 13902 goto out; 13903 /* Error in intersection list. */ 13904 13905 err190: *jstat = -190; 13906 s6err("s6idput",*jstat,kpos); 13907 goto out; 13908 13909 /* Error in space allocation. */ 13910 13911 err101: *jstat = -101; 13912 s6err("s6idput",*jstat,kpos); 13913 goto out; 13914 13915 /* Error in sub function. */ 13916 13917 error: *jstat = kstat; 13918 s6err("s6idput",*jstat,kpos); 13919 goto out; 13920 13921 out: if (uintpt != SISL_NULL) freearray(uintpt); 13922 if (spar != SISL_NULL) freearray(spar); 13923 } 13924 13925 13926 //=========================================================================== 13927 void s1192_s9mbox(double ecoef[], int in1,int in2,double aepsge, 13928 double *cmax, double *cmin,int *jmax,int *jmin) 13929 //=========================================================================== 13930 { 13931 int ki,kj,li[4]; /* Counters. */ 13932 int icorn; /* Number of corners in object. */ 13933 int kmin, kmax; /* Index for max and min corner value. */ 13934 double tmin, tmax; /* Max and min corner value. */ 13935 13936 /* Compute the indexes of the (up to four) corners. */ 13937 li[0] = 0; 13938 li[1] = in1 -1; 13939 li[2] = in1*(in2 - 1); 13940 li[3] = in1*in2 - 1; 13941 13942 /* Set number of corners. 13943 for point, curve, surface. */ 13944 if(in1 == 1) 13945 { 13946 if(in2 == 1) 13947 icorn = 0; 13948 else 13949 icorn = 2; 13950 } 13951 else 13952 icorn = 4; 13953 13954 /* Now find the max and min corner. */ 13955 tmax = tmin = ecoef[li[0]]; 13956 kmin = kmax = 0; 13957 13958 for (ki = 1; ki < icorn; ki++) 13959 { 13960 if (ecoef[li[ki]] > tmax) 13961 { 13962 tmax = ecoef[li[ki]]; 13963 kmax = li[ki]; 13964 } 13965 13966 if (ecoef[li[ki]] < tmin) 13967 { 13968 tmin = ecoef[li[ki]]; 13969 kmin = li[ki]; 13970 } 13971 } 13972 13973 /* Now find the max and min for the inner of the object. */ 13974 *cmax = tmax - (double)1000.0; 13975 *jmax = -1; 13976 *cmin = tmin + (double)1000.0; 13977 *jmin = -1; 13978 13979 for (ki = 0; ki < icorn - 1; ki++) 13980 for (kj = li[ki] + 1; kj < li[ki + 1]; kj++) 13981 { 13982 if (ecoef[kj] > *cmax) 13983 { 13984 *cmax = ecoef[kj]; 13985 *jmax = kj; 13986 } 13987 13988 if (ecoef[kj] < *cmin) 13989 { 13990 *cmin = ecoef[kj]; 13991 *jmin = kj; 13992 } 13993 } 13994 13995 13996 /* At last compare the corner values against the interior ones */ 13997 13998 if (tmax > *cmax + aepsge) 13999 { 14000 *cmax = tmax; 14001 *jmax = kmax; 14002 } 14003 14004 if (tmin < *cmin - aepsge) 14005 { 14006 *cmin = tmin; 14007 *jmin = kmin; 14008 } 14009 } 14010 14011 14012 //=========================================================================== 14013 void s1192(SISLObject *po,double aepsge,int *jstat) 14014 //=========================================================================== 14015 { 14016 int kpos = 0; /* Position of error. */ 14017 14018 14019 if (po -> iobj == SISLPOINT) 14020 { 14021 if (po->p1->idim != 1) goto err105; 14022 14023 if (po->p1->pbox == SISL_NULL) 14024 { 14025 if ((po->p1->pbox = newbox(po->p1->idim))==SISL_NULL) 14026 goto err101; 14027 14028 s1192_s9mbox(po->p1->ecoef,1,1,aepsge, 14029 po->p1->pbox->emax,po->p1->pbox->emin, 14030 &po->p1->pbox->imax,&po->p1->pbox->imin); 14031 14032 14033 } 14034 } 14035 else 14036 if (po -> iobj == SISLCURVE) 14037 { 14038 if (po->c1->idim != 1) goto err105; 14039 if (po->c1->pbox == SISL_NULL) 14040 { 14041 if ((po->c1->pbox = newbox(po->c1->idim))==SISL_NULL) 14042 goto err101; 14043 14044 s1192_s9mbox(po->c1->ecoef,po->c1->in,1,aepsge, 14045 po->c1->pbox->emax,po->c1->pbox->emin, 14046 &po->c1->pbox->imax,&po->c1->pbox->imin); 14047 14048 } 14049 } 14050 else 14051 if (po -> iobj == SISLSURFACE) 14052 { 14053 if (po->s1->idim != 1) goto err105; 14054 if (po->s1->pbox == SISL_NULL) 14055 { 14056 if ((po->s1->pbox = newbox(po->s1->idim))==SISL_NULL) 14057 goto err101; 14058 14059 s1192_s9mbox(po->s1->ecoef,po->s1->in1,po->s1->in2,aepsge, 14060 po->s1->pbox->emax,po->s1->pbox->emin, 14061 &po->s1->pbox->imax,&po->s1->pbox->imin); 14062 } 14063 } 14064 14065 *jstat = 0; 14066 goto out; 14067 14068 14069 /* Error in space allocation. */ 14070 14071 err101: *jstat = -101; 14072 s6err("s1192",*jstat,kpos); 14073 goto out; 14074 14075 /* Dimension not equal one. */ 14076 14077 err105: *jstat = -105; 14078 s6err("s1192",*jstat,kpos); 14079 goto out; 14080 14081 out: ; 14082 } 14083 14084 14085 //=========================================================================== 14086 void s1190(SISLObject *po1, double *cmax, double aepsge,int *jstat) 14087 //=========================================================================== 14088 { 14089 int kstat = 0; /* Local status error. */ 14090 int kpos = 0; /* Position of error. */ 14091 int kcorn = 0; /* Number of corners in object. */ 14092 int li[4]; /* Contains the indexes of the corners. */ 14093 int kbez = 0; /* Flag to mark bezier curve or patch. */ 14094 int kdim; /* Dimension of space. */ 14095 int in1,in2; /* Local number of vertices. */ 14096 int i1; /* Counter. */ 14097 int kmax; /* Index for the largest value of 14098 the vertices of the object*/ 14099 double *tmin1,*tmax1; /* Smallest and largest value of 14100 the vertices of the object*/ 14101 double scorn[4]; /* The corner values of the object*/ 14102 14103 14104 *jstat = 0; 14105 14106 /* Check kind of first object. */ 14107 14108 if (po1->iobj == SISLPOINT) 14109 { 14110 kcorn = 0; 14111 /* Fetch dimention of the object. */ 14112 14113 if((kdim = po1->p1->idim) != 1) goto err105;; 14114 14115 14116 /* Check if the SISLbox have been computed. */ 14117 14118 if (po1->p1->pbox == SISL_NULL) 14119 { 14120 /* If not compute a box. */ 14121 14122 s1192(po1,aepsge,&kstat); 14123 if (kstat<0) goto error; 14124 } 14125 14126 /* Fetch the SISLbox boarder. */ 14127 14128 kmax = po1->p1->pbox->imax; 14129 tmax1 = po1->p1->pbox->emax; 14130 tmin1 = po1->p1->pbox->emin; 14131 } 14132 else 14133 if (po1->iobj == SISLCURVE) 14134 { 14135 /* Fetch dimention of the object. */ 14136 14137 if((kdim = po1->c1->idim) != 1) goto err105;; 14138 14139 /* Fetch corners. */ 14140 14141 kcorn = 2; 14142 li[0] = 0; 14143 li[1] = po1->c1->in - 1; 14144 scorn[0] = po1->c1->ecoef[li[0]]; 14145 scorn[1] = po1->c1->ecoef[li[1]]; 14146 14147 /* Check if we have a bezier curve. */ 14148 14149 if (po1->c1->in == po1->c1->ik) kbez = 1; 14150 14151 /* Check if the SISLbox have been computed. */ 14152 14153 if (po1->c1->pbox == SISL_NULL) 14154 { 14155 /* If not compute a box. */ 14156 14157 s1192(po1,aepsge,&kstat); 14158 if (kstat<0) goto error; 14159 } 14160 14161 /* Fetch the SISLbox boarder. */ 14162 kmax = po1->c1->pbox->imax; 14163 tmax1 = po1->c1->pbox->emax; 14164 tmin1 = po1->c1->pbox->emin; 14165 } 14166 else 14167 if (po1->iobj == SISLSURFACE) 14168 { 14169 /* Fetch dimention of the object. */ 14170 14171 if((kdim = po1->s1->idim) != 1) goto err105;; 14172 14173 14174 kcorn = 4; 14175 in1 = po1->s1->in1; 14176 in2 = po1->s1->in2; 14177 li[0] = 0; 14178 li[1] = in1 - 1; 14179 li[2] = in1*(in2 - 1); 14180 li[3] = in1*in2-1; 14181 scorn[0] = po1->s1->ecoef[li[0]]; 14182 scorn[1] = po1->s1->ecoef[li[1]]; 14183 scorn[2] = po1->s1->ecoef[li[2]]; 14184 scorn[3] = po1->s1->ecoef[li[3]]; 14185 14186 /* Check if we have a bezier patch. */ 14187 14188 if (po1->s1->in1 == po1->s1->ik1 && 14189 po1->s1->in2 == po1->s1->ik2) kbez = 1; 14190 14191 /* Check if the SISLbox have been computed. */ 14192 14193 if (po1->s1->pbox == SISL_NULL) 14194 { 14195 /* If not compute a box. */ 14196 14197 s1192(po1,aepsge,&kstat); 14198 if (kstat<0) goto error; 14199 } 14200 14201 /* Fetch the SISLbox boarder. */ 14202 kmax = po1->s1->pbox->imax; 14203 tmax1 = po1->s1->pbox->emax; 14204 tmin1 = po1->s1->pbox->emin; 14205 } 14206 else goto err121; 14207 14208 14209 /* Now we've got the box, do the test: */ 14210 14211 if (*cmax - *tmax1 > aepsge) 14212 *jstat = 1; /* The object is beyond level value. */ 14213 14214 else if (*tmax1 - *tmin1 < aepsge) 14215 *jstat = 2; /* The object is of constant value. */ 14216 14217 else 14218 /* if (kbez)*/ 14219 { 14220 /*check for corner max. */ 14221 for (i1=0; i1<kcorn; i1++) 14222 if (fabs(scorn[i1] - *tmax1) < aepsge) 14223 { 14224 14225 *jstat = 3; /* Only corner touching possible.*/ 14226 break; 14227 14228 } 14229 } 14230 /* 14231 else */ 14232 /*check for absolute corner max. */ 14233 /* for (i1=0; i1<kcorn; i1++) 14234 if (kmax == li[i1]) 14235 { 14236 14237 *jstat = 3; */ /* Only corner touching possible.*/ 14238 /* break; 14239 14240 } 14241 14242 */ 14243 14244 /* Box-test performed. */ 14245 goto out; 14246 14247 /* Dimensions not equal one. */ 14248 14249 err105: *jstat = -105; 14250 s6err("s1190",*jstat,kpos); 14251 goto out; 14252 14253 /* Kind of object does not exist. */ 14254 14255 err121: *jstat = -121; 14256 s6err("s1190",*jstat,kpos); 14257 goto out; 14258 14259 /* Error in lower level routine. */ 14260 14261 error: *jstat = kstat; 14262 s6err("s1190",*jstat,kpos); 14263 goto out; 14264 14265 out: return; 14266 } 14267 14268 //=========================================================================== 14269 void s6idnpt(SISLIntdat **pintdat,SISLIntpt **pintpt,int itest,int *jstat) 14270 //=========================================================================== 14271 { 14272 register int ki,kj; /* Counters. */ 14273 14274 /* We have to be sure that we have an intdat structure. */ 14275 14276 if ((*pintdat) == SISL_NULL) 14277 { 14278 if (((*pintdat) = newIntdat()) == SISL_NULL) goto err101; 14279 } 14280 14281 14282 /* Than we have to be sure that we do not have the intersection point 14283 before or an equal point. */ 14284 14285 for (ki=0; ki<(*pintdat)->ipoint; ki++) 14286 if ((*pintdat)->vpoint[ki] == (*pintpt)) 14287 { 14288 *jstat = 1; 14289 goto out; 14290 } 14291 else if (itest && (*pintpt)->iinter != 2) 14292 { 14293 for (kj=0; kj<(*pintpt)->ipar; kj++) 14294 if (DNEQUAL((*pintpt)->epar[kj],(*pintdat)->vpoint[ki]->epar[kj])) 14295 break; 14296 14297 if (kj == (*pintpt)->ipar) 14298 { 14299 freeIntpt(*pintpt); 14300 (*pintpt) = (*pintdat)->vpoint[ki]; 14301 *jstat = 2; 14302 goto out; 14303 } 14304 } 14305 14306 14307 /* Than we have to be sure that the array vpoint is great enought. */ 14308 14309 if (ki == (*pintdat)->ipmax) 14310 { 14311 (*pintdat)->ipmax += 20; 14312 14313 if (((*pintdat)->vpoint = increasearray((*pintdat)->vpoint, 14314 (*pintdat)->ipmax,SISLIntpt *)) == SISL_NULL) 14315 goto err101; 14316 } 14317 14318 14319 /* Now we can insert the new point. */ 14320 14321 (*pintdat)->vpoint[ki] = (*pintpt); 14322 (*pintdat)->ipoint++; 14323 *jstat = 0; 14324 goto out; 14325 14326 14327 /* Error in space allocation. */ 14328 14329 err101: *jstat = -101; 14330 s6err("s6idnpt",*jstat,0); 14331 goto out; 14332 14333 out: ; 14334 } 14335 14336 //=========================================================================== 14337 SISLIntpt *newIntpt (int ipar, double *epar, double adist) 14338 //=========================================================================== 14339 { 14340 SISLIntpt *pnew; /* Local pointer to instance to create. */ 14341 int ki; /* Counter. */ 14342 14343 /* Allocate space for instance of Intpt. */ 14344 14345 pnew = newarray (1, SISLIntpt); 14346 if (pnew == SISL_NULL) 14347 goto err101; 14348 14349 /* Initialize instance. First allocate space for parameter array. */ 14350 14351 if (ipar > 0) 14352 { 14353 pnew->epar = newarray (ipar, DOUBLE); 14354 if (pnew->epar == SISL_NULL) 14355 goto err101; 14356 } 14357 14358 14359 /* Initialize the variables of the instance. */ 14360 14361 pnew->ipar = ipar; 14362 for (ki = 0; ki < ipar; ki++) 14363 pnew->epar[ki] = epar[ki]; 14364 pnew->adist = adist; 14365 pnew->pcurve = SISL_NULL; 14366 pnew->iinter = 0; 14367 14368 /* Set intersection atributes to SISL_NULL */ 14369 pnew->no_of_curves_alloc = 0; 14370 pnew->no_of_curves = 0; 14371 14372 pnew->pnext = SISL_NULL; 14373 pnew->curve_dir = SISL_NULL; 14374 pnew->left_obj_1 = SISL_NULL; 14375 pnew->left_obj_2 = SISL_NULL; 14376 pnew->right_obj_1 = SISL_NULL; 14377 pnew->right_obj_2 = SISL_NULL; 14378 pnew->geo_data_1 = SISL_NULL; 14379 pnew->size_1 = 0; 14380 pnew->geo_data_2 = SISL_NULL; 14381 pnew->size_2 = 0; 14382 14383 pnew->trim[0] = SISL_NULL; 14384 pnew->trim[1] = SISL_NULL; 14385 14386 /* Task done. */ 14387 14388 14389 goto out; 14390 14391 /* Error in space allocation. Return zero. */ 14392 14393 err101:pnew = SISL_NULL; 14394 goto out; 14395 14396 out:return (pnew); 14397 } 14398 14399 //=========================================================================== 14400 void s1161(SISLObject *po1,double *cmax,double aepsge,SISLIntdat **pintdat,int *jstat) 14401 //=========================================================================== 14402 { 14403 int klevel=0; /* Parameter into s1162 */ 14404 int knum=0; /* Parameter into s1162 */ 14405 int kpar; /* Fixed parameter direction. */ 14406 int ki; /* Counter. */ 14407 int kedge; /* Number of edges. */ 14408 int idim = 1; /* Local dimension, always = 1 */ 14409 int kstat = 0; /* Local status variable. */ 14410 int kpos = 0; /* Position of error. */ 14411 double tpar; /* Help variable used for parameter value 14412 and geometric distance. */ 14413 SISLEdge *qedge[2]; /* Edges for use in s1162(). */ 14414 SISLObject *qdum = SISL_NULL; /* Dummy pointer. */ 14415 SISLObject *qob = SISL_NULL; /* Objects for use in recurson. */ 14416 SISLIntdat *qintdat = SISL_NULL; /* Intdat for use in recurson. */ 14417 14418 qedge[0] = SISL_NULL; 14419 qedge[1] = SISL_NULL; 14420 14421 if (po1->iobj == SISLPOINT) 14422 { 14423 /* It's a point, treat the case here and return. */ 14424 14425 /* Control the dimension. */ 14426 if (po1->p1->idim != idim ) goto err106; 14427 14428 /* Computing the distance beetween the point and level value. */ 14429 tpar = po1->p1->ecoef[0] - *cmax; 14430 14431 if (fabs(tpar) <= aepsge) 14432 14433 /* The point is close enough to the level value to be a max. */ 14434 *jstat = 1; /* Mark maximum found. */ 14435 14436 else if (tpar > (double)0.0) 14437 { 14438 14439 /* The point is greater than the level value . */ 14440 *jstat = 2; /* Mark new maximum found. */ 14441 *cmax = po1->p1->ecoef[0]; 14442 } 14443 14444 else 14445 14446 *jstat = 0; /* Mark no maximum found. */ 14447 14448 14449 if ( *jstat > 0 ) 14450 { 14451 SISLIntpt *qt; 14452 14453 /* Add maximum point. */ 14454 qt = newIntpt(0,cmax,DZERO); 14455 if (qt == SISL_NULL) goto err101; 14456 14457 /* Uppdate pintdat. */ 14458 s6idnpt(pintdat,&qt,1,&kstat); 14459 if (kstat < 0) goto error; 14460 } 14461 14462 } 14463 14464 14465 else if (po1->iobj > SISLPOINT) 14466 { 14467 /* It's a higher order geometry, treat the edges here and 14468 use a recursiv function to treat the inner of the object */ 14469 14470 14471 *jstat = 0; 14472 /* Perform a boxtest */ 14473 s1190(po1,cmax,aepsge,&kstat); 14474 if (kstat == 1) goto out; 14475 14476 14477 /*Create a dummy object, to be used when calling 14478 the intersection routines 14479 treating two objects.*/ 14480 if ((qdum = newObject(SISLPOINT)) == SISL_NULL) goto err101; 14481 14482 14483 14484 kedge = 2 * po1->iobj; 14485 kpar = kedge/2; 14486 14487 /* Create correct number of edges. */ 14488 if ((qedge[0] = newEdge(kedge)) == SISL_NULL) goto err101; 14489 14490 14491 for (ki=0; ki<kedge; ki++) 14492 { 14493 14494 /* Set correct parameter direction to keep constant */ 14495 kpar = ((ki == kedge/2) ? kedge/2-1:kpar-1); 14496 14497 /* Create one lower order helpobject */ 14498 if ((qob = newObject(po1->iobj - 1)) == SISL_NULL) goto err101; 14499 14500 14501 if (po1->iobj == SISLCURVE) 14502 14503 /* Pick out end point from a curve. */ 14504 s1438(po1->c1,ki,&(qob->p1),&tpar,&kstat); 14505 14506 else if (po1->iobj == SISLSURFACE) 14507 14508 /* Pick out edge curve from a surface. */ 14509 s1435(po1->s1,ki,&(qob->c1),&tpar,&kstat); 14510 14511 else 14512 /* Unknown higher order object . */ 14513 goto err121; 14514 14515 if (kstat < 0) goto error; 14516 14517 /* Recursiv computing of end maximum. */ 14518 s1161(qob,cmax,aepsge,&qintdat,&kstat); 14519 if (kstat < 0) goto error; 14520 14521 if (kstat == 2) 14522 { 14523 14524 /* New maximum found, delete old ones */ 14525 if (*pintdat != SISL_NULL) 14526 { 14527 freeIntdat(*pintdat); 14528 *pintdat = SISL_NULL; 14529 } 14530 14531 if (qedge[0] != SISL_NULL) 14532 { 14533 /* Empty the edges */ 14534 freeEdge(qedge[0]); 14535 if ((qedge[0] = newEdge(kedge)) == SISL_NULL) goto err101; 14536 } 14537 14538 } 14539 14540 14541 if (kstat) 14542 { 14543 /* Maximum found, add them to the list */ 14544 14545 *jstat = max(*jstat,kstat); /* Mark maximum found. */ 14546 14547 /* Put maximum found on edges into pintdat. */ 14548 14549 /* Set parameter border values of object. */ 14550 s6idput(pintdat,qintdat,kpar,tpar,&kstat); 14551 if (kstat < 0) goto error; 14552 14553 /* Uppdate edge structure. */ 14554 s6idedg(po1,qdum,1,kpar+1,tpar,*pintdat, 14555 &(qedge[0]->prpt[ki]),&(qedge[0]->ipoint),&kstat); 14556 if (kstat < 0) goto error; 14557 } 14558 14559 if (qintdat != SISL_NULL) freeIntdat(qintdat); 14560 qintdat = SISL_NULL; 14561 freeObject(qob); 14562 } 14563 14564 14565 /* ---------------------------------------------------------------*/ 14566 /* Treat the inner of higher order objects. */ 14567 14568 /* Before we enter internal maximum and subdivision we 14569 initiate pointers to top level objects. */ 14570 14571 if (po1->o1 == SISL_NULL) po1->o1 = po1; 14572 14573 /* Find the maximums in the inner of the object. */ 14574 s1162(po1,cmax,aepsge,pintdat,qedge,klevel,knum,&kstat); 14575 if (kstat < 0) goto error; 14576 *jstat = max(*jstat,kstat); 14577 14578 /* Organize the list in pintdat. */ 14579 s6idlis(po1,po1,pintdat,&kstat); 14580 if (kstat < 0) goto error; 14581 } 14582 14583 else 14584 /* Unknown object . */ 14585 goto err121; 14586 14587 14588 goto out; 14589 14590 14591 14592 /* -------------- ERROR HANDLING ----------------------------------------*/ 14593 14594 /* Error in space allocation. */ 14595 err101: *jstat = -101; 14596 s6err("s1161",*jstat,kpos); 14597 goto out; 14598 14599 /* Error. Dimensions conflicting. */ 14600 err106: *jstat = -106; 14601 s6err("s1161",*jstat,kpos); 14602 goto out; 14603 14604 /* Error. Kind of object does not exist. */ 14605 err121: *jstat = -121; 14606 s6err("s1161",*jstat,kpos); 14607 goto out; 14608 14609 /* Error in lower order routine. */ 14610 error : *jstat = kstat; 14611 s6err("s1161",*jstat,kpos); 14612 goto out; 14613 14614 out: 14615 /* Free the edges used in s1162. */ 14616 if (qedge[0] != SISL_NULL) freeEdge(qedge[0]); 14617 14618 /* Free the dummy object(point). */ 14619 if (qdum != SISL_NULL) freeObject(qdum); 14620 14621 } 14622 14623 //=========================================================================== 14624 void s1921(SISLSurf *ps1,double edir[],int idim,double aepsco,double aepsge, 14625 int *jpt,double **gpar,int *jcrv,SISLIntcurve ***wcurve,int *jstat) 14626 //=========================================================================== 14627 { 14628 int ikind; /* Type of surface ps1 is. */ 14629 int kstat = 0; /* Local status variable. */ 14630 int kpos = 0; /* Position of error. */ 14631 int ki; /* Counter. */ 14632 int kn1,kn2; /* Number of vertices of surface. */ 14633 int kk1,kk2; /* Order of surface. */ 14634 double tmax; /* Estimate of maximal value of 1-dim. surface.*/ 14635 double *st1,*st2; /* Pointer to knotvectors of surface. */ 14636 double *scoef; /* Pointer to vertices of surface. */ 14637 double *sc = SISL_NULL; /* Pointer to vertices of surface in maxima 14638 calculation. */ 14639 double *spar = SISL_NULL; /* Values of maxima in the parameter area of 14640 the second object. Empty in this case. */ 14641 double *s1,*s2,*sstop; /* Pointers used to traverse double-arrays. */ 14642 SISLIntdat *qintdat = SISL_NULL; /* Pointer to max data structure.*/ 14643 SISLSurf *qs = SISL_NULL; /* Pointer to 1-dim. surface in maxima-calculation.*/ 14644 SISLObject *qo1 = SISL_NULL; /* Pointer to object in maxima-calculation. */ 14645 SISLSurf *qkreg = SISL_NULL; /* Input surface with k-regularity ensured. */ 14646 14647 14648 /* Ensure k-regular input surface. */ 14649 14650 if ( ps1 -> cuopen_1 == SISL_SURF_PERIODIC || 14651 ps1 -> cuopen_2 == SISL_SURF_PERIODIC ) 14652 { 14653 /* Cyclic (periodic) surface */ 14654 14655 make_sf_kreg(ps1, &qkreg, &kstat); 14656 if ( kstat < 0 ) goto error; 14657 } 14658 else 14659 qkreg = ps1; 14660 14661 14662 /* Check dimension. */ 14663 14664 if ( qkreg -> idim != idim ) goto err106; 14665 14666 /* Describe surface with local variables. */ 14667 14668 kn1 = qkreg -> in1; 14669 kn2 = qkreg -> in2; 14670 kk1 = qkreg -> ik1; 14671 kk2 = qkreg -> ik2; 14672 st1 = qkreg -> et1; 14673 st2 = qkreg -> et2; 14674 ikind = qkreg -> ikind; 14675 14676 if ( ikind == 2 || ikind == 4 ) 14677 { 14678 scoef = qkreg -> rcoef; 14679 /* Allocate space for coeffecients of new surface. */ 14680 14681 if ( (sc = newarray(2*kn1*kn2, DOUBLE)) == SISL_NULL ) goto err101; 14682 14683 /* Compute scalar-product of surface-vertices and direction vector. */ 14684 /* Copy over weights. */ 14685 14686 for ( s1=scoef, s2=sc, sstop=s2+2*kn1*kn2; s2 < sstop; s1+=idim+1, s2+=2 ) 14687 { 14688 *s2 = s6scpr(s1, edir, idim); 14689 *(s2+1) = *(s1+idim); 14690 } 14691 } 14692 else 14693 { 14694 scoef = qkreg -> ecoef; 14695 /* Allocate space for coeffecients of new surface. */ 14696 14697 if ( (sc = newarray(kn1*kn2, DOUBLE)) == SISL_NULL ) goto err101; 14698 14699 /* Compute scalar-product of surface-vertices and direction vector. */ 14700 14701 for ( s1=scoef, s2=sc, sstop=s2+kn1*kn2; s2 < sstop; s1+=idim, s2++ ) 14702 *s2 = s6scpr(s1, edir, idim); 14703 } 14704 14705 14706 /* Create new surface. */ 14707 14708 qs = newSurf(kn1, kn2, kk1, kk2, st1, st2, sc, qkreg->ikind, 1, 1); 14709 if ( qs == SISL_NULL ) goto err101; 14710 14711 /* Create new object and connect surface to object. */ 14712 14713 qo1 = newObject(SISLSURFACE); 14714 if ( qo1 == SISL_NULL ) goto err101; 14715 qo1 -> s1 = qs; 14716 14717 /* Find maxima. */ 14718 14719 /* Find maxima. */ 14720 tmax = -(double)HUGE; 14721 14722 s1161(qo1, &tmax, aepsge, &qintdat, &kstat); 14723 if ( kstat < 0 ) goto error; 14724 14725 if (qintdat) 14726 { 14727 14728 /* Express maximal points/intervals on output format. */ 14729 s1880(2, 0, &qintdat->ipoint, qintdat->vpoint, 14730 &qintdat->ilist, qintdat->vlist, 14731 jpt, gpar, &spar, jcrv, wcurve, &kstat); 14732 if ( kstat < 0 ) goto error; 14733 14734 /* Handle periodicity (remove extraneous points) */ 14735 14736 if ( *jpt > 1 && idim > 1 && (ps1 -> cuopen_1 == SISL_SURF_PERIODIC || 14737 ps1 -> cuopen_2 == SISL_SURF_PERIODIC ) ) 14738 { 14739 for ( ki=0; ki < (*jpt); ki++ ) 14740 { 14741 if ( (ps1 -> cuopen_1 == SISL_SURF_PERIODIC && 14742 (*gpar)[2*ki] == ps1 -> et1[ps1->in1]) || 14743 (ps1 -> cuopen_2 == SISL_SURF_PERIODIC && 14744 (*gpar)[2*ki+1] == ps1 -> et2[ps1->in2]) ) 14745 { 14746 (*jpt)--; 14747 (*gpar)[2*ki] = (*gpar)[2*(*jpt)]; 14748 (*gpar)[2*ki+1] = (*gpar)[2*(*jpt)+1]; 14749 ki--; 14750 } 14751 } 14752 } 14753 } 14754 14755 /* Extremal points/intervals found. */ 14756 14757 *jstat = 0; 14758 goto out; 14759 14760 /* Error in space allocation. */ 14761 14762 err101: 14763 *jstat = -101; 14764 s6err("s1921",*jstat,kpos); 14765 goto out; 14766 14767 /* Dimensions conflicting. */ 14768 14769 err106: 14770 *jstat = -106; 14771 s6err("s1921",*jstat,kpos); 14772 goto out; 14773 14774 /* Error in lower level routine. */ 14775 14776 error: 14777 *jstat = kstat; 14778 s6err("s1921",*jstat,kpos); 14779 goto out; 14780 14781 out: 14782 14783 /* Free allocated space. */ 14784 14785 if ( qkreg && qkreg != ps1 ) freeSurf(qkreg); 14786 if (sc) freearray(sc); 14787 if (spar) freearray(spar); 14788 if (qo1) freeObject(qo1); 14789 if (qintdat) freeIntdat(qintdat); 14790 14791 return; 14792 } 14793 14794 14795 //=========================================================================== 14796 void s1954(SISLSurf *psurf,double epoint[],int idim,double aepsco,double aepsge, 14797 int *jpt,double **gpar,int *jcrv,SISLIntcurve ***wcurve,int *jstat) 14798 //=========================================================================== 14799 { 14800 int kstat = 0; /* Local status variable. */ 14801 int kpos = 0; /* Position of error. */ 14802 int kdim = 1; /* Dimension of curve in extremal problem. */ 14803 double tradius = 0; /* Radius of hyper-sphere describing point. */ 14804 double tdir = -1; /* Direction of extremal value. */ 14805 double *sarray = SISL_NULL; /* Matrix describing hyper-sphere. */ 14806 SISLSurf *qs = SISL_NULL; /* Surface of which to find extremal points. */ 14807 SISLSurf *qkreg = SISL_NULL; /* Input surface with k-regularity ensured. */ 14808 int ratflag = 0; /* Flag to indicate if surface is rational. */ 14809 int ki; /* Counter. */ 14810 14811 14812 *jstat = 0; 14813 14814 /* Ensure k-regular basis */ 14815 14816 if ( psurf -> cuopen_1 == SISL_SURF_PERIODIC || 14817 psurf -> cuopen_2 == SISL_SURF_PERIODIC ) 14818 { 14819 /* Cyclic (i.e. periodic) surface */ 14820 14821 make_sf_kreg(psurf, &qkreg, &kstat); 14822 if ( kstat < 0 ) goto error; 14823 } 14824 else 14825 qkreg = psurf; 14826 14827 14828 /* Test input. */ 14829 14830 if ( qkreg -> idim != idim ) goto err106; 14831 14832 if ( qkreg -> ikind == 2 || qkreg -> ikind == 4) ratflag = 1; 14833 14834 /* Allocate space for array describing a hyper-sphere. */ 14835 14836 if ( (sarray = newarray((idim+1)*(idim+1), DOUBLE)) == SISL_NULL ) goto err101; 14837 14838 /* Make a matrix of dimension (idim+1)*(idim+1) to describe 14839 the hyper-shpere. */ 14840 14841 s1321(epoint, tradius, idim, kdim, sarray, &kstat); 14842 if ( kstat < 0 ) goto error; 14843 14844 /* Put surface into equation of hyper-sphere. */ 14845 14846 s1320(qkreg, sarray, kdim, ratflag, &qs, &kstat); 14847 if ( kstat < 0 ) goto error; 14848 14849 /* Find minimum points of the new surface. */ 14850 14851 s1921(qs, &tdir, kdim, aepsco, aepsge, jpt, gpar, jcrv, wcurve, &kstat); 14852 if ( kstat < 0 ) goto error; 14853 14854 /* Handle periodicity (remove extraneous points) */ 14855 if ( (*jpt) > 1 && idim > 1 && (psurf -> cuopen_1 == SISL_SURF_PERIODIC || 14856 psurf -> cuopen_2 == SISL_SURF_PERIODIC) ) 14857 { 14858 for ( ki=0; ki < (*jpt); ki++ ) 14859 { 14860 if ( (psurf -> cuopen_1 == SISL_SURF_PERIODIC && 14861 (*gpar)[2*ki] == psurf -> et1[psurf->in1]) || 14862 (psurf -> cuopen_2 == SISL_SURF_PERIODIC && 14863 (*gpar)[2*ki+1] == psurf -> et2[psurf->in2]) ) 14864 { 14865 (*jpt)--; 14866 (*gpar)[2*ki] = (*gpar)[2*(*jpt)]; 14867 (*gpar)[2*ki+1] = (*gpar)[2*(*jpt)+1]; 14868 ki--; 14869 } 14870 } 14871 } 14872 14873 /* Closest points/intervals found. */ 14874 14875 *jstat = 0; 14876 goto out; 14877 14878 14879 /* Error in space allocation. */ 14880 14881 err101: 14882 *jstat = -101; 14883 s6err("s1954",*jstat,kpos); 14884 goto out; 14885 14886 /* Dimensions conflicting. */ 14887 14888 err106: 14889 *jstat = -106; 14890 s6err("s1954",*jstat,kpos); 14891 goto out; 14892 14893 /* Error in lower level routine. */ 14894 14895 error: 14896 *jstat = kstat; 14897 s6err("s1954",*jstat,kpos); 14898 goto out; 14899 14900 out: 14901 14902 /* Free allocated space. */ 14903 14904 if ( qkreg && qkreg != psurf ) freeSurf(qkreg); 14905 if (sarray) freearray(sarray); 14906 if (qs) freeSurf(qs); 14907 14908 return; 14909 } 14910 14911 //=========================================================================== 14912 void s1893 (SISLCurve * orig, double earray[], int dimp1, int narr, int der1, 14913 int der2, SISLCurve ** ncurve, int *jstat) 14914 //=========================================================================== 14915 { 14916 int nik; /* The order of the new basis. */ 14917 int nin; /* The number of verices in the new basis. */ 14918 int mder; /* max(der1,der2) */ 14919 int left; /* Interval indicator. */ 14920 int pos; /* Used to index earray */ 14921 int pos1; /* Position of the first derivatives in the 14922 * array deriv. (returned form s1221); */ 14923 int pos2; /* Position of the second derivatives in the 14924 * array deriv. (returned form s1221); */ 14925 int count1, count2; /* Loop control variables. */ 14926 int count3=0; 14927 int kr, kl, kp; 14928 int *der = SISL_NULL; /* The derivative indicators. (0) */ 14929 14930 double *nknots = SISL_NULL; /* The new knot vector. */ 14931 double *coef = SISL_NULL; /* Coefficients of the new B-spline curve. */ 14932 double *par = SISL_NULL; /* Parameter values used for interpolation. */ 14933 double *deriv = SISL_NULL; /* The derivates returned by s1221. */ 14934 double *val1 = SISL_NULL; /* Extracted values from deriv. */ 14935 double *val2 = SISL_NULL; /* Extracted values from deriv. */ 14936 double *tau = SISL_NULL; /* Interpolation points. */ 14937 double sum; /* Used for calculating F(t). */ 14938 int kpos = 0; 14939 int kstat = 0; 14940 14941 *jstat = 0; 14942 14943 14944 /* Test if legal input. */ 14945 14946 if (orig->ik <= 1 || orig->in <orig->ik) 14947 goto err112; 14948 if ( dimp1 < orig->idim || dimp1 > orig->idim +1 ) 14949 goto err151; 14950 14951 14952 /* Produce a knot vector. */ 14953 14954 s1894 (orig->et, orig->ik, orig->in, der1, der2, earray, dimp1, narr, 14955 &nknots, &nik, &nin, &kstat); 14956 if (kstat < 0) 14957 goto error; 14958 14959 14960 /* Produce parameter values and derivate indicators. */ 14961 14962 s1890 (nknots, nik, nin, &par, &der, &kstat); 14963 if (kstat < 0) 14964 goto error; 14965 14966 14967 /* Allocate arrays. */ 14968 14969 val1 = newarray (orig->idim + 1, DOUBLE); 14970 if (val1 == SISL_NULL) 14971 goto err101; 14972 val2 = newarray (orig->idim + 1, DOUBLE); 14973 if (val2 == SISL_NULL) 14974 goto err101; 14975 tau = new0array (nin * narr * narr, DOUBLE); 14976 /* tau = newarray (nin * narr, DOUBLE); (PFU 21/09-94) */ 14977 if (tau == SISL_NULL) 14978 goto err101; 14979 14980 mder = max (der1, der2); 14981 deriv = newarray ((mder + 1) * orig->idim, DOUBLE); 14982 if (deriv == SISL_NULL) 14983 goto err101; 14984 14985 14986 /* Calculate interpolation points. */ 14987 14988 left = 0; 14989 for (count1 = 0; count1 < nin; count1++) 14990 { 14991 s1221 (orig, mder, par[count1], &left, deriv, &kstat); 14992 if (kstat < 0) 14993 goto error; 14994 14995 14996 /* Extract the values/derivatives. */ 14997 14998 pos1 = der1 * orig->idim; 14999 pos2 = der2 * orig->idim; 15000 15001 for (count2 = 0; count2 < orig->idim; count2++) 15002 { 15003 val1[count2] = deriv[pos1++]; 15004 val2[count2] = deriv[pos2++]; 15005 } 15006 15007 if(orig->idim < dimp1) 15008 { 15009 if (der1 > 0) 15010 val1[orig->idim] = (double) 0.0; 15011 else 15012 val1[orig->idim] = (double) 1.0; 15013 15014 if (der2 > 0) 15015 val2[orig->idim] = (double) 0.0; 15016 else 15017 val2[orig->idim] = (double) 1.0; 15018 } 15019 15020 /* Calculate the functtion F(t). */ 15021 15022 pos = 0; 15023 for (kl = 0; kl < narr; kl++) 15024 { 15025 sum = (double) 0.0; 15026 for (kr = 0; kr < dimp1; kr++) 15027 { 15028 for (kp = 0; kp < dimp1; kp++) 15029 sum += earray[pos++] * val1[kr] * val2[kp]; 15030 /* sum += earray[pos++] * val1[kp] * val2[kr]; */ 15031 } 15032 tau[count3++] = sum; 15033 } 15034 } 15035 15036 /* Caculate new curve description */ 15037 15038 s1891 (par, tau, narr, nin, narr, der, TRUE, nknots, &coef, &nin, 15039 nik, 0, 0, &kstat); 15040 if (kstat < 0) 15041 goto error; 15042 15043 *ncurve = newCurve (nin, nik, nknots, coef, orig->ikind, narr, 2); 15044 if (*ncurve == SISL_NULL) 15045 goto err171; 15046 (*ncurve)->cuopen = orig->cuopen; 15047 15048 /* OK */ 15049 15050 goto out; 15051 15052 15053 /* Memory error. */ 15054 15055 err101: 15056 *jstat = -101; 15057 s6err ("s1893", *jstat, kpos); 15058 goto out; 15059 15060 /* Could not create curve. */ 15061 15062 err171: 15063 *jstat = -171; 15064 s6err ("s1893", *jstat, kpos); 15065 goto out; 15066 15067 /* Error in description of B-spline. */ 15068 15069 err112: 15070 *jstat = -112; 15071 s6err ("s1893", *jstat, kpos); 15072 goto out; 15073 15074 /* dimp1 not equal to idim+1. */ 15075 15076 err151: 15077 *jstat = -151; 15078 s6err ("s1893", *jstat, kpos); 15079 goto out; 15080 15081 /* Error in lower level routine. */ 15082 15083 error: 15084 *jstat = kstat; 15085 s6err ("s1893", *jstat, kpos); 15086 goto out; 15087 15088 /* Free memory. */ 15089 15090 out: 15091 if (val1 != SISL_NULL) 15092 freearray (val1); 15093 if (val2 != SISL_NULL) 15094 freearray (val2); 15095 if (der != SISL_NULL) 15096 freearray (der); 15097 if (par != SISL_NULL) 15098 freearray (par); 15099 if (deriv != SISL_NULL) 15100 freearray (deriv); 15101 if (tau != SISL_NULL) 15102 freearray (tau); 15103 return; 15104 } 15105 15106 15107 //=========================================================================== 15108 void s1370 (SISLCurve * pcurv, double earray[], int idim, int inarr, 15109 int ratflag, SISLCurve ** rcurv, int *jstat) 15110 //=========================================================================== 15111 { 15112 int kpos = 0; 15113 int kstat = 0; 15114 SISLCurve *icurve = SISL_NULL; /* Temporary SISLCurve. */ 15115 int kn; /* Number of vertices of pcurv */ 15116 int kk; /* Order in pcurv */ 15117 int kdim; /* Number of dimesions in pcurv */ 15118 int kdimp1; /* Dimension of earray should be kdim+1 */ 15119 double *st = SISL_NULL; /* First knot vector is pcurv */ 15120 double *scoef = SISL_NULL; /* Vertices of pcurv */ 15121 int ikind; /* kind of surface pcurv is */ 15122 double *rscoef = SISL_NULL; /* Scaled coefficients if pcurv is rational */ 15123 double wmin, wmax; /* min and max values of the weights if rational */ 15124 double scale; /* factor for scaling weights if rational */ 15125 int i; /* loop variable */ 15126 double *sarray = SISL_NULL; /* Array for calculating denominator if used */ 15127 int knarr; /* Number of parallel arrays to use. */ 15128 int nkind; /* Kind of output curve (rcurf). */ 15129 15130 *jstat = 0; 15131 15132 /* Make local pointers. */ 15133 15134 kn = pcurv->in; 15135 kk = pcurv->ik; 15136 kdim = pcurv->idim; 15137 st = pcurv->et; 15138 ikind = pcurv->ikind; 15139 15140 kdimp1 = kdim + 1; 15141 15142 /* Test input. */ 15143 15144 if (kdim != idim || (kdim != 2 && kdim != 3)) 15145 goto err104; 15146 if (inarr < 1 || 3 < inarr) goto err172; 15147 15148 /* rational surfaces are a special case. */ 15149 if (ikind == 2 || ikind == 4) 15150 { 15151 kdim++; 15152 15153 /* scale the coeffs so that min. weight * max. weight = 1. */ 15154 15155 rscoef = pcurv->rcoef; 15156 wmin = rscoef[kdim-1]; 15157 wmax = rscoef[kdim-1]; 15158 15159 for (i = 2*kdim-1; i < kn * kdim; i += kdim) 15160 { 15161 if (rscoef[i] < wmin) 15162 wmin = rscoef[i]; 15163 if (rscoef[i] > wmax) 15164 wmax = rscoef[i]; 15165 } 15166 scale = (double) 1.0 / sqrt (wmin * wmax); 15167 scoef = newarray (kn * kdim, DOUBLE); 15168 if (scoef == SISL_NULL) 15169 goto err101; 15170 15171 for (i = 0; i < kn * kdim; i++) 15172 scoef[i] = rscoef[i] * scale; 15173 } 15174 else 15175 scoef = pcurv->ecoef; 15176 15177 icurve = newCurve (kn, kk, st, scoef, 1, kdim, 1); 15178 if (icurve == SISL_NULL) 15179 goto err171; 15180 15181 icurve->cuopen = pcurv->cuopen; 15182 15183 if ((ikind == 2 || ikind == 4) && ratflag == 1) 15184 { 15185 /* Output curve will also be rational. */ 15186 15187 nkind = 2; 15188 15189 /* Add an extra parallel array to pick up the weights 15190 of the subsequent homogeneous vertices of rcurv. */ 15191 15192 knarr = inarr + 1; 15193 sarray = new0array (kdimp1 * kdimp1 * knarr, DOUBLE); 15194 if (sarray == SISL_NULL) goto err101; 15195 15196 memcopy (sarray, earray, kdimp1 * kdimp1 * inarr, DOUBLE); 15197 sarray[kdimp1 * kdimp1 * knarr - 1] = (DOUBLE) 1.0; 15198 } 15199 else 15200 { 15201 nkind = 1; 15202 knarr = inarr; 15203 sarray = earray; 15204 } 15205 15206 /* Put curve into implicit surface. */ 15207 15208 s1893 (icurve, sarray, kdimp1, knarr, 0, 0, rcurv, &kstat); 15209 if (kstat < 0) goto error; 15210 15211 if (*rcurv == SISL_NULL) goto err171; 15212 15213 if ( ikind == 2 || ikind == 4 ) 15214 { 15215 /* Free arrays. */ 15216 15217 if (scoef) freearray (scoef); 15218 if (ratflag && sarray) freearray (sarray); 15219 15220 if ( ratflag == 1 ) 15221 { 15222 /* Output from s1893 is a dim+1 non-rational curve. */ 15223 /* Convert homogeneous curve to rational form (rcoef is SISL_NULL here). */ 15224 15225 (*rcurv)->rcoef = newarray((*rcurv)->in * (*rcurv)->idim, DOUBLE); 15226 memcopy((*rcurv)->rcoef, (*rcurv)->ecoef, 15227 (*rcurv)->in * (*rcurv)->idim, DOUBLE); 15228 15229 (*rcurv)->idim --; /* Adjust from the homogeneus coordinates. */ 15230 (*rcurv)->ikind = 2; /* i.e. rational */ 15231 15232 } 15233 } 15234 15235 15236 /* Ok ! */ 15237 15238 goto out; 15239 15240 /* Error in lower level function. */ 15241 15242 error: 15243 *jstat = kstat; 15244 s6err ("s1370", *jstat, kpos); 15245 goto out; 15246 15247 /* Allocation problems. */ 15248 15249 err101: 15250 *jstat = -101; 15251 s6err ("s1370", *jstat, kpos); 15252 goto out; 15253 15254 /* Dimension not equal to 3. */ 15255 15256 err104: 15257 *jstat = -104; 15258 s6err ("s1370", *jstat, kpos); 15259 goto out; 15260 15261 /* Could not create curve */ 15262 15263 err171: 15264 *jstat = -171; 15265 s6err ("s1370", *jstat, kpos); 15266 goto out; 15267 15268 /* Dimension inarr not equal to 1,2 or 3. */ 15269 15270 err172: 15271 *jstat = -172; 15272 s6err ("s1370", *jstat, kpos); 15273 goto out; 15274 15275 out: 15276 if (icurve != SISL_NULL) freeCurve (icurve); 15277 return; 15278 } 15279 15280 15281 //=========================================================================== 15282 void sh6sepcrv_s9circle(double apt1[], double apt2[], double apt3[], 15283 double aepsge, double ecentre[], double eaxis[], 15284 double *crad, int *jstat) 15285 //=========================================================================== 15286 { 15287 int kstat = 0; 15288 int ki; 15289 int kdim = 3; 15290 int lpiv[3]; 15291 double snorm[3]; 15292 double smid1[3]; 15293 double smid2[3]; 15294 double sdiff1[3]; 15295 double sdiff2[3]; 15296 double smat[9]; 15297 double sright[3]; 15298 15299 /* Compute difference vectors between the 1. and 2. and 2. and 3. point. */ 15300 15301 s6diff(apt1, apt2, kdim, sdiff1); 15302 s6diff(apt3, apt2, kdim, sdiff2); 15303 15304 /* Compute the normal of the plane in which the circle lies. */ 15305 15306 s6crss(sdiff1, sdiff2, snorm); 15307 15308 /* Compute the normals to the planes normal to the first plane and 15309 perpendicular to the difference vectors. */ 15310 15311 /* s6crss(sdiff1, snorm, snorm1); 15312 s6crss(sdiff2, snorm, snorm3); */ 15313 15314 /* Check normals. */ 15315 15316 if (s6norm(sdiff1, kdim, sdiff1, &kstat) < aepsge) goto warn1; 15317 if (s6norm(snorm, kdim, snorm, &kstat) < aepsge) goto warn1; 15318 if (s6norm(sdiff2, kdim, sdiff2, &kstat) < aepsge) goto warn1; 15319 15320 /* Compute the midpoints of the difference vectors. */ 15321 15322 for (ki=0; ki<kdim; ki++) 15323 { 15324 smid1[ki] = (double)0.5*(apt1[ki] + apt2[ki]); 15325 smid2[ki] = (double)0.5*(apt2[ki] + apt3[ki]); 15326 } 15327 15328 /* Set up equation system. */ 15329 15330 memcopy(smat, snorm, kdim, DOUBLE); 15331 memcopy(smat+kdim, sdiff1, kdim, DOUBLE); 15332 memcopy(smat+2*kdim, sdiff2, kdim, DOUBLE); 15333 15334 sright[0] = s6scpr(apt2, snorm, kdim); 15335 sright[1] = s6scpr(smid1, sdiff1, kdim); 15336 sright[2] = s6scpr(smid2, sdiff2, kdim); 15337 15338 /* Solve equation system. */ 15339 15340 s6lufacp(smat, lpiv, 3, &kstat); 15341 if (kstat < 0) goto error; 15342 15343 s6lusolp(smat, sright, lpiv, 3, &kstat); 15344 if (kstat < 0) goto error; 15345 15346 /* Prepare output. */ 15347 15348 memcopy(eaxis, snorm, kdim, DOUBLE); 15349 memcopy(ecentre, sright, kdim, DOUBLE); 15350 *crad = s6dist(ecentre, apt2, kdim); 15351 15352 *jstat = 0; 15353 goto out; 15354 15355 /* Almost singular equation system. */ 15356 15357 warn1 : 15358 *jstat = 1; 15359 goto out; 15360 15361 /* Error in lower level routine. */ 15362 15363 error : 15364 *jstat = kstat; 15365 goto out; 15366 15367 out : 15368 return; 15369 } 15370 15371 15372 //=========================================================================== 15373 void sh6sepcrv (SISLCurve *pc1, SISLCurve *pc2, double aepsge, double ecentre[], 15374 double *crad, int *jstat) 15375 //=========================================================================== 15376 { 15377 int kstat = 0; /* Status variable. */ 15378 int ki,kj; /* Counters. */ 15379 int kleft1=0; /* Parameters to surface evaluator. */ 15380 int kdim=pc1->idim; /* Dimension of geometry space. */ 15381 double tpar; /* Midpoint of surface. */ 15382 double sparc1[3]; /* Corner parameters of first surface. */ 15383 double sparc2[3]; /* Parameters of closest points on second surface. */ 15384 double scorn1[9]; /* Corners of first surface. */ 15385 double scorn2[9]; /* Closest points in the other surface. */ 15386 SISLPoint *qp = SISL_NULL; /* Representing a surface corner as a point. */ 15387 double tstart; /* Start parameters of second surface. */ 15388 double tend; /* End parameters of second surface. */ 15389 double saxis[3]; /* Normal to circle between edges. */ 15390 double tdot; 15391 double tsign; 15392 double tang; 15393 double tpi4 = PI/(double)4.0; 15394 15395 /* Test dimension. */ 15396 15397 if (kdim != 3) 15398 { 15399 *jstat = 0; 15400 goto out; 15401 } 15402 15403 /* Test if the cones of the surfaces is less than pi, otherwise 15404 no attempt to find splitting geometry is made. */ 15405 15406 if (pc1->pdir->igtpi != 0 || pc2->pdir->igtpi != 0) 15407 { 15408 *jstat = 0; 15409 goto out; 15410 } 15411 15412 15413 /* Check that the objects are not too large, i.e. contain to many 15414 vertices to be put into a sphere equation effectively. */ 15415 15416 if (pc1->in > 4*pc1->ik || pc2->in > 4*pc2->ik) 15417 { 15418 *jstat = 0; 15419 goto out; 15420 } 15421 15422 /* Make sure that the cones lies in the same area, otherwise 15423 return. */ 15424 15425 tdot = s6scpr(pc1->pdir->ecoef,pc2->pdir->ecoef,kdim); 15426 tsign = (tdot >= DZERO) ? (double)1.0 : -(double)1.0; 15427 15428 tang = s6ang(pc1->pdir->ecoef,pc2->pdir->ecoef,kdim); 15429 if (tang > tpi4) 15430 { 15431 *jstat = 0; 15432 goto out; 15433 } 15434 15435 /* Try to find a circle splitting the edge curves of the surface and the 15436 cyrve, and extend this circle to a sphere. */ 15437 15438 sparc1[0] = *(pc1->et+pc1->ik-1); 15439 sparc1[2] = *(pc1->et+pc1->in); 15440 sparc1[1] = (double)0.5*(sparc1[0] + sparc1[2]); 15441 15442 tstart = *(pc2->et + pc2->ik - 1); 15443 tend = *(pc2->et + pc2->in); 15444 tpar= (double)0.5*(tstart + tend); 15445 15446 for (ki=0; ki<3; ki++) 15447 { 15448 /* Evaluate curve. */ 15449 15450 s1221(pc1, 0, sparc1[ki], &kleft1, scorn1+ki*kdim, &kstat); 15451 if (kstat < 0) goto error; 15452 15453 /* Find the closest point in the other surface. First express 15454 the corner as a SISLPoint. */ 15455 15456 if ((qp = newPoint(scorn1+ki*kdim, kdim, 1)) == SISL_NULL) goto err101; 15457 s1771(qp, pc2, aepsge, tstart, tend, tpar, sparc2+ki, &kstat); 15458 if (kstat < 0) goto error; 15459 15460 /* Evaluate second curve. */ 15461 15462 s1221(pc2, 0, sparc2[ki], &kleft1, scorn2+ki*kdim, &kstat); 15463 if (kstat < 0) goto error; 15464 15465 if (qp != SISL_NULL) freePoint(qp); qp = SISL_NULL; 15466 } 15467 15468 15469 /* Find middle points between the sets of closest points. */ 15470 15471 for (kj=0; kj<3; kj++) 15472 for (ki=0; ki<kdim; ki++) 15473 scorn1[kj*kdim+ki] = (double)0.5*(scorn1[kj*kdim+ki] + 15474 scorn2[kj*kdim+ki]); 15475 15476 /* Compute splitting cylinder. */ 15477 15478 sh6sepcrv_s9circle(scorn1, scorn1+kdim, scorn1+2*kdim, 15479 aepsge, ecentre, saxis, crad, &kstat); 15480 if (kstat < 0) goto error; 15481 if (kstat > 0) 15482 { 15483 *jstat = 0; 15484 goto out; 15485 } 15486 15487 /* Output sphere. */ 15488 15489 *jstat = 1; 15490 goto out; 15491 15492 err101 : *jstat = -101; 15493 goto out; 15494 15495 error : *jstat = kstat; 15496 goto out; 15497 15498 out : 15499 return; 15500 } 15501 15502 15503 15504 //=========================================================================== 15505 void sh1831(SISLCurve *pc1, SISLCurve *pc2, int isign, double epoint[], 15506 double enorm[], double aepsge, int *jstat) 15507 //=========================================================================== 15508 { 15509 int kpos = 0; /* Position of error. */ 15510 int ki; 15511 int kdim; /* Dimension of space. */ 15512 int kbez1, kbez2; /* Indicates if the curves are of type Bezier. */ 15513 int ksignprev = 0; /* Sign of distance between previous curve and plane.*/ 15514 int ksign1 = 0; /* Sign of distance between curve and plane.*/ 15515 int ksign2 = 0; /* Sign of distance between curve and plane.*/ 15516 double tdist; /* Distance between coefficient and plane. */ 15517 double *s1; /* Pointer to coefficient of curve. */ 15518 double sdiff[3]; /* Difference vector. */ 15519 15520 /* Test dimension of geometry space. */ 15521 15522 kdim = pc1->idim; 15523 if (kdim != 2 && kdim != 3) goto err105; 15524 if (kdim != pc2->idim) goto err106; 15525 15526 /* Test if the curves are Bezier curves. */ 15527 15528 kbez1 = (pc1->ik == pc1->in) ? 1 : 0; 15529 kbez2 = (pc2->ik == pc2->in) ? 1 : 0; 15530 15531 /* For each curve, compute the distance between the coefficients of the 15532 curve and the given plane. */ 15533 15534 for (s1=pc1->ecoef, ki=0; ki<pc1->in; ki++, s1+=kdim) 15535 { 15536 s6diff(epoint, s1, kdim, sdiff); 15537 tdist = s6scpr(sdiff, enorm, kdim); 15538 15539 if (fabs(tdist) <= aepsge && !kbez1 && !(ki==0 || ki==pc1->in-1)) break; 15540 ksign2 = (DEQUAL(tdist,DZERO)) ? 0 : ((tdist > 0) ? 1 : -1); 15541 if (ksign1*ksign2 < 0) break; 15542 ksign1 = ksign2; 15543 } 15544 if (ki < pc1->in) 15545 { 15546 *jstat = 1; 15547 goto out; 15548 } 15549 15550 ksignprev = isign*ksign1; 15551 ksign1 = 0; 15552 for (s1=pc2->ecoef, ki=0; ki<pc2->in; ki++, s1+=kdim) 15553 { 15554 s6diff(epoint, s1, kdim, sdiff); 15555 tdist = s6scpr(sdiff, enorm, kdim); 15556 15557 if (fabs(tdist) <= aepsge && !kbez2 && !(ki==0 || ki==pc2->in-1)) break; 15558 ksign2 = (DEQUAL(tdist,DZERO)) ? 0 : ((tdist > 0) ? 1 : -1); 15559 if (ksign1*ksign2 < 0) break; 15560 if (ksignprev*ksign1 > 0) break; 15561 ksign1 = ksign2; 15562 } 15563 if (ki < pc2->in) 15564 { 15565 *jstat = 1; 15566 goto out; 15567 } 15568 15569 goto out; 15570 15571 /* Error in input. Dimension not equal to 2 or 3. */ 15572 15573 err105: *jstat = -105; 15574 s6err("sh1831",*jstat,kpos); 15575 goto out; 15576 15577 /* Error in input. Dimensions conflicting. */ 15578 15579 err106: *jstat = -106; 15580 s6err("sh1831",*jstat,kpos); 15581 goto out; 15582 15583 out: 15584 15585 return; 15586 } 15587 15588 //=========================================================================== 15589 void sh1830(SISLObject *po1,SISLObject *po2,double aepsge,int *jstat) 15590 //=========================================================================== 15591 { 15592 int kstat = 0; /* Local status variable. */ 15593 int kpos = 0; /* Position of error. */ 15594 int kdim; /* Dimension of space. */ 15595 int knc; /* Number of vertices of curve. */ 15596 int kn1,kn2; /* Number of vertices of surface. */ 15597 double *scurve; /* Vertices of curve. */ 15598 double *ssurf; /* Vertices of surface. */ 15599 double *stan = SISL_NULL; /* Main tangent of curve. */ 15600 double *sdiag1 = SISL_NULL; /* First main diagonal of surface. */ 15601 double *sdiag2 = SISL_NULL; /* Second main diagonal of surface. */ 15602 double *snorm = SISL_NULL; /* Main normal of surface. */ 15603 SISLCurve *qcurve; /* Pointer to curve. */ 15604 SISLSurf *qsurf; /* Pointer to surface. */ 15605 15606 /* Test input. */ 15607 15608 if (!((po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE) || 15609 (po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE))) 15610 goto err121; 15611 15612 /* Set pointers to objects. */ 15613 15614 if (po1->iobj == SISLSURFACE) 15615 { 15616 qsurf = po1->s1; qcurve = po2->c1; 15617 } 15618 else 15619 { 15620 qsurf = po2->s1; qcurve = po1->c1; 15621 } 15622 15623 /* Test dimension. */ 15624 15625 kdim = qsurf -> idim; 15626 if (kdim != 3) goto err104; 15627 if (kdim != qcurve -> idim) goto err106; 15628 15629 /* Allocate space for local arrays. */ 15630 15631 if ((stan = newarray(kdim,double)) == SISL_NULL) goto err101; 15632 if ((sdiag1 = newarray(kdim,double)) == SISL_NULL) goto err101; 15633 if ((sdiag2 = newarray(kdim,double)) == SISL_NULL) goto err101; 15634 if ((snorm = newarray(kdim,double)) == SISL_NULL) goto err101; 15635 15636 /* Describe curve with local parameters. */ 15637 15638 knc = qcurve->in; 15639 scurve = qcurve->ecoef; 15640 15641 /* Describe surface with local parameters. */ 15642 15643 kn1 = qsurf->in1; 15644 kn2 = qsurf->in2; 15645 ssurf = qsurf->ecoef; 15646 15647 /* Fetch main tangent of curve. */ 15648 15649 s6diff(scurve+(knc-1)*kdim,scurve,kdim,stan); 15650 15651 /* Fetch main diagonals of surface. */ 15652 15653 s6diff(ssurf+(kn1*kn2-1)*kdim,ssurf,kdim,sdiag1); 15654 15655 s6diff(ssurf+kn1*(kn2-1)*kdim,ssurf+(kn1-1)*kdim,kdim,sdiag2); 15656 15657 /* Compute main normal of surface. */ 15658 15659 s6crss(sdiag1,sdiag2,snorm); 15660 15661 /* Perform rotated box-test. */ 15662 15663 sh1834(po1,po2,aepsge,kdim,stan,snorm,&kstat); 15664 if (kstat < 0) goto error; 15665 15666 if (kstat == 1) 15667 { 15668 kstat = 0; 15669 15670 sh1834(po1,po2,aepsge,kdim,snorm,stan,&kstat); 15671 if (kstat < 0) goto error; 15672 } 15673 15674 /* Improved box-test performed. */ 15675 15676 *jstat = kstat; 15677 goto out; 15678 15679 /* Error in space allocation. */ 15680 15681 err101: *jstat = -101; 15682 s6err("sh1830",*jstat,kpos); 15683 goto out; 15684 15685 /* Error in input. Dimension not equal to 3. */ 15686 15687 err104: *jstat = -104; 15688 s6err("sh1830",*jstat,kpos); 15689 goto out; 15690 15691 /* Error in input. Dimensions conflicting. */ 15692 15693 err106: *jstat = -106; 15694 s6err("sh1830",*jstat,kpos); 15695 goto out; 15696 15697 /* Error in kind of object. */ 15698 15699 err121: *jstat = -121; 15700 s6err("s1930",*jstat,kpos); 15701 goto out; 15702 15703 /* Error in lower level routine. */ 15704 15705 error : *jstat = kstat; 15706 s6err("sh1830",*jstat,kpos); 15707 goto out; 15708 15709 out: 15710 15711 /* Free space occupied by local arrays. */ 15712 15713 if (stan != SISL_NULL) freearray(stan); 15714 if (sdiag1 != SISL_NULL) freearray(sdiag1); 15715 if (sdiag2 != SISL_NULL) freearray(sdiag2); 15716 if (snorm != SISL_NULL) freearray(snorm); 15717 15718 return; 15719 } 15720 15721 15722 //=========================================================================== 15723 void s1376(double et[],int in,int ik,double **gt,int *jkn,int *jkk,int *jstat) 15724 //=========================================================================== 15725 { 15726 double tval; /* Value of knot */ 15727 double *sdum; /* Pointer to knot array */ 15728 int ki,kl; /* Variable in loop */ 15729 int knumb; /* Number of intervals */ 15730 int kstop; /* Loop stop variable */ 15731 int kpos=0; /* Position of error */ 15732 15733 /* Run through the knot vector to decide how many intervals exist */ 15734 15735 knumb = 0; 15736 tval = et[ik-1]; 15737 15738 for (ki=ik ; ki<=in ; ki++) 15739 { 15740 if (tval < et[ki]) 15741 { 15742 /* New knot value found */ 15743 knumb = knumb + 1; 15744 tval = et[ki]; 15745 } 15746 } 15747 15748 *jkk = 4*(ik-1) + 1; 15749 *jkn = (*jkk-1)*(knumb-1) + *jkk; 15750 15751 sdum = newarray(*jkn+*jkk,DOUBLE); 15752 if (sdum == SISL_NULL) goto err101; 15753 15754 *gt = sdum; 15755 15756 /* Make knot values */ 15757 15758 tval = et[ik-1]; 15759 15760 /* Make jkk first knot values */ 15761 15762 for (kl=0;kl<*jkk;kl++) 15763 { 15764 sdum[kl] = tval; 15765 } 15766 15767 /* kl points to the array entry where the next knot value is to be stored 15768 */ 15769 15770 for (ki=ik ; ki<=in ; ki++) 15771 { 15772 if (tval < et[ki]) 15773 { 15774 /* New knot value, remember this and make knots */ 15775 tval = et[ki]; 15776 kstop = kl + *jkk-1; 15777 for (;kl<kstop;kl++) 15778 sdum[kl] = tval; 15779 } 15780 } 15781 15782 /* Make last knot value */ 15783 15784 sdum[kl] = tval; 15785 15786 *jstat = 0; 15787 goto out; 15788 15789 /* Error in space allocation */ 15790 err101: *jstat = -101; 15791 s6err("s1376",*jstat,kpos); 15792 goto out; 15793 out: 15794 15795 return; 15796 } 15797 15798 15799 //=========================================================================== 15800 void s1378 (SISLSurf * psurf, double econic[], int ideg, int idim, 15801 SISLSurf ** rsurf, int *jstat) 15802 //=========================================================================== 15803 { 15804 int ikind; /* type of surface psurf is */ 15805 int kn1; /* Number of vertices of psurf in first par.dir */ 15806 int kk1; /* Order in psurf in first par.dir */ 15807 int kn2; /* Number of vertices of psurf in second par.dir */ 15808 int kk2; /* Order in psurf in second par.dir */ 15809 int kjkk1; /* Order of interpolated basis in first par.dir */ 15810 int kjkn1; /* Number of vertices in interpolated basis first.dr*/ 15811 int kjkk2; /* Order of interpolated basis in first par SISLdir */ 15812 int kjkn2; /* Number of vertices in interpolated basis secnd.dr*/ 15813 int kdim; /* Number of dimesions in psurf */ 15814 int kstat; /* Local status variable */ 15815 int kpos = 0; /* Position indicator for errors */ 15816 int kzero = 0; /* Value 0 needed in call s1891 */ 15817 int kone = 1; /* Value 1 needed in call s1891 */ 15818 int cuopen; /* Open/Closed flag */ 15819 int ki, kj, kl; /* Loop control variable */ 15820 int kp; /* Index of points put into conic equation */ 15821 int klfs = 0; /* Pointer into knot vector */ 15822 int klft = 0; /* Pointer into knot vector */ 15823 double *st1 = SISL_NULL; /* First knot vector is psurf */ 15824 double *st2 = SISL_NULL; /* Second knot vector is psurf */ 15825 double *scentr = econic; /* Center of torus */ 15826 double *saxis = econic + 3; /* Axis of torus */ 15827 double tbigr = *(econic + 6); /* Big radius of torus */ 15828 double tsmalr = *(econic + 7);/* Small radius of torus */ 15829 double tbigr2 = tbigr * tbigr;/* Square of big radius */ 15830 double tdiffr2 = tbigr2 - tsmalr * tsmalr; /* Difference of square of radia*/ 15831 double *sval1 = SISL_NULL; /* Array of values of surface put into torus eq. */ 15832 double *sval2 = SISL_NULL; 15833 double *sval3 = SISL_NULL; 15834 double *sgt1 = SISL_NULL; /* Knot vector in first parameter direction of 15835 surface put into torus equation */ 15836 double *sgt2 = SISL_NULL; /* Knot vector in second parameter direction of 15837 surface put into torus equation */ 15838 double sy[3]; /* Difference between point and torus center */ 15839 double tzn; /* Projection of sy onto torus axis */ 15840 double tyy; /* Square of length of sy */ 15841 double tzz; /* Square of length of sz */ 15842 double ty; /* Component of sy */ 15843 double tz; /* Component of sz */ 15844 double sder[4]; /* SISLPoint on the surface */ 15845 double spar[2]; /* Current parameter pair */ 15846 double ww; /* the weight of sder squared if psurf is rational */ 15847 double *par1 = SISL_NULL; /* Parameter vaues in direction 1. */ 15848 double *par2 = SISL_NULL; /* Parameter vaues in direction 2. */ 15849 int *der1 = SISL_NULL; /* Derivative indicators in direction 1. */ 15850 int *der2 = SISL_NULL; /* Derivative indicators in direction 2. */ 15851 SISLSurf *tempsurf = SISL_NULL; /* only used for rational surfaces */ 15852 15853 *jstat = 0; 15854 15855 15856 /* Test if torus. */ 15857 15858 if (ideg != 1001) 15859 goto err180; 15860 15861 if (idim != psurf->idim) 15862 goto err104; 15863 15864 /* Make local pointers. */ 15865 15866 kn1 = psurf->in1; 15867 kk1 = psurf->ik1; 15868 kn2 = psurf->in2; 15869 kk2 = psurf->ik2; 15870 kdim = psurf->idim; 15871 st1 = psurf->et1; 15872 st2 = psurf->et2; 15873 ikind = psurf->ikind; 15874 15875 if (ikind == 2 || ikind == 4) 15876 { 15877 tempsurf = newSurf (kn1, kn2, kk1, kk2, st1, st2, 15878 psurf->rcoef, ikind - 1, kdim + 1, 0); 15879 if (tempsurf == SISL_NULL) 15880 goto err171; 15881 tempsurf->cuopen_1 = psurf->cuopen_1; 15882 tempsurf->cuopen_2 = psurf->cuopen_2; 15883 } 15884 else 15885 { 15886 tempsurf = psurf; 15887 } 15888 15889 /* Test input. */ 15890 15891 if (kdim != 3) 15892 goto err104; 15893 15894 15895 /* Make description of knot array for interpolation in first parameter 15896 direction. */ 15897 15898 s1376 (st1, kn1, kk1, &sgt1, &kjkn1, &kjkk1, &kstat); 15899 if (kstat < 0) 15900 goto error; 15901 15902 15903 /* Make parameter values and derivative indicators. */ 15904 15905 s1890 (sgt1, kjkk1, kjkn1, &par1, &der1, &kstat); 15906 if (kstat < 0) 15907 goto error; 15908 15909 15910 /* Make description of knot array for interpolation in second parameter 15911 direction. */ 15912 15913 s1376 (st2, kn2, kk2, &sgt2, &kjkn2, &kjkk2, &kstat); 15914 if (kstat < 0) 15915 goto error; 15916 15917 15918 /* Make parameter values and derivative indicators. */ 15919 15920 s1890 (sgt2, kjkk2, kjkn2, &par2, &der2, &kstat); 15921 if (kstat < 0) 15922 goto error; 15923 15924 15925 /* Allocate array for values of surface put into torus equation. */ 15926 15927 sval1 = newarray (kjkn1 * kjkn2, DOUBLE); 15928 if (sval1 == SISL_NULL) 15929 goto err101; 15930 15931 15932 /* Calculate values to be interpolated. */ 15933 15934 /* Index of point to be stored. */ 15935 15936 kp = 0; 15937 15938 for (kj = 0; kj < kjkn2; kj++) 15939 { 15940 15941 spar[1] = par2[kj]; 15942 15943 for (ki = 0; ki < kjkn1; ki++) 15944 { 15945 /* Calculate values on 3-D surface */ 15946 15947 spar[0] = par1[ki]; 15948 15949 s1424 (tempsurf, 0, 0, spar, &klfs, &klft, sder, &kstat); 15950 if (kstat < 0) 15951 goto error; 15952 15953 /* 15954 * The calculation of a point on the torus surface 15955 * can be done in the following way. 15956 * 15957 * y = p - scentr 15958 * z = y - (y saxis) saxis 15959 * 15960 * The equation of the torus can be written 15961 * 15962 * 2 2 15963 * (y - R z/sqrt(z z) ) - r = 0 15964 * 15965 * 15966 * or by elliminating the square root: 15967 * 15968 * f = 15969 * 15970 * 2 2 2 2 2 2 2 15971 * (yy) + 2 (yy)(R -r ) - 4R zz + (R -r ) = 0 15972 * 15973 * or in 4-D homogeneous coordinates: 15974 * 15975 * 4 15976 * f = 15977 * 15978 * 2 2 2 2 2 2 4 2 2 2 15979 * (yy) + 2 w (yy)(R -r ) - 4w R zz + w (R -r ) = 0 15980 * 15981 * where Y = T - w*scentr, p+T/w 15982 * 15983 * We thus need to calculate yy and zz: 15984 */ 15985 15986 if (ikind == 2 || ikind == 4) 15987 { 15988 for (kl = 0; kl < 3; kl++) 15989 sy[kl] = sder[kl] - sder[3] * scentr[kl]; 15990 ww = sder[3] * sder[3]; 15991 } 15992 else 15993 { 15994 for (kl = 0; kl < 3; kl++) 15995 sy[kl] = sder[kl] - scentr[kl]; 15996 ww = (double) 1.0; 15997 } 15998 15999 tzn = s6scpr (sy, saxis, 3); 16000 16001 tyy = (double) 0.0; 16002 tzz = (double) 0.0; 16003 16004 /* Make z and necessary derivatives of z */ 16005 16006 for (kl = 0; kl < 3; kl++) 16007 { 16008 ty = sy[kl]; 16009 tz = ty - tzn * saxis[kl]; 16010 tyy += ty * ty; 16011 tzz += tz * tz; 16012 } 16013 16014 /* 2 2 2 16015 Now tyy = yy and tzz = zz, tbigr2 = R ,tdiffr2 = R - r */ 16016 16017 sval1[kp++] = tyy * tyy + ((double) 2.0 * ww * tyy + ww * ww * tdiffr2) * tdiffr2 16018 - (double) 4.0 *ww * tbigr2 * tzz; 16019 } 16020 } 16021 16022 cuopen = TRUE; 16023 16024 /* Interpolate in second parameter direction, the first parameter direction 16025 is treated as a point of dimension kjkn1 */ 16026 16027 s1891 (par2, sval1, kjkn1, kjkn2, kone, der2, cuopen, sgt2, &sval2, 16028 &kjkn2, kjkk2, kzero, kzero, &kstat); 16029 if (kstat < 0) 16030 goto error; 16031 16032 16033 /* Interpolate in first parameter direction, perform kjkn2 interpolations 16034 of one dimensional data */ 16035 16036 s1891 (par1, sval2, kone, kjkn1, kjkn2, der1, cuopen, sgt1, &sval3, 16037 &kjkn1, kjkk1, kzero, kzero, &kstat); 16038 if (kstat < 0) 16039 goto error; 16040 16041 *rsurf = SISL_NULL; 16042 *rsurf = newSurf (kjkn1, kjkn2, kjkk1, kjkk2, sgt1, sgt2, sval3, 1, 1, 1); 16043 if (*rsurf == SISL_NULL) 16044 goto err171; 16045 (*rsurf)->cuopen_1 = psurf->cuopen_1; 16046 (*rsurf)->cuopen_2 = psurf->cuopen_2; 16047 16048 /* Ok ! */ 16049 16050 goto out; 16051 16052 16053 /* Error in lower level function */ 16054 16055 error: 16056 *jstat = kstat; 16057 s6err ("s1378", *jstat, kpos); 16058 goto out; 16059 16060 /* Error in space allocation */ 16061 16062 err101: 16063 *jstat = -101; 16064 s6err ("s1378", *jstat, kpos); 16065 goto out; 16066 16067 /* Dimension not equal to 3 or confliciting dim */ 16068 16069 err104: 16070 *jstat = -104; 16071 s6err ("s1378", *jstat, kpos); 16072 goto out; 16073 16074 /* Could not create surface. */ 16075 16076 err171: 16077 *jstat = -171; 16078 s6err ("s1378", *jstat, kpos); 16079 goto out; 16080 16081 /* Error in torus description */ 16082 16083 err180: 16084 *jstat = -180; 16085 s6err ("s1378", *jstat, kpos); 16086 goto out; 16087 16088 out: 16089 16090 /* Release allocated arrays */ 16091 16092 if (sgt1 != SISL_NULL) 16093 freearray (sgt1); 16094 if (sgt2 != SISL_NULL) 16095 freearray (sgt2); 16096 if (sval1 != SISL_NULL) 16097 freearray (sval1); 16098 if (sval2 != SISL_NULL) 16099 freearray (sval2); 16100 if (sval3 != SISL_NULL) 16101 freearray (sval3); 16102 if (par1 != SISL_NULL) 16103 freearray(par1); 16104 if (par2 != SISL_NULL) 16105 freearray(par2); 16106 if (der1 != SISL_NULL) 16107 freearray(der1); 16108 if (der2 != SISL_NULL) 16109 freearray(der2); 16110 if ((ikind == 2 || ikind == 4) && (tempsurf != SISL_NULL)) 16111 freeSurf (tempsurf); 16112 16113 16114 return; 16115 } 16116 16117 //=========================================================================== 16118 void s1927 (double *w1, int nur, int ik, int *ed, double *w2, int nrc, 16119 double *w3, int nlr, double *ex[], double *ey, int *jstat) 16120 //=========================================================================== 16121 { 16122 int kpos = 0; 16123 int ii, jj; /* Loop control parameters */ 16124 int di; /* Pointer to diagonal element of W */ 16125 int midi; /* Parameter always equal: ii-di */ 16126 int dim; /* di minus 2: di-2 */ 16127 int mur; /* Used in calculation of index for w3 */ 16128 int nn; /* Number of rows/columns in w3 */ 16129 int nlc; /* Number of left columns in W */ 16130 double wii; /* Used to store values from matrix W */ 16131 double sum; /* Stores values for calculation of ex */ 16132 16133 *jstat = 0; 16134 16135 16136 /* Test if legal dimension of interpolatoin problem */ 16137 16138 if (nur < 1 || ik < 1 || nrc < 0 || nlr < 0) 16139 goto err160; 16140 nn = nur + nlr; 16141 nlc = nn - nrc; 16142 if (ik > nlc) 16143 goto err160; 16144 16145 16146 /* Allocate output array ex */ 16147 16148 *ex = new0array (nn, DOUBLE); 16149 if (*ex == SISL_NULL) 16150 goto err101; 16151 16152 16153 /* Solve L*z = ey */ 16154 16155 for (ii = 0; ii < nur; ii++) 16156 { 16157 di = ed[ii]; 16158 wii = w1[(di - 1) * nur + ii]; 16159 16160 16161 /* Test for errors */ 16162 16163 if (ii >= nlc) 16164 goto err163; 16165 if (di < 1 || ik < di || wii == (double) 0.0) 16166 goto err162; 16167 sum = ey[ii]; 16168 if (di > 1) 16169 { 16170 dim = di - 1; 16171 midi = ii - di + 1; 16172 for (jj = 0; jj < dim; jj++) 16173 sum -= w1[jj * nur + ii] * ((*ex)[jj + midi]); 16174 } 16175 (*ex)[ii] = sum / wii; 16176 } 16177 16178 /* Solve filled part of L*z = ey */ 16179 16180 for (; ii < nn; ii++) 16181 { 16182 mur = ii - nur; 16183 wii = w3[ii * nlr + mur]; 16184 if (wii == (double) 0.0) 16185 goto err162; 16186 sum = ey[ii]; 16187 if (ii >= 1) 16188 { 16189 for (jj = 0; jj < ii; jj++) 16190 sum -= w3[jj * nlr + mur] * ((*ex)[jj]); 16191 } 16192 (*ex)[ii] = sum / wii; 16193 } 16194 16195 /* Solve U*ex = z ; Jump if filled part of U is exhausted */ 16196 16197 for (ii = nn - 2; ii >= nur; ii--) 16198 { 16199 sum = (*ex)[ii]; 16200 mur = ii - nur; 16201 for (jj = ii + 1; jj < nn; jj++) 16202 sum -= w3[jj * nlr + mur] * ((*ex)[jj]); 16203 (*ex)[ii] = sum; 16204 } 16205 16206 /* Test if w2 contains diagonal elements */ 16207 16208 if (ii >= nlc) 16209 goto err163; 16210 if (nlc < nn) 16211 { 16212 for (; ii >= 0; ii--) 16213 { 16214 sum = (*ex)[ii]; 16215 for (jj = nlc; jj < nn; jj++) 16216 sum -= w2[(jj - nlc) * nur + ii] * ((*ex)[jj]); 16217 (*ex)[ii] = sum; 16218 } 16219 } 16220 for (ii = nur - 1; ii >= 0; ii--) 16221 { 16222 di = ed[ii]; 16223 if (di < ik) 16224 { 16225 sum = (*ex)[ii]; 16226 midi = ii - di + 1; 16227 for (jj = di; jj < ik; jj++) 16228 sum -= w1[jj * nur + ii] * ((*ex)[jj + midi]); 16229 (*ex)[ii] = sum; 16230 } 16231 } 16232 16233 goto out; 16234 16235 16236 /* Memory error, array ex not allocated */ 16237 16238 err101: 16239 *jstat = -101; 16240 s6err ("s1927", *jstat, kpos); 16241 goto out; 16242 16243 /* error in dimension of interpolation problem */ 16244 16245 err160: 16246 *jstat = -160; 16247 s6err ("s1927", *jstat, kpos); 16248 goto out; 16249 16250 /* W is non-invertible */ 16251 16252 err162: 16253 *jstat = -162; 16254 s6err ("s1927", *jstat, kpos); 16255 goto out; 16256 16257 /* w2 contains diagonal element */ 16258 16259 err163: 16260 *jstat = -163; 16261 s6err ("s1927", *jstat, kpos); 16262 goto out; 16263 16264 out: 16265 return; 16266 } 16267 16268 16269 //=========================================================================== 16270 void s1926 (double *w1, int nur, int ik, int *ed, double *w2, int nrc, 16271 double *w3, int nlr, int *jstat) 16272 //=========================================================================== 16273 { 16274 int kpos = 0; 16275 int ii, jj; /* Loop control parameters */ 16276 int ll; 16277 int nn; /* Number of rows/columns in W */ 16278 int nlc; /* Number of left columns in W */ 16279 int di; /* Pointer to diagonal element of W */ 16280 int midi; /* Parameters used in elimination alg. */ 16281 int midl; 16282 int korr; /* midl - midi */ 16283 int mur; /* Used in calculation of index for w3 */ 16284 double wii; /* Used to store values from matrix W */ 16285 double wli; 16286 16287 *jstat = 0; 16288 16289 16290 /* Test if legal dimension of interpolation problem */ 16291 16292 if (nur < 1 || (nur >= 1 && ik < 1) || nrc < 0 || nlr < 0) 16293 goto err160; 16294 16295 nn = nur + nlr; 16296 nlc = nn - nrc; 16297 if (ik > nlc) 16298 goto err160; 16299 16300 16301 /* Elimination scheme, jump if band part of W is completed */ 16302 16303 for (ii = 0; ii < nur; ii++) 16304 { 16305 di = ed[ii]; 16306 wii = w1[(di - 1) * nur + ii]; 16307 16308 16309 /* Test for errors */ 16310 16311 if (ii >= nlc) 16312 goto err163; 16313 if ((di < 1) || (ik < di) || (wii == 0.0)) 16314 goto err162; 16315 16316 16317 /* Jump if W(ii,jj) is trivially zero, jj = ii+1,ii+2,...,nlr */ 16318 16319 if (di < ik) 16320 { 16321 for (jj = di; jj < ik; jj++) 16322 w1[jj * nur + ii] /= wii; 16323 16324 16325 /* Perform elimination row by row */ 16326 16327 midi = ii - di; 16328 for (ll = ii + 1;; ll++) 16329 { 16330 /* Jump if ii-th element of rows of band-part has been 16331 * eliminated */ 16332 16333 if (ll >= nur) 16334 break; 16335 midl = ll - ed[ll]; 16336 16337 16338 /* Jump if W(ii,jj) is trivially zero, jj = ll,ll+1,...,nur */ 16339 16340 if (midl >= ii) 16341 break; 16342 korr = midl - midi; 16343 wli = w1[(di - korr - 1) * nur + ll]; 16344 for (jj = di; jj < ik; jj++) 16345 w1[(jj - korr) * nur + ll] += -w1[jj * nur + ii] * wli; 16346 } 16347 16348 /* Eliminate ii-th column of w3 using ii-th row from w1 */ 16349 16350 if (nlr > 0) 16351 for (ll = 0; ll < nlr; ll++) 16352 { 16353 wli = w3[ii * nlr + ll]; 16354 for (jj = di; jj < ik; jj++) 16355 w3[(jj + midi + 1) * nlr + ll] -= w1[jj * nur + ii] * wli; 16356 } 16357 } 16358 } 16359 16360 /* Apply the above elimination scheme on w2 */ 16361 16362 if (nrc > 0) 16363 { 16364 /* Jump if band part of W is completed or if system error 16365 * occures, i.e. if w2 contains some diagonal elements of W) */ 16366 16367 for (ii = 0; ii < nur; ii++) 16368 { 16369 /* Test for error */ 16370 16371 if (ii > nlc) 16372 goto err163; 16373 16374 di = ed[ii]; 16375 wii = w1[(di - 1) * nur + ii]; 16376 for (jj = 0; jj < nrc; jj++) 16377 w2[jj * nur + ii] /= wii; 16378 16379 16380 /* Perform elimination row by row */ 16381 16382 midi = ii - di; 16383 for (ll = ii + 1;; ll++) 16384 { 16385 16386 /* Jump if ii-th element of rows of band-part has been 16387 eliminated */ 16388 16389 if (ll >= nur) 16390 break; 16391 midl = ll - ed[ll]; 16392 16393 16394 /* Jump if W(ii,jj) is trivially zero, jj = ll,ll+1,...,nur */ 16395 16396 if (midl >= ii) 16397 break; 16398 korr = midl - midi; 16399 wli = w1[(di - korr - 1) * nur + ll]; 16400 for (jj = 0; jj < nrc; jj++) 16401 w2[jj * nur + ll] -= w2[jj * nur + ii] * wli; 16402 } 16403 16404 /* Eliminate ii-th column of w3 using ii-th row from w2 */ 16405 16406 for (ll = 0; ll < nlr; ll++) 16407 { 16408 wli = w3[ii * nlr + ll]; 16409 for (jj = nlc; jj < nn; jj++) 16410 w3[jj * nlr + ll] -= w2[(jj - nlc) * nur + ii] * wli; 16411 } 16412 } 16413 } 16414 16415 /* Eliminate w3-part of W */ 16416 16417 if (ii >= nn) 16418 goto out; 16419 for (; ii < nn; ii++) 16420 { 16421 16422 /* 1 <= ii <= nn */ 16423 16424 mur = ii - nur; 16425 wii = w3[ii * nlr + mur]; 16426 if (wii == (double) 0.0) 16427 goto err162; 16428 16429 16430 /* 1 <= ii < nn */ 16431 16432 for (jj = ii + 1; jj < nn; jj++) 16433 w3[jj * nlr + mur] /= wii; 16434 for (ll = mur + 1; ll < nlr; ll++) 16435 { 16436 wli = w3[ii * nlr + ll]; 16437 for (jj = ii + 1; jj < nn; jj++) 16438 w3[jj * nlr + ll] -= w3[jj * nlr + mur] * wli; 16439 } 16440 } 16441 16442 goto out; 16443 16444 16445 /* W may be non-invertible */ 16446 16447 err162: 16448 *jstat = -162; 16449 s6err ("s1926", *jstat, kpos); 16450 goto out; 16451 16452 /* Error in dimension in interpolation problem */ 16453 16454 err160: 16455 *jstat = -160; 16456 s6err ("s1926", *jstat, kpos); 16457 goto out; 16458 16459 /* w2 contains diagonal elements */ 16460 16461 err163: 16462 *jstat = -163; 16463 s6err ("s1926", *jstat, kpos); 16464 goto out; 16465 16466 out: 16467 return; 16468 } 16469 16470 //=========================================================================== 16471 void s1897 (double et[], int ik, double ax, int left, int deriv, 16472 double ebiatx[], int *jstat) 16473 //=========================================================================== 16474 { 16475 int kpos = 0; 16476 int local_array_allocated = FALSE; 16477 int j; /* Loop control variables. */ 16478 int count; 16479 double dummy; /* Used for temporary calculations.*/ 16480 double fak; 16481 double term; 16482 double saved; 16483 double stmp[2*s1897_MAX_IK + 1]; /* temporary storage */ 16484 double *sltmp = SISL_NULL; /* temp storage allocated only 16485 if ik > MAX_IK */ 16486 double *edltr = SISL_NULL; /* pointer into temporary storage */ 16487 double *edltl = SISL_NULL; /* pointer into temporary storage */ 16488 16489 /* 16490 * Initialize. 16491 * ----------- 16492 */ 16493 16494 *jstat = 0; 16495 16496 if (ik > s1897_MAX_IK) 16497 { 16498 /* 16499 * We need to allocate a larger local tmp array; Do so. 16500 * ---------------------------------------------------- 16501 */ 16502 16503 if ((sltmp = newarray(2 * ik + 1, DOUBLE)) == SISL_NULL) 16504 goto err101; 16505 local_array_allocated = TRUE; 16506 16507 } 16508 else 16509 sltmp = stmp; 16510 16511 /* 16512 * Set pointer into local array. 16513 * ----------------------------- 16514 */ 16515 16516 edltr = sltmp; 16517 edltl = sltmp + ik; 16518 16519 ebiatx[0] = (double) 1.0; 16520 16521 for (j = 1; j <= deriv; j++) 16522 { 16523 edltr[j - 1] = et[left + j] - ax; 16524 edltl[j - 1] = ax - et[left + 1 - j]; 16525 fak = (double) j; 16526 16527 saved = (double) 0.0; 16528 for (count = 1; count <= j; count++) 16529 { 16530 dummy = edltr[count - 1] + edltl[j - count]; 16531 if (dummy <= (double) 0.0) 16532 goto err112; 16533 16534 term = fak * ebiatx[count - 1] / dummy; 16535 ebiatx[count - 1] = saved - term; 16536 saved = term; 16537 } 16538 ebiatx[j] = saved; 16539 } 16540 16541 for (; j < ik; j++) 16542 { 16543 edltr[j - 1] = et[left + j] - ax; 16544 edltl[j - 1] = ax - et[left + 1 - j]; 16545 fak = ((double) j) / (double) (j - deriv); 16546 16547 saved = (double) 0.0; 16548 for (count = 1; count <= j; count++) 16549 { 16550 dummy = edltr[count - 1] + edltl[j - count]; 16551 if (dummy <= (double) 0.0) 16552 goto err112; 16553 16554 term = fak * ebiatx[count - 1] / dummy; 16555 ebiatx[count - 1] = saved + edltr[count - 1] * term; 16556 saved = edltl[j - count] * term; 16557 } 16558 ebiatx[j] = saved; 16559 } 16560 16561 /* OK */ 16562 16563 goto out; 16564 16565 /* Error in scratch allocation. */ 16566 16567 err101: 16568 *jstat = -101; 16569 s6err ("s1897", *jstat, kpos); 16570 goto out; 16571 16572 /* Error in knot vector. */ 16573 16574 err112: 16575 *jstat = -112; 16576 s6err ("s1897", *jstat, kpos); 16577 goto out; 16578 16579 out: 16580 if (local_array_allocated) 16581 freearray (sltmp); 16582 return; 16583 } 16584 16585 //=========================================================================== 16586 void s1925 (double etau[], double epoint[], int inbpnt, int eder[], 16587 double et[], double ebcoef[], int in, int ik, int iright, int dim, 16588 double ew1[], int nur, int ed[], double ew2[], int inrc, double ew3[], 16589 int inlr, int *jstat) 16590 //=========================================================================== 16591 { 16592 int kstat = 0; 16593 int kpos = 0; /* Position of error */ 16594 int open; /* Used as a boolean parameter to 16595 * indicate open or closed curve: 16596 * open=TRUE ; Open curve 16597 * open=FALSE ; Closed curve */ 16598 int left; /* An integer chosen (usually) so that 16599 * et(left-1)<=point<et(left) */ 16600 int leftmax; 16601 int leftmin; 16602 int leftdel; 16603 int kmod; /* Used in calculation of ew3 index */ 16604 int isum; 16605 int ii, jj, kl, stop; /* Loop control parameters */ 16606 int dim1; /* Loop control parameter, 16607 * values: 0..dim-1 */ 16608 int imnur; /* Equals ii-nur */ 16609 int nn; /* Equals nur+inlr 16610 * i.e. Number of rows/columns in W */ 16611 int nlc; /* Number of lower columns 16612 * Equals inbpnt-inrc */ 16613 int kk; /* Minimum: ik or nlc */ 16614 double tk; /* ik-th element of knot vector */ 16615 double taudel; /* to left and taui */ 16616 int lfmkm; /* Equals left-ik */ 16617 int iadd; 16618 int iadd_save; 16619 int kmiadd; 16620 int isub; 16621 int kmisub; /* Equals ik-isub */ 16622 int ish; 16623 int ideri; /* Derivative order indicator */ 16624 int store; 16625 16626 double taui; /* Parametrization value = etau[ii] */ 16627 double *mcoef = SISL_NULL; /* Arrays for internal use in */ 16628 double *ebder = SISL_NULL; /* this subroutine */ 16629 double sarray[s1925_MAX_ARRAY_SIZE]; 16630 int alloc_needed=FALSE; 16631 16632 *jstat = 0; 16633 16634 nn = nur + inlr; 16635 16636 /* Test if legal input */ 16637 16638 if (ik < 1) 16639 goto err109; 16640 16641 if ((nur < 0) || ((nur + inlr) != inbpnt) || (inrc < 0) || (inlr < 0)) 16642 goto err160; 16643 16644 nlc = inbpnt - inrc; 16645 kk = MIN (ik, nlc); 16646 tk = et[ik - 1]; 16647 16648 16649 /* Test if open or closed curve */ 16650 16651 if (inbpnt == in) 16652 open = TRUE; 16653 else 16654 open = FALSE; 16655 16656 if (open == TRUE) 16657 { 16658 /* Open curve */ 16659 16660 taudel = (double) 0.0; 16661 leftdel = 0; 16662 leftmin = ik - 1; 16663 leftmax = in -1; 16664 if ((inrc != 0) || (inlr != 0)) 16665 goto err160; 16666 } 16667 else 16668 { 16669 /* Closed curve, note: we assume that et(in) < etau(inbpnt) */ 16670 16671 if ((inbpnt + ik - 1) != in) 16672 goto err160; 16673 leftdel = in +1 - ik; 16674 iadd = (ik - 1) / 2; 16675 leftmax = leftdel + iadd - 1; 16676 leftmin = ik - iadd - 1; 16677 taudel = et[in] -tk; 16678 16679 if ((iadd != inrc) || ((inrc + inlr) != (ik - 1))) 16680 goto err160; 16681 16682 if (inrc > 0) 16683 { 16684 stop = nur * inrc; 16685 for (ii = 0; ii < stop; ii++) 16686 ew2[ii] = (double) 0.0; 16687 } 16688 } 16689 16690 /* Band part of W */ 16691 16692 /* Allocate array ebder */ 16693 16694 left = leftmin; 16695 if (ik > s1925_MAX_ARRAY_SIZE) 16696 { 16697 if ((ebder = newarray (ik, DOUBLE)) == SISL_NULL) 16698 goto err101; 16699 alloc_needed = TRUE; 16700 } 16701 else 16702 ebder = sarray; 16703 16704 for (ii = 0; ii < nur; ii++) 16705 { 16706 taui = etau[ii]; 16707 ideri = eder[ii]; 16708 16709 16710 /* Locate left so that et[left] <= taui < et[left+1] */ 16711 16712 while (left < leftmax && et[left + 1] <= taui) 16713 left++; 16714 16715 16716 /* et(left-1) <= taui < et(left) */ 16717 16718 ed[ii] = ii - (left - ik); 16719 16720 16721 /* Test if error in interpolation problem */ 16722 16723 if ((ed[ii] < 1) || (ed[ii] > ik)) 16724 goto err165; 16725 16726 16727 iadd = MAX (0, ik - left - 1); 16728 iadd_save = iadd; 16729 kmiadd = ik - iadd; 16730 16731 16732 /* Compute the value and ideri first derivative of the 16733 ik (possibly) nonzero B-spline associated with the knot 16734 vector et at a point */ 16735 16736 if (iadd > 0) 16737 { 16738 s1897 (et, ik, taui + taudel, left + leftdel, ideri, ebder, &kstat); 16739 if (kstat < 0) 16740 goto error; 16741 16742 ed[ii] -= iadd; 16743 ish = inrc - iadd; 16744 if ((ish < 0) || (kmiadd < 0)) 16745 goto err160; 16746 16747 for (jj = 0; jj < iadd; jj++) 16748 { 16749 ew1[(jj + kmiadd) * nur + ii] = (double) 0.0; 16750 ew2[(jj + ish) * nur + ii] = ebder[jj]; 16751 } 16752 } 16753 else 16754 { 16755 s1897 (et, ik, taui, left, ideri, ebder, &kstat); 16756 if (kstat < 0) 16757 goto error; 16758 } 16759 16760 isub = MAX (0, ii - ed[ii] + kmiadd - nlc + 1); 16761 kmisub = ik - isub; 16762 if (isub > 0) 16763 { 16764 ish = isub - (kmiadd - kk); 16765 ed[ii] += ish; 16766 iadd -= ish; 16767 if (kmisub < 0) 16768 goto err160; 16769 stop = MIN (ik, kmisub + inrc); 16770 16771 for (jj = kmisub; jj < stop; jj++) 16772 { 16773 ew1[(jj - kmisub) * nur + ii] = (double) 0.0; 16774 ew2[(jj - kmisub) * nur + ii] = ebder[jj]; 16775 } 16776 } 16777 for (jj = iadd_save; jj < kmisub; jj++) 16778 ew1[(jj - iadd) * nur + ii] = ebder[jj]; 16779 16780 16781 /* Test if error in dimension of interpolation problem */ 16782 16783 if ((ideri < 0) || (ik <= ideri)) 16784 goto err160; 16785 } 16786 16787 /* Band part of W is now completed */ 16788 16789 if (ii < inbpnt) 16790 { 16791 /* Will compute lower, filled part of W for closed 16792 curve interpolation */ 16793 16794 if ((inbpnt + ik - 1) != in) 16795 goto err160; 16796 store = inlr * inbpnt; 16797 for (jj = 0; jj < store; jj++) 16798 ew3[jj] = (double) 0.0; 16799 16800 16801 /* Repeat until filled part of W is completed */ 16802 16803 for (; ii < inbpnt; ii++) 16804 { 16805 taui = etau[ii]; 16806 16807 16808 /* Locate left so that et[left] <= taui < et[left+1] */ 16809 16810 while (left < in -1 && et[left + 1] <= taui) 16811 left++; 16812 16813 16814 /* et(left-1) <= taui < et(left) */ 16815 16816 ideri = eder[ii]; 16817 16818 16819 /* Compute the value and the ideri first derivatives of the 16820 ik (possibly) nonzero B-spline associated with the knot 16821 vector et at the point (taui) */ 16822 16823 s1897 (et, ik, taui, left, ideri, ebder, &kstat); 16824 if (kstat < 0) 16825 goto error; 16826 16827 imnur = ii - nur; 16828 lfmkm = left - ik; 16829 for (jj = 0; jj < ik; jj++) 16830 { 16831 isum = jj + lfmkm + 1; 16832 if (isum >= 0) 16833 kmod = isum % inbpnt; 16834 if (isum < 0) 16835 kmod = (isum + 1) % inbpnt + in -1; 16836 ew3[kmod * inlr + imnur] = ebder[jj]; 16837 } 16838 if ((ideri < 0) || (ik <= ideri)) 16839 goto err160; 16840 } 16841 } 16842 if (inlr != (inbpnt - nur)) 16843 goto err160; 16844 16845 16846 /* W is now contained in ew1, ew2 and ew3 as required 16847 by the subroutine s1898 */ 16848 16849 s1926 (ew1, nur, kk, ed, ew2, inrc, ew3, inlr, &kstat); 16850 if (kstat < 0) 16851 goto error; 16852 16853 store = iright * dim * inbpnt; 16854 for (jj = 0; jj < store; jj++) 16855 ebcoef[jj] = epoint[jj]; 16856 16857 16858 /* epoint is now properly contained in ebcoef. 16859 * Solve interpolation equations */ 16860 16861 if (nn > s1925_MAX_ARRAY_SIZE) 16862 { 16863 if (alloc_needed) 16864 { 16865 if ((ebder = increasearray(ebder,nn,DOUBLE)) == SISL_NULL) 16866 goto err101; 16867 } 16868 else 16869 { 16870 if ((ebder = newarray(nn,DOUBLE)) == SISL_NULL) 16871 goto err101; 16872 alloc_needed = TRUE; 16873 } 16874 } 16875 16876 for (kl = 0; kl < iright; kl++) 16877 for (dim1 = 0; dim1 < dim; dim1++) 16878 { 16879 store = inbpnt * dim * kl + dim1; 16880 for (jj = 0; jj < nn; jj++, store += dim) 16881 ebder[jj] = ebcoef[store]; 16882 16883 s1927 (ew1, nur, kk, ed, ew2, inrc, ew3, inlr, &mcoef, ebder, &kstat); 16884 if (kstat < 0) 16885 goto error; 16886 16887 store = inbpnt * dim * kl + dim1; 16888 for (jj = 0; jj < nn; jj++, store += dim) 16889 ebcoef[store] = mcoef[jj]; 16890 16891 if(mcoef != SISL_NULL) /* KYS 200594: healed memory leak */ 16892 { 16893 freearray(mcoef); 16894 mcoef = SISL_NULL; 16895 } 16896 } 16897 16898 goto out; 16899 16900 16901 /* Error in array allocations */ 16902 16903 err101: 16904 *jstat = -101; 16905 s6err ("s1925", *jstat, kpos); 16906 goto out; 16907 16908 /* Order of B-spline zero or negative */ 16909 16910 err109: 16911 *jstat = -109; 16912 s6err ("s1925", *jstat, kpos); 16913 goto out; 16914 16915 /* Error in dimension of interpolation problem */ 16916 16917 err160: 16918 *jstat = -160; 16919 s6err ("s1925", *jstat, kpos); 16920 goto out; 16921 16922 /* Error in lower level routine */ 16923 16924 error: 16925 *jstat = kstat; 16926 s6err ("s1925", *jstat, kpos); 16927 goto out; 16928 16929 /* Error in interpolation problem */ 16930 16931 err165: 16932 *jstat = -165; 16933 s6err ("s1925", *jstat, kpos); 16934 goto out; 16935 16936 out: 16937 if (alloc_needed) 16938 freearray (ebder); 16939 if (mcoef != SISL_NULL) 16940 freearray (mcoef); 16941 return; 16942 } 16943 16944 16945 //=========================================================================== 16946 void s1891 (double etau[], double epoint[], int idim, int inbpnt, int iright, 16947 int eder[], int iopen, double et[], double *ebcoef[], int *in, 16948 int ik, int inlr, int inrc, int *jstat) 16949 //=========================================================================== 16950 { 16951 int kstat = 0; 16952 int kpos = 0; /* Position of error */ 16953 int ii; /* Loop control parameter */ 16954 int limit1, limit2; /* Loop parameters */ 16955 int kj, kl; 16956 int kdum, stop; 16957 int nur; /* Number of upper rows in W */ 16958 int inlx; /* Equal to inlr if inlr>0, else=1 */ 16959 int inrx; /* Equal to inrc if inrc>0, else=1 */ 16960 int edarray[s1891_MAX_SIZE]; /* Array for ed below */ 16961 int alloc_needed=FALSE; 16962 int *ed = SISL_NULL; /* Arrays defining elements of W */ 16963 double *ewarray=SISL_NULL; /* Array for ew1, ew2 and ew3 */ 16964 double *ew1 = SISL_NULL; /* See subroutine s1926 */ 16965 double *ew2 = SISL_NULL; 16966 double *ew3 = SISL_NULL; 16967 16968 *jstat = 0; 16969 16970 16971 /* Test if legal input. */ 16972 16973 if (ik < 1 || idim < 1) goto err112; 16974 16975 /* Indicate dimension of B-spline. */ 16976 16977 *in = inbpnt; 16978 if (iopen != SISL_CRV_OPEN) *in +=ik - 1; 16979 16980 *ebcoef = new0array (*in *idim * iright, DOUBLE); 16981 if (*ebcoef == SISL_NULL) goto err101; 16982 16983 if ((nur = inbpnt - inlr) > s1891_MAX_SIZE) 16984 alloc_needed = TRUE; 16985 16986 /* Allocate arrays ew1, ew2, ew3, ed. */ 16987 16988 inlx = MAX (1, inlr); 16989 inrx = MAX (1, inrc); 16990 limit1 = (ik * nur) + (inrx * nur) + (inlx * inbpnt); 16991 16992 if ((ewarray = new0array(limit1 + 1,DOUBLE)) == SISL_NULL) goto err101; 16993 16994 ew1 = ewarray; 16995 ew2 = ew1 + (ik * nur); 16996 ew3 = ew2 + (inrx * nur); 16997 16998 if (alloc_needed) 16999 { 17000 if ((ed = new0array(nur,INT)) == SISL_NULL) 17001 goto err101; 17002 } 17003 else 17004 ed = edarray; 17005 17006 s1925 (etau, epoint, inbpnt, eder, et, *ebcoef,*in, ik, iright, 17007 idim, ew1, nur, ed, ew2, inrc, ew3, inlr, &kstat); 17008 if (kstat < 0) goto error; 17009 17010 /* For closed B-spline curves we have: 17011 * ebcoef(i) = ebcoef(i+inbpnt) ; i=1,...,ik-1. */ 17012 17013 if (iopen != SISL_CRV_OPEN) 17014 { 17015 stop = ik - 1; 17016 for (kl = 0; kl < iright; kl++) 17017 { 17018 kdum = *in *kl; 17019 for (kj = 0; kj < stop; kj++) 17020 { 17021 limit2 = (kj + kdum) * idim; 17022 limit1 = inbpnt * idim + limit2; 17023 for (ii = 0; ii < idim; ii++) 17024 (*ebcoef)[limit1 + ii] = (*ebcoef)[limit2 + ii]; 17025 } 17026 } 17027 } 17028 17029 goto out; 17030 17031 /* Error in lower level routine */ 17032 17033 error: 17034 *jstat = kstat; 17035 s6err ("s1891", *jstat, kpos); 17036 goto out; 17037 17038 /* Error in array allocations */ 17039 17040 err101: 17041 *jstat = -101; 17042 s6err ("s1891", *jstat, kpos); 17043 goto out; 17044 17045 /* Error in description of B-spline */ 17046 17047 err112: 17048 *jstat = -112; 17049 s6err ("s1891", *jstat, kpos); 17050 goto out; 17051 17052 out: 17053 if (alloc_needed) freearray (ed); 17054 if (ewarray) freearray (ewarray); 17055 return; 17056 } 17057 17058 //=========================================================================== 17059 void s1890 (double oknots[], int oik, int oin, double *par[], int *der[], int *jstat) 17060 //=========================================================================== 17061 { 17062 int kpos = 0; 17063 int count1, count2; /* Loop control variables */ 17064 int start, stop; 17065 int numb; /* Number of wrong parameters */ 17066 17067 double sum; /* Sum of knot values */ 17068 double pvl; /* Single parameter value */ 17069 double delta; /* Used for correcting wrong 17070 * parameter values */ 17071 17072 *jstat = 0; 17073 17074 17075 /* Test if legal input. */ 17076 17077 if (oik <= 1 || oin < oik) 17078 goto err112; 17079 17080 17081 /* Test if input knot vector degenerate. */ 17082 17083 if (oknots[oik - 1] >= oknots[oin]) 17084 goto err112; 17085 17086 17087 /* Allocate arrays par and der. */ 17088 17089 *par = newarray (oin, DOUBLE); 17090 if (*par == SISL_NULL) 17091 goto err101; 17092 *der = new0array (oin, INT); 17093 if (*der == SISL_NULL) 17094 goto err101; 17095 17096 17097 /* P R O D U C E P A R A M E T E R V A L U E S. 17098 * First we produce parameter values by a simple algorithm. 17099 * The parameter values calculated in a wrong way are then corrected. */ 17100 17101 (*par)[0] = oknots[oik - 1]; 17102 (*par)[oin - 1] = oknots[oin]; 17103 17104 for (count1 = 2; count1 < oin; count1++) 17105 { 17106 stop = count1 + oik; 17107 sum = (double) 0.0; 17108 for (count2 = count1; count2 <= stop; count2++) 17109 sum += oknots[count2 - 1]; 17110 (*par)[count1 - 1] = sum / (oik + 1); 17111 } 17112 17113 /* Find second distinct knot value. */ 17114 17115 pvl = oknots[oik - 1]; 17116 for (count1 = oik; oknots[count1] <= pvl; count1++) ; 17117 17118 17119 /* Find number of parameter values with wrong value at start of curve. */ 17120 17121 pvl = (oknots[oik - 1] + oknots[count1]) / (double)2.0; 17122 for (numb = 0, start = 1; (*par)[start] <= pvl; start++, numb++) ; 17123 17124 if (numb > 0) 17125 { 17126 delta = (pvl - (*par)[0]) / (numb + 1); 17127 17128 /* Fill inn missing parameter values. */ 17129 17130 pvl = (*par)[0] + delta; 17131 17132 for (count1 = 1; count1 <= numb; count1++) 17133 { 17134 (*par)[count1] = pvl; 17135 pvl += delta; 17136 } 17137 } 17138 17139 /* Find last but one distinct knot value. */ 17140 17141 pvl = oknots[oin]; 17142 for (count1 = oin - 1; oknots[count1] >= pvl; count1--) ; 17143 17144 17145 /* Find end parameters in wrong interval. */ 17146 17147 pvl = (oknots[count1] + oknots[oin + 1]) / (double) 2.0; 17148 for (numb = 0, stop = oin - 2; (*par)[stop] >= pvl; stop--, numb++) ; 17149 17150 if (numb > 0) 17151 { 17152 delta = ((*par)[oin - 1] - pvl) / (numb + 1); 17153 pvl = (*par)[oin - 1] - delta; 17154 for (count1 = 1; count1 <= numb; count1++) 17155 { 17156 (*par)[oin - 1 - count1] = pvl; 17157 pvl -= delta; 17158 } 17159 } 17160 17161 /* Make derivative indicators */ 17162 17163 /* We used new0array which initializes all elements with zeroes 17164 * and then this code is redundant. 17165 * 17166 * for (count1 = 0; count1 < oin; count1++) 17167 * (*der)[count1] = 0; 17168 */ 17169 /* Knots produced */ 17170 17171 goto out; 17172 17173 17174 /* Not enough memory. */ 17175 17176 err101: 17177 *jstat = -101; 17178 s6err ("s1890", *jstat, kpos); 17179 goto out; 17180 17181 /* Error in description of B-spline. */ 17182 17183 err112: 17184 *jstat = -112; 17185 s6err ("s1890", *jstat, kpos); 17186 goto out; 17187 17188 out: 17189 return; 17190 } 17191 17192 17193 //=========================================================================== 17194 void s1894 (double oknots[], int oik, int oin, int der1, int der2, double earray[], 17195 int dimp1, int narr, double *nknots[], int *nik, int *nin, int *jstat) 17196 //=========================================================================== 17197 { 17198 int size; /* The total size of earray. */ 17199 int mult; /* Multiplicity of knots */ 17200 int numb; /* Number of new knots. */ 17201 int kdim; /* dimp1 -1 (sub-matrix dimension) */ 17202 int empty; /* Used to check if sub-matrix of earray 17203 is zero. */ 17204 int kl; /* Loop control varibles. */ 17205 int count1; 17206 int count2; 17207 int count3; 17208 int start; 17209 int stop; 17210 17211 double eps; /* Resolution. */ 17212 double maximum; /* The maximum value in et. */ 17213 double prev; /* Knot value. (extracted from orig) */ 17214 double curr; /* Knot value. (extracted from orig) */ 17215 int kpos = 0; 17216 int der = max(der1, der2); 17217 17218 *jstat = 0; 17219 17220 17221 /* Test if legal input. */ 17222 17223 if (oik <= 1 || oin < oik) 17224 goto err112; 17225 17226 17227 /* Test if knot vector degenerate. */ 17228 17229 if (oknots[oik - 1] >= oknots[oin]) 17230 goto err112; 17231 17232 17233 /* The maximal number of knots to be produced at a specified knot value 17234 * is the order of the B-spline basis produced. */ 17235 17236 /* Allocate space for new knot vector */ 17237 17238 (*nknots) = newarray ((oin + oik) * oik, DOUBLE); 17239 if (*nknots == SISL_NULL) 17240 goto err101; 17241 17242 17243 /* Check if sub-matrix is zero. */ 17244 17245 kdim = dimp1 - 1; 17246 size = dimp1 * dimp1; 17247 empty = TRUE; 17248 17249 for (count1 = 0; count1 < narr && empty; count1++) 17250 for (count2 = 0; count2 < kdim && empty; count2++) 17251 for (count3 = 0; count3 < kdim && empty; count3++) 17252 if (earray[count1 * size + count2 * dimp1 + count3] != (double)0.) 17253 empty = FALSE; 17254 17255 17256 /* Assign value to nk. */ 17257 17258 if (empty) 17259 (*nik) = oik - min (der1, der2); 17260 else 17261 (*nik) = 2 * oik - der1 - der2 - 1; 17262 if ((*nik) < 2) 17263 (*nik) = 2; 17264 *nin = 0; 17265 17266 17267 /* Make resolution to be used for testing of knot value equalness. */ 17268 17269 eps = fabs (oknots[oin] - oknots[oik - 1]) * 1.0e-11; 17270 17271 17272 /* Production of knots. Initiate for calculation of knots. 17273 Find first knot not equal to start of curve. */ 17274 17275 maximum = oknots[oin]; 17276 prev = oknots[oik - 1]; 17277 for (kl = oik; prev >= oknots[kl]; kl++) ; 17278 17279 curr = oknots[kl]; 17280 for (mult = oik; curr < maximum; mult++) 17281 { 17282 if (curr < prev) 17283 goto err112; 17284 17285 if (prev > curr || curr > prev + eps) 17286 { 17287 17288 /* New knot value found. Fill in old value. */ 17289 17290 /* numb = (*nik) - oik + mult; */ 17291 numb = (*nik) - oik + mult + der; 17292 if (numb > (*nik)) 17293 numb = (*nik); 17294 17295 17296 /* If numb >= nik, test if all the numb knots are equal 17297 or if they only are equal within the resolution eps. 17298 If not totally equal knumb=nik-1. */ 17299 17300 if (numb == (*nik)) 17301 { 17302 /* start = max (kl - oik, 1); 17303 stop = kl - 2; 17304 for (count1 = start; count1 <= stop; count1++) 17305 if (oknots[count1 - 1] != oknots[count1]) 17306 numb = (*nik) - 1; */ 17307 17308 start = kl - oik + der; 17309 stop = kl - 2; 17310 for (count1 = start; count1 <= stop; count1++) 17311 if (oknots[count1] != oknots[count1 + 1]) 17312 numb = (*nik) - 1; 17313 } 17314 17315 if (prev == oknots[oik - 1]) 17316 numb = (*nik); 17317 for (count1 = 1; count1 <= numb; count1++) 17318 (*nknots)[(*nin)++] = prev; 17319 17320 17321 /* Initialize multiplicity. */ 17322 17323 mult = 0; 17324 prev = curr; 17325 } 17326 kl++; 17327 curr = oknots[kl]; 17328 } 17329 17330 /* Knot for the next last knot value not produced. */ 17331 17332 /* numb = min ((*nik) - oik + mult, (*nik)); */ 17333 numb = min ((*nik) - oik + mult + der, (*nik)); 17334 17335 17336 /* If numb >= nik, test if all the numb knots are equal or if they 17337 * only are equal within the resolution eps. */ 17338 17339 /* I not totally equal numb=nik-1. */ 17340 17341 if (numb >= (*nik)) 17342 { 17343 /* start = max (kl - oik, 1); 17344 stop = kl - 2; 17345 for (count1 = start; count1 <= stop; count1++) 17346 if (oknots[count1 - 1] != oknots[count1]) 17347 numb = (*nik) - 1; */ 17348 17349 start = kl - oik + der; 17350 stop = kl - 2; 17351 for (count1 = start; count1 <= stop; count1++) 17352 if (oknots[count1] != oknots[count1 + 1]) 17353 numb = (*nik) - 1; 17354 } 17355 17356 for (count1 = 1; count1 <= numb; count1++) 17357 (*nknots)[(*nin)++] = prev; 17358 17359 17360 /* Knot at et[oin+1] not produced. */ 17361 17362 for (count1 = 1; count1 <= (*nik); count1++) 17363 (*nknots)[(*nin)++] = maximum; 17364 17365 17366 /* Knots produced. Correct nin and length of nknots. */ 17367 17368 (*nin) -= (*nik); 17369 *nknots = increasearray (*nknots, (*nik) + (*nin), DOUBLE); 17370 if (*nknots == SISL_NULL) 17371 goto err101; 17372 17373 goto out; 17374 17375 /* Not enough memory. */ 17376 17377 err101: 17378 *jstat = -101; 17379 s6err ("s1894", *jstat, kpos); 17380 goto out; 17381 17382 /* Error in description of B-spline. */ 17383 17384 err112: 17385 *jstat = -112; 17386 s6err ("s1894", *jstat, kpos); 17387 goto out; 17388 17389 out: 17390 return; 17391 } 17392 17393 //=========================================================================== 17394 void s1896 (SISLSurf * osurf, double earray[], int dimp1, int narr, int ders1[], 17395 int dert1[], int ders2[], int dert2[], SISLSurf ** nsurf, int *jstat) 17396 //=========================================================================== 17397 { 17398 int nik1; /* Order of new surface in 17399 first parameter direction. */ 17400 int nin1; /* Order of new surface in 17401 second parameter direction. */ 17402 int nik2; /* Number of vertices in first 17403 parameter direction. */ 17404 int nin2; /* Number of vertices in second parameter direction. */ 17405 int lfs; /* Interval indicator. (left side) */ 17406 int lft; /* Interval indicator. (left side) */ 17407 int tpos; /* Used to index array tau. */ 17408 int epos; /* Used to index earray. */ 17409 int pos1; /* Position of values of first derivatives. */ 17410 int pos2; /* Position of values of second derivatives. */ 17411 int ds1; /* Order of derivatives. */ 17412 int dt1; 17413 int ds2; 17414 int dt2; 17415 int mds1; /* Maximum order of derivatives. */ 17416 int mdt1; 17417 int mds2; 17418 int mdt2; 17419 int nder1; /* Total order of derivatives. 17420 (Both directions) */ 17421 int nder2; 17422 int dim; /* Dimension of tau. */ 17423 int maxder; /* Largest total order of derivatives. 17424 (Both functions.) */ 17425 int count1; /* Loop control variables. */ 17426 int kj, ki; 17427 int kl, kr, kp; 17428 double parval[2]; 17429 double sum; /* Used for calculation of P(s,t). */ 17430 double *nknots1 = SISL_NULL; /* New knots in first parameter direction. */ 17431 double *nknots2 = SISL_NULL; /* New knots in second parameter direction. */ 17432 double *coef1 = SISL_NULL; /* New coeficients */ 17433 double *coef2 = SISL_NULL; /* New coeficients */ 17434 double *par1 = SISL_NULL; /* Parameter values in first direction. */ 17435 double *par2 = SISL_NULL; /* Parameter values in second direction. */ 17436 int *der1 = SISL_NULL; /* Derivative indicators in first direction. */ 17437 int *der2 = SISL_NULL; /* Derivative indicators in second direction.*/ 17438 double *deriv = SISL_NULL; /* Derivatives returned by s1421. */ 17439 double *normal = SISL_NULL; /* Normal returned by s1421. (not used) */ 17440 double *val1 = SISL_NULL; /* Values extracted from deriv. */ 17441 double *val2 = SISL_NULL; /* Values extracted from deriv. */ 17442 double *tau = SISL_NULL; /* Interpolation points. */ 17443 int kstat = 0; 17444 int kpos = 0; 17445 17446 *jstat = 0; 17447 17448 /* Test if legal input. */ 17449 17450 if (osurf->ik1 <= 1 || osurf->in1 < osurf->ik1) 17451 goto err112; 17452 if (osurf->ik2 <= 1 || osurf->in2 < osurf->ik2) 17453 goto err112; 17454 17455 /* Find minimal and maximal order of derivatives */ 17456 17457 ds1 = mds1 = ders1[0]; 17458 dt1 = mdt1 = dert1[0]; 17459 ds2 = mds2 = ders2[0]; 17460 dt2 = mdt2 = dert2[0]; 17461 17462 for (count1 = 1; count1 < narr; count1++) 17463 { 17464 if (ds1 > ders1[count1]) ds1 = ders1[count1]; 17465 if (dt1 > dert1[count1]) dt1 = dert1[count1]; 17466 if (ds2 > ders2[count1]) ds2 = ders2[count1]; 17467 if (dt2 > dert2[count1]) dt2 = dert2[count1]; 17468 17469 if (mds1 < ders1[count1]) mds1 = ders1[count1]; 17470 if (mdt1 < dert1[count1]) mdt1 = dert1[count1]; 17471 if (mds2 < ders2[count1]) mds2 = ders2[count1]; 17472 if (mdt2 < dert2[count1]) mdt2 = dert2[count1]; 17473 } 17474 17475 /* Produce a knot vector in the first parameter direction. */ 17476 17477 s1894 (osurf->et1, osurf->ik1, osurf->in1, ds1, ds2, earray, dimp1, narr, 17478 &nknots1, &nik1, &nin1, &kstat); 17479 if (kstat < 0) goto error; 17480 17481 /* Produce a knot vector in second parameter direction. */ 17482 17483 s1894 (osurf->et2, osurf->ik2, osurf->in2, dt1, dt2, earray, dimp1, narr, 17484 &nknots2, &nik2, &nin2, &kstat); 17485 if (kstat < 0) goto error; 17486 17487 /* Produce parameter values and derivative indicators in first 17488 * parameter direction. */ 17489 17490 s1890 (nknots1, nik1, nin1, &par1, &der1, &kstat); 17491 if (kstat < 0) goto error; 17492 17493 /* Produce parameter values and derivative indicators in second 17494 * parameter direction. */ 17495 17496 s1890 (nknots2, nik2, nin2, &par2, &der2, &kstat); 17497 if (kstat < 0) goto error; 17498 17499 /* Allocate memory for point calculation. */ 17500 17501 val1 = newarray (dimp1, DOUBLE); 17502 if (val1 == SISL_NULL) goto err101; 17503 val2 = newarray (dimp1, DOUBLE); 17504 if (val2 == SISL_NULL) goto err101; 17505 tau = newarray (narr * nin1 * nin2, DOUBLE); 17506 if (tau == SISL_NULL) goto err101; 17507 maxder = max (max (mds1, mds2), max (mdt1, mdt2)); 17508 deriv = newarray (osurf->idim * (maxder + 1) * (maxder + 2) / 2, DOUBLE); 17509 if (deriv == SISL_NULL) goto err101; 17510 normal = newarray (osurf->idim * (maxder + 1) * (maxder + 2) / 2, DOUBLE); 17511 if (normal == SISL_NULL) goto err101; 17512 17513 /* Calculate interpolation points. */ 17514 17515 lfs = 0; 17516 lft = 0; 17517 tpos = 0; 17518 for (kj = 0; kj < nin2; kj++) 17519 { 17520 parval[1] = par2[kj]; 17521 for (ki = 0; ki < nin1; ki++) 17522 { 17523 parval[0] = par1[ki]; 17524 epos = 0; 17525 for (kl = 0; kl < narr; kl++) 17526 { 17527 ds1 = ders1[kl]; 17528 dt1 = dert1[kl]; 17529 ds2 = ders2[kl]; 17530 dt2 = dert2[kl]; 17531 17532 /* ds2 = dert2[kl]; 17533 dt2 = ders2[kl]; */ 17534 17535 maxder = max (max (ds1, ds2), max (dt1, dt2)); 17536 17537 s1421 (osurf, maxder, parval, &lfs, &lft, deriv, normal, &kstat); 17538 if (kstat < 0) goto error; 17539 17540 nder1 = ds1 + dt1; 17541 nder2 = ds2 + dt2; 17542 pos1 = osurf->idim * (nder1 * (nder1 + 1) / 2 + dt1); 17543 pos2 = osurf->idim * (nder2 * (nder2 + 1) / 2 + dt2); 17544 17545 for (count1 = 0; count1 < osurf->idim; count1++) 17546 { 17547 val1[count1] = deriv[pos1++]; 17548 val2[count1] = deriv[pos2++]; 17549 } 17550 if (osurf->idim < dimp1) 17551 { 17552 val1[osurf->idim] = (double) 1.0; 17553 val2[osurf->idim] = (double) 1.0; 17554 if (ds1 > 0 || dt1 > 0) 17555 val1[osurf->idim] = (double) 0.0; 17556 if (ds2 > 0 || dt2 > 0) 17557 val2[osurf->idim] = (double) 0.0; 17558 } 17559 17560 /* Can now calculate a interpolation point. */ 17561 17562 sum = (double) 0.0; 17563 for (kr = 0; kr < dimp1; kr++, epos += dimp1) 17564 { 17565 for (kp = 0; kp < dimp1; kp++) 17566 sum += earray[epos + kp] * val1[kr] * val2[kp]; 17567 /* sum += earray[epos + kp] * val1[kp] * val2[kr]; */ 17568 } 17569 tau[tpos++] = sum; 17570 } 17571 } 17572 } 17573 17574 /* Calculate new surface description. */ 17575 17576 /* Interpolate in second parameter direction. */ 17577 17578 dim = narr * nin1; 17579 17580 s1891 (par2, tau, dim, nin2, 1, der2, TRUE, nknots2, &coef1, &nin2, 17581 nik2, 0, 0, &kstat); 17582 if (kstat < 0) goto error; 17583 17584 /* Interpolate in first parameter direction. */ 17585 17586 s1891 (par1, coef1, narr, nin1, nin2, der1, TRUE, nknots1, &coef2, 17587 &nin1, nik1, 0, 0, &kstat); 17588 if (kstat < 0) goto error; 17589 17590 /* OK */ 17591 17592 *nsurf = newSurf (nin1, nin2, nik1, nik2, nknots1, nknots2, 17593 coef2, osurf->ikind, narr, 2); 17594 if (*nsurf == SISL_NULL) goto err171; 17595 17596 goto out; 17597 17598 /* Not enough memory. */ 17599 17600 err101: 17601 *jstat = -101; 17602 s6err ("s1896", *jstat, kpos); 17603 goto out; 17604 17605 /* Could not create surface, */ 17606 17607 err171: 17608 *jstat = -171; 17609 s6err ("s1896", *jstat, kpos); 17610 goto out; 17611 17612 /* Error in description of B-spline. */ 17613 17614 err112: 17615 *jstat = -112; 17616 s6err ("s1896", *jstat, kpos); 17617 goto out; 17618 17619 /* Error in lower level routine. */ 17620 17621 error: 17622 *jstat = kstat; 17623 s6err ("s1896", *jstat, kpos); 17624 goto out; 17625 17626 /* Free pointers. */ 17627 17628 out: 17629 if (coef1 != SISL_NULL) freearray (coef1); 17630 if (val1 != SISL_NULL) freearray (val1); 17631 if (val2 != SISL_NULL) freearray (val2); 17632 if (par1 != SISL_NULL) freearray (par1); 17633 if (par2 != SISL_NULL) freearray (par2); 17634 if (der1 != SISL_NULL) freearray (der1); 17635 if (der2 != SISL_NULL) freearray (der2); 17636 if (normal != SISL_NULL) freearray (normal); 17637 if (deriv != SISL_NULL) freearray (deriv); 17638 if (tau != SISL_NULL) freearray (tau); 17639 17640 return; 17641 } 17642 17643 //=========================================================================== 17644 void s1320 (SISLSurf * psurf, double earray[], int inarr, 17645 int ratflag, SISLSurf ** rsurf, int *jstat) 17646 //=========================================================================== 17647 { 17648 int kpos = 0; 17649 int kstat = 0; 17650 SISLSurf *ssurf = SISL_NULL; /* Temperary SISL-surface. */ 17651 int kdim; /* Number of dimesions in psurf */ 17652 int kdimp1; /* Dimension of earray should be kdim+1 */ 17653 int lder[3]; /* Derivative indicator array */ 17654 double *scoef = SISL_NULL; /* Vertices of psurf (scaled in the rational case) */ 17655 double *rscoef = SISL_NULL; /* pointer to vertices in the rational case */ 17656 int ikind; /* kind of surface */ 17657 double wmin, wmax; /* min. and max. weight values for rational surface */ 17658 double scale; /* factor used for scaling rational weights */ 17659 int i; /* loop variable */ 17660 double *sarray = SISL_NULL; /* Array for calculating denominator if used */ 17661 int knarr; /* Number of parallel arrays to use. */ 17662 int nkind; /* Kind of output surface (rsurf). */ 17663 SISLSurf *jsurf = SISL_NULL; /* Temporary SISLSurf. */ 17664 17665 *jstat = 0; 17666 17667 17668 /* Make local pointers. */ 17669 17670 kdim = psurf->idim; 17671 ikind = psurf->ikind; 17672 17673 /* Set dimension of kdimp1. */ 17674 17675 kdimp1 = kdim + 1; 17676 17677 17678 /* Test input. */ 17679 17680 if (kdim < 1) 17681 goto err102; 17682 if (inarr < 1 || 3 < inarr) 17683 goto err172; 17684 17685 17686 /* rational surfaces is a special case. */ 17687 17688 if (ikind == 2 || ikind == 4) 17689 { 17690 kdim++; 17691 /* scale the coeffs so that min. weight * max. weight = 1. */ 17692 17693 rscoef = psurf->rcoef; 17694 wmin = rscoef[kdim-1]; 17695 wmax = rscoef[kdim-1]; 17696 17697 for (i = kdim-1; i < psurf->in1 * psurf->in2 * kdim; i += kdim) 17698 { 17699 if (rscoef[i] < wmin) 17700 wmin = rscoef[i]; 17701 if (rscoef[i] > wmax) 17702 wmax = rscoef[i]; 17703 } 17704 17705 scale = (double) 1.0 / sqrt (wmin * wmax); 17706 scoef = newarray (psurf->in1 * psurf->in2 * kdim, DOUBLE); 17707 if (scoef == SISL_NULL) 17708 goto err101; 17709 17710 for (i = 0; i < psurf->in1 * psurf->in2 * kdim; i++) 17711 { 17712 scoef[i] = rscoef[i] * scale; 17713 } 17714 } 17715 else 17716 { 17717 scoef = psurf->ecoef; 17718 } 17719 17720 ssurf = newSurf (psurf->in1, psurf->in2, psurf->ik1, psurf->ik2, 17721 psurf->et1, psurf->et2, scoef, 1, kdim, 1); 17722 if (ssurf == SISL_NULL) 17723 goto err171; 17724 17725 if ((ikind == 2 || ikind == 4) && ratflag == 1) 17726 { 17727 /* Output surface will also be rational. */ 17728 17729 nkind = 2; 17730 17731 /* Add an extra parallel array to pick up the weights 17732 of the subsequent homogeneous vertices of rsurf. */ 17733 17734 knarr = inarr + 1; 17735 17736 sarray = new0array (kdimp1 * kdimp1 * knarr, DOUBLE); 17737 if (sarray == SISL_NULL) 17738 goto err101; 17739 17740 memcopy (sarray, earray, kdimp1 * kdimp1 * inarr, double); 17741 17742 sarray[kdimp1 * kdimp1 * knarr - 1] = (double) 1.0; 17743 } 17744 else 17745 { 17746 nkind = 1; 17747 knarr = inarr; 17748 sarray = earray; 17749 } 17750 17751 lder[0] = 0; 17752 lder[1] = 0; 17753 lder[2] = 0; 17754 17755 /* Put surface into implicit surface */ 17756 17757 s1896 (ssurf, sarray, kdimp1, knarr, lder, lder, lder, lder, &jsurf, &kstat); 17758 if (kstat < 0) 17759 goto error; 17760 17761 if ((ikind == 2 || ikind == 4) && ratflag == 1) 17762 { 17763 /* Output from s1896 is a dim+1 non-rational surface jsurf. */ 17764 /* Convert homogeneous jsurf to rational rsurf. */ 17765 17766 *rsurf = newSurf(jsurf->in1,jsurf->in2, 17767 jsurf->ik1,jsurf->ik2, 17768 jsurf->et1,jsurf->et2, 17769 jsurf->ecoef, 17770 2,jsurf->idim-1,1); 17771 freeSurf(jsurf); 17772 } 17773 else 17774 { 17775 *rsurf = jsurf; 17776 } 17777 17778 if (ikind == 2 || ikind == 4) 17779 { 17780 if (scoef) 17781 freearray (scoef); 17782 if (ratflag) 17783 freearray (sarray); 17784 } 17785 17786 /* Ok. */ 17787 17788 goto out; 17789 17790 17791 /* Error in lower level function */ 17792 17793 error: 17794 *jstat = kstat; 17795 s6err ("s1320", *jstat, kpos); 17796 goto out; 17797 17798 /* allocation problems. */ 17799 err101: 17800 *jstat = -101; 17801 s6err ("s1320", *jstat, kpos); 17802 goto out; 17803 17804 /* Dimension less than 1 */ 17805 17806 err102: 17807 *jstat = -102; 17808 s6err ("s1320", *jstat, kpos); 17809 goto out; 17810 17811 /* Could not create surface. */ 17812 17813 err171: 17814 *jstat = -171; 17815 s6err ("s1320", *jstat, kpos); 17816 goto out; 17817 17818 /* Dimension inarr not equal to 1,2 or 3 */ 17819 17820 err172: 17821 *jstat = -172; 17822 s6err ("s1320", *jstat, kpos); 17823 goto out; 17824 17825 out: 17826 if (ssurf) 17827 freeSurf (ssurf); 17828 return; 17829 } 17830 17831 17832 //=========================================================================== 17833 void s1322(double epoint[],double edirec[],double aradiu,int idim, 17834 int inumb,double carray[],int *jstat) 17835 //=========================================================================== 17836 { 17837 int kdimp1; /* Dimension of matrix kdimp1 = idim + 1 */ 17838 int kdimp2; /* idim + 2 */ 17839 int kstop; /* Stop condition for for loop */ 17840 int ki,kj,kl; /* Running variables in loop */ 17841 int kpos=0; /* Position of error */ 17842 double twx,twy,twz; /* Local version of normalized direction vector */ 17843 double tx0,ty0,tz0; /* Local version of point on axis */ 17844 double temp; /* Temporary storage variable */ 17845 double tsum; /* Varaible used for summation */ 17846 double sdirec[3]; /* Normalized direction vector */ 17847 17848 17849 /* Test i legal input */ 17850 if (inumb <1 ) inumb = 1; 17851 if (idim != 3 ) goto err104; 17852 17853 kdimp1 = idim + 1; 17854 kdimp2 = idim + 2; 17855 kstop = kdimp1*kdimp1; 17856 17857 for (ki=0;ki<kstop;ki++) 17858 { 17859 carray[ki] = DZERO; 17860 } 17861 17862 /* Normalize direction vector */ 17863 17864 tsum = DZERO; 17865 17866 for (ki=0;ki<idim;ki++) 17867 { 17868 temp = edirec[ki]; 17869 tsum += (temp*temp); 17870 } 17871 17872 tsum = sqrt(tsum); 17873 if (DEQUAL(tsum,DZERO)) goto err173; 17874 17875 for (ki=0;ki<idim;ki++) 17876 { 17877 sdirec[ki] = edirec[ki]/tsum; 17878 } 17879 17880 /* Make diagonal elements */ 17881 17882 for (ki=0,kl=0 ; ki<kstop-1 ; kl++,ki+=kdimp2) /* (PFU 14/11-1994) */ 17883 { 17884 temp = sdirec[kl]; 17885 carray[ki] = (double)1.0 - temp*temp; 17886 } 17887 carray[ki] = (double) 1.0; /* (PFU 14/11-1994) */ 17888 17889 /* Make element 1,...,idim of last row and 1,...,idim of last column */ 17890 17891 tsum = DZERO; 17892 twx = sdirec[0]; 17893 twy = sdirec[1]; 17894 twz = sdirec[2]; 17895 tx0 = epoint[0]; 17896 ty0 = epoint[1]; 17897 tz0 = epoint[2]; 17898 17899 /* Make element (1,4) and (4,1) */ 17900 17901 temp = tx0*(twx*twx-(double)1.0) + twx*(ty0*twy+tz0*twz); 17902 17903 carray[3] = temp; 17904 carray[12] = temp; 17905 17906 /* Make element (2,4) and (4,2) */ 17907 17908 temp = ty0*(twy*twy-(double)1.0) + twy*(tz0*twz+tx0*twx); 17909 17910 carray[7] = temp; 17911 carray[13] = temp; 17912 17913 /* Make element (3,4) amd (4,3) */ 17914 17915 temp = tz0*(twz*twz-(double)1.0) + twz*(tx0*twx+ty0*twy); 17916 17917 carray[11] = temp; 17918 carray[14] = temp; 17919 17920 /* Make element (4,4) */ 17921 17922 temp = tx0*tx0*((double)1.0-twx*twx) + ty0*ty0*((double)1.0-twy*twy) 17923 + tz0*tz0*((double)1.0-twz*twz) - (double)2.0*tx0*ty0*twx*twy 17924 - (double)2.0*ty0*tz0*twy*twz - (double)2.0*tz0*tx0*twz*twx 17925 - aradiu*aradiu; 17926 17927 carray[15] = temp; 17928 17929 /* Make element (1,2) and (2,1) */ 17930 17931 temp = -twx*twy; 17932 carray[1] = temp; 17933 carray[4] = temp; 17934 17935 /* Make element (1,3) and (3,1) */ 17936 17937 temp = -twx*twz; 17938 carray[2] = temp; 17939 carray[8] = temp; 17940 17941 /* Make element (2,3) and (3,2) */ 17942 temp = -twy*twz; 17943 carray[6] = temp; 17944 carray[9] = temp; 17945 17946 /* Make extra copies of cylinder */ 17947 17948 kj = kstop; 17949 for (ki=1;ki<inumb;ki++) 17950 { 17951 for (kl=0;kl<kstop;kl++,kj++) 17952 { 17953 carray[kj] = carray[kl]; 17954 } 17955 } 17956 17957 *jstat = 0; 17958 goto out; 17959 17960 /* Dimension less than 1 */ 17961 err104: *jstat = -104; 17962 s6err("s1322",*jstat,kpos); 17963 goto out; 17964 17965 /* Direction vector of length 0 */ 17966 err173: *jstat = -173; 17967 s6err("s1322",*jstat,kpos); 17968 goto out; 17969 out: 17970 return; 17971 } 17972 17973 17974 //=========================================================================== 17975 void s1321(double ecentr[],double aradiu,int idim,int inumb, double carray[],int *jstat) 17976 //=========================================================================== 17977 { 17978 int kdimp1; /* Dimension of matrix kdimp1 = idim + 1 */ 17979 int kdimp2; /* idim + 2 */ 17980 int kstop; /* Stop condition for for loop */ 17981 int ki,kj,kl; /* Running variables in loop */ 17982 int kpos=0; /* Position of error */ 17983 double temp; /* Temporary storage variable */ 17984 double tsum; /* Varaible used for summation */ 17985 17986 17987 17988 /* Test i legal input */ 17989 if (inumb <1 ) inumb = 1; 17990 if (idim < 1 ) goto err102; 17991 17992 kdimp1 = idim + 1; 17993 kdimp2 = idim + 2; 17994 kstop = kdimp1*kdimp1; 17995 17996 for (ki=0;ki<kstop;ki++) 17997 { 17998 carray[ki] = (double)0.0; 17999 } 18000 18001 /* Make diagonal elements */ 18002 18003 for (ki=0;ki<kstop;ki+=kdimp2) 18004 { 18005 carray[ki] = (double)1.0; 18006 } 18007 18008 /* Make element 1,...,idim of last column and element 1,...,idim of last 18009 * row */ 18010 18011 tsum = (double)0.0; 18012 for (kl=0,ki=idim,kj=idim*kdimp1;kl<idim;kl++,kj++,ki+=kdimp1) 18013 { 18014 temp = -ecentr[kl]; 18015 carray[ki] = temp; 18016 carray[kj] = temp; 18017 tsum +=(temp*temp); 18018 } 18019 18020 /* Make lower right corner element */ 18021 18022 carray[kstop-1] = tsum - aradiu*aradiu; 18023 18024 /* Make extra copies of hyper sphere */ 18025 18026 kj = kstop; 18027 for (ki=1;ki<inumb;ki++) 18028 { 18029 for (kl=0;kl<kstop;kl++,kj++) 18030 { 18031 carray[kj] = carray[kl]; 18032 } 18033 } 18034 18035 *jstat = 0; 18036 goto out; 18037 18038 /* Dimension less than 1 */ 18039 err102: *jstat = -102; 18040 s6err("s1321",*jstat,kpos); 18041 goto out; 18042 out: 18043 return; 18044 } 18045 18046 18047 //=========================================================================== 18048 void sh6splitgeom_s9circle(double apt1[], double apt2[], double apt3[], 18049 double aepsge, double ecentre[], double eaxis[], 18050 double *crad, int *jstat) 18051 //=========================================================================== 18052 { 18053 int kstat = 0; 18054 int ki; 18055 int kdim = 3; 18056 int lpiv[3]; 18057 double snorm2[3]; 18058 double smid1[3]; 18059 double smid2[3]; 18060 double sdiff1[3]; 18061 double sdiff2[3]; 18062 double smat[9]; 18063 double sright[3]; 18064 18065 /* Compute difference vectors between the 1. and 2. and 2. and 3. point. */ 18066 18067 s6diff(apt1, apt2, kdim, sdiff1); 18068 s6diff(apt3, apt2, kdim, sdiff2); 18069 18070 /* Compute the normal of the plane in which the circle lies. */ 18071 18072 s6crss(sdiff1, sdiff2, snorm2); 18073 18074 /* Compute the normals to the planes normal to the first plane and 18075 perpendicular to the difference vectors. */ 18076 18077 /* s6crss(sdiff1, snorm2, snorm1); 18078 s6crss(sdiff2, snorm2, snorm3); */ 18079 18080 /* Check normals. */ 18081 18082 if (s6norm(snorm2, kdim, snorm2, &kstat) < aepsge) goto warn1; 18083 18084 /* Compute the midpoints of the difference vectors. */ 18085 18086 for (ki=0; ki<kdim; ki++) 18087 { 18088 smid1[ki] = (double)0.5*(apt1[ki] + apt2[ki]); 18089 smid2[ki] = (double)0.5*(apt2[ki] + apt3[ki]); 18090 } 18091 18092 /* Set up equation system. */ 18093 18094 memcopy(smat, snorm2, kdim, DOUBLE); 18095 memcopy(smat+kdim, sdiff1, kdim, DOUBLE); 18096 memcopy(smat+2*kdim, sdiff2, kdim, DOUBLE); 18097 18098 sright[0] = s6scpr(apt2, snorm2, kdim); 18099 sright[1] = s6scpr(smid1, sdiff1, kdim); 18100 sright[2] = s6scpr(smid2, sdiff2, kdim); 18101 18102 /* Solve equation system. */ 18103 18104 s6lufacp(smat, lpiv, 3, &kstat); 18105 if (kstat < 0) goto error; 18106 18107 s6lusolp(smat, sright, lpiv, 3, &kstat); 18108 if (kstat < 0) goto error; 18109 18110 /* Prepare output. */ 18111 18112 memcopy(eaxis, snorm2, kdim, DOUBLE); 18113 memcopy(ecentre, sright, kdim, DOUBLE); 18114 *crad = s6dist(ecentre, apt2, kdim); 18115 18116 *jstat = 0; 18117 goto out; 18118 18119 /* Almost singular equation system. */ 18120 18121 warn1 : 18122 *jstat = 1; 18123 goto out; 18124 18125 /* Error in lower level routine. */ 18126 18127 error : 18128 *jstat = kstat; 18129 goto out; 18130 18131 out : 18132 return; 18133 } 18134 18135 18136 //=========================================================================== 18137 void sh6splitgeom (SISLSurf *ps1, SISLSurf *ps2, double aepsge, double ecentre[], 18138 double eaxis[], double *cdist, double *crad, int *jstat) 18139 //=========================================================================== 18140 { 18141 int kstat = 0; /* Status variable. */ 18142 int ki,kj,k1,k2; /* Counters. */ 18143 int kleft1=0, kleft2=0; /* Parameters to surface evaluator. */ 18144 int kder=0; /* Evaluate only position. */ 18145 int kdim=ps1->idim; /* Dimension of geometry space. */ 18146 double tpi6=PI/(double)6; 18147 double tsign; /* Sign of vector. */ 18148 double tdot; /* Scalar product. */ 18149 double tang; /* Angle between vectors. */ 18150 double trad1, trad2; /* Curvature radius. */ 18151 double tmaxrad; /* Maximum radius of sphere/torus/cylinder. */ 18152 double tminfac = (double)0.9; /* Minimum factor between radiuses 18153 for a sphere. */ 18154 double spar1[2],spar2[2]; /* Paramater value in which to evaluate 18155 surfaces. */ 18156 double sder1[18]; /* Value of 1. surface. */ 18157 double snorm1[3]; /* Normal of 1. surface. */ 18158 double sder2[18]; /* Value of 2. surface. */ 18159 double snorm2[3]; /* Normal of 2. surface. */ 18160 double scentre1[3]; /* Centre of first circle. */ 18161 double scentre2[3]; /* Centre of second circle. */ 18162 double svec[3]; /* Vector used to find midpoint of 18163 splitting geometry. */ 18164 double sdiff[3]; /* Difference vector between midpoints. */ 18165 double sparc1[10]; /* Corner parameters of first surface. */ 18166 double sparc2[10]; /* Parameters of closest points on second surface. */ 18167 double scorn1[15]; /* Corners of first surface. */ 18168 double scorn2[15]; /* Closest points in the other surface. */ 18169 SISLPoint *qp = SISL_NULL; /* Representing a surface corner as a point. */ 18170 double start2[2]; /* Start parameters of second surface. */ 18171 double send2[2]; /* End parameters of second surface. */ 18172 double sdist[4]; /* Distance between closest points. */ 18173 18174 /* Test if the cones of the surfaces is less than pi, otherwise 18175 no attempt to find splitting geometry is made. */ 18176 18177 if (ps1->pdir->igtpi != 0 || ps2->pdir->igtpi != 0) 18178 { 18179 *jstat = 0; 18180 goto out; 18181 } 18182 18183 /* if (ps1->pdir->aang > tpi4 || ps2->pdir->aang > tpi4) 18184 { 18185 *jstat = 0; 18186 goto out; 18187 } */ 18188 18189 /* Make sure that the cones lies in the same area, otherwise 18190 return. */ 18191 18192 tdot = s6scpr(ps1->pdir->ecoef,ps2->pdir->ecoef,kdim); 18193 tsign = (tdot >= DZERO) ? (double)1.0 : -(double)1.0; 18194 18195 tang = s6ang(ps1->pdir->ecoef,ps2->pdir->ecoef,kdim); 18196 if (tang > tpi6) 18197 { 18198 *jstat = 0; 18199 goto out; 18200 } 18201 18202 /* Check that the surfaces is not too large, i.e. contain to many 18203 vertices to be put into a sphere- or cylinder equation effectively. */ 18204 18205 if (ps1->in1 > 2*ps1->ik1 || ps1->in2 > 2*ps1->ik2 || 18206 ps2->in1 > 2*ps2->ik1 || ps2->in2 > 2*ps2->ik2) 18207 { 18208 *jstat = 0; 18209 goto out; 18210 } 18211 18212 /* Compute the midvector between the axises of the surface cones. */ 18213 18214 for (ki=0; ki<kdim; ki++) 18215 svec[ki] = (double)0.5*(tsign*ps1->pdir->ecoef[ki] + ps2->pdir->ecoef[ki]); 18216 (void)s6norm(svec,kdim,svec,&kstat); 18217 if (!kstat) 18218 { 18219 *jstat = 0; 18220 goto out; 18221 } 18222 18223 /* Set maximum radius. */ 18224 18225 tmaxrad = ps1->pbox->e2max[2][0] - ps1->pbox->e2min[2][0]; 18226 tmaxrad = MAX(tmaxrad, ps1->pbox->e2max[2][1]-ps1->pbox->e2min[2][1]); 18227 tmaxrad = MAX(tmaxrad, ps1->pbox->e2max[2][2]-ps1->pbox->e2min[2][2]); 18228 tmaxrad *= (double)10.0; 18229 18230 /* Set parameter bourders of second surface. */ 18231 18232 start2[0] = *(ps2->et1 + ps2->ik1 - 1); 18233 start2[1] = *(ps2->et2 + ps2->ik2 - 1); 18234 send2[0] = *(ps2->et1 + ps2->in1); 18235 send2[1] = *(ps2->et2 + ps2->in2); 18236 18237 /* Evaluate the surfaces in their midpoints up to 2. order 18238 derivatives. */ 18239 18240 spar1[0] = (double)0.5*(ps1->et1[ps1->ik1-1] + ps1->et1[ps1->in1]); 18241 spar1[1] = (double)0.5*(ps1->et2[ps1->ik2-1] + ps1->et2[ps1->in2]); 18242 18243 s1421(ps1,kder,spar1,&kleft1,&kleft2,sder1,snorm1,&kstat); 18244 if (kstat < 0) goto error; 18245 18246 spar2[0] = (double)0.5*(ps2->et1[ps2->ik1-1] + ps2->et1[ps2->in1]); 18247 spar2[1] = (double)0.5*(ps2->et2[ps2->ik2-1] + ps2->et2[ps2->in2]); 18248 18249 s1421(ps2,kder,spar2,&kleft1,&kleft2,sder2,snorm2,&kstat); 18250 if (kstat < 0) goto error; 18251 18252 /* Check if the difference vector between the midpoints point in 18253 about the same direction as the vector svec. */ 18254 18255 s6diff(sder1, sder2, kdim, sdiff); 18256 tang = s6ang(sdiff, svec, kdim); 18257 if (tang < tpi6 || tang > (double)5.0*tpi6) 18258 { 18259 /* Set up parameter values for evaluation of first surface in 18260 the midpoint and in the midpoints of each edge curve. */ 18261 18262 memcopy(sparc1, spar1, 2, DOUBLE); 18263 sparc1[3] = *(ps1->et2+ps1->ik2-1); 18264 sparc1[4] = *(ps1->et1+ps1->in1); 18265 sparc1[7] = *(ps1->et2+ps1->in2); 18266 sparc1[8] = *(ps1->et1+ps1->ik1-1); 18267 sparc1[2] = sparc1[6] = spar1[0]; 18268 sparc1[5] = sparc1[9] = spar1[1]; 18269 18270 for (ki=0; ki<5; ki++) 18271 { 18272 /* Evaluate point. */ 18273 18274 if (ki == 0) 18275 memcopy(scorn1, sder1, kdim, DOUBLE); 18276 else 18277 { 18278 s1421(ps1, 0, sparc1+2*ki, &kleft1, &kleft2, scorn1+ki*kdim, 18279 snorm1, &kstat); 18280 if (kstat < 0) goto error; 18281 } 18282 18283 /* Find the closest point in the other surface. First express 18284 the corner as a SISLPoint. */ 18285 18286 if ((qp = newPoint(scorn1+ki*kdim, kdim, 1)) == SISL_NULL) goto err101; 18287 s1773(qp, ps2, aepsge, start2, send2, spar2, sparc2+2*ki, &kstat); 18288 if (kstat < 0) goto error; 18289 18290 /* Evaluate surface. */ 18291 18292 s1421(ps2, 0, sparc2+2*ki, &kleft1, &kleft2, scorn2+ki*kdim, 18293 snorm2, &kstat); 18294 if (kstat < 0) goto error; 18295 18296 /* Compute midpoint. */ 18297 18298 for (kj=0; kj<kdim; kj++) 18299 scorn1[ki*kdim+kj] = (double)0.5*(scorn1[ki*kdim+kj] + scorn2[ki*kdim+kj]); 18300 18301 if (qp != SISL_NULL) freePoint(qp); qp = SISL_NULL; 18302 } 18303 18304 /* Estimate circles. */ 18305 18306 sh6splitgeom_s9circle(scorn1+kdim, scorn1, scorn1+3*kdim, 18307 aepsge, scentre1, snorm1, &trad1, &kstat); 18308 if (kstat < 0) goto error; 18309 if (kstat > 0) 18310 *jstat = 1; /* Find plane. */ 18311 18312 sh6splitgeom_s9circle(scorn1+4*kdim, scorn1, scorn1+2*kdim, 18313 aepsge, scentre2, snorm2, &trad2, &kstat); 18314 if (kstat < 0) goto error; 18315 if (kstat > 0) 18316 *jstat = 1; /* Find plane. */ 18317 18318 /* Find kind of splitting geometry. */ 18319 18320 if (*jstat == 1 || (trad1 > tmaxrad && trad2 > tmaxrad)) 18321 { 18322 /* Set plane geometry. */ 18323 18324 *jstat = 1; 18325 memcopy(ecentre, scorn1, kdim, DOUBLE); 18326 s6diff(scorn1+2*kdim, scorn1, kdim, scorn1+2*kdim); 18327 s6diff(scorn1+3*kdim, scorn1, kdim, scorn1+3*kdim); 18328 s6crss(scorn1+2*kdim, scorn1+3*kdim, eaxis); 18329 } 18330 else if (MAX(trad1,trad2) > tmaxrad) 18331 { 18332 /* Set cylinder geometry. */ 18333 18334 *jstat = 3; 18335 *crad = MIN(trad1, trad2); 18336 if (trad1 < trad2) 18337 { 18338 memcopy(ecentre, scentre1, kdim, DOUBLE); 18339 memcopy(eaxis, snorm1, kdim, DOUBLE); 18340 } 18341 else 18342 { 18343 memcopy(ecentre, scentre2, kdim, DOUBLE); 18344 memcopy(eaxis, snorm2, kdim, DOUBLE); 18345 } 18346 } 18347 else if (MIN(trad1,trad2)/MAX(trad1,trad2) > tminfac) 18348 { 18349 /* Set sphere geometry. */ 18350 18351 *jstat = 2; 18352 *crad = (double)0.5*(trad1 + trad2); 18353 for (kj=0; kj<kdim; kj++) 18354 ecentre[kj] = (double)0.5*(scentre1[kj] + scentre2[kj]); 18355 } 18356 else if (MAX(trad1,trad2)/MIN(trad1,trad2) > (double)25.0) 18357 { 18358 /* Little chance of success in interception. */ 18359 18360 *jstat = 0; 18361 goto out; 18362 } 18363 else 18364 { 18365 /* Set torus geometry. */ 18366 18367 *jstat = 4; 18368 *crad = MIN(trad1, trad2); 18369 *cdist = MAX(trad1, trad2) - (*crad); 18370 *crad = MIN(trad1, trad2); 18371 if (trad1 < trad2) 18372 { 18373 memcopy(ecentre, scentre2, kdim, DOUBLE); 18374 memcopy(eaxis, snorm2, kdim, DOUBLE); 18375 } 18376 else 18377 { 18378 memcopy(ecentre, scentre1, kdim, DOUBLE); 18379 memcopy(eaxis, snorm1, kdim, DOUBLE); 18380 } 18381 18382 } 18383 } 18384 else if (tang > (double)2.0*tpi6 && tang < (double)4.0*tpi6) 18385 { 18386 /* Try to find a circle splitting the edge curves of the surfaces, 18387 and extend this circle to a cylinder. First find closest edgecurves 18388 by feching the corners of the first surface and finding the closest 18389 points in the other surface. */ 18390 18391 sparc1[6] = sparc1[0] = *(ps1->et1+ps1->ik1-1); 18392 sparc1[2] = sparc1[4] = *(ps1->et1+ps1->in1); 18393 sparc1[1] = sparc1[3] = *(ps1->et2+ps1->ik2-1); 18394 sparc1[5] = sparc1[7] = *(ps1->et2+ps1->in2); 18395 18396 for (ki=0; ki<4; ki++) 18397 { 18398 /* Evaluate corner. */ 18399 18400 s1421(ps1, 0, sparc1+2*ki, &kleft1, &kleft2, scorn1+ki*kdim, 18401 snorm1, &kstat); 18402 if (kstat < 0) goto error; 18403 18404 /* Find the closest point in the other surface. First express 18405 the corner as a SISLPoint. */ 18406 18407 if ((qp = newPoint(scorn1+ki*kdim, kdim, 1)) == SISL_NULL) goto err101; 18408 s1773(qp, ps2, aepsge, start2, send2, spar2, sparc2+2*ki, &kstat); 18409 if (kstat < 0) goto error; 18410 18411 /* Evaluate surface. */ 18412 18413 s1421(ps2, 0, sparc2+2*ki, &kleft1, &kleft2, scorn2+ki*kdim, 18414 snorm2, &kstat); 18415 if (kstat < 0) goto error; 18416 18417 /* Compute distance. */ 18418 18419 sdist[ki] = s6dist(scorn1+ki*kdim, scorn2+ki*kdim, kdim); 18420 18421 if (qp != SISL_NULL) freePoint(qp); qp = SISL_NULL; 18422 } 18423 18424 /* Check if the two closest points lies on a common edge. */ 18425 18426 if (sdist[0] < MIN(sdist[1],sdist[2]) && 18427 sdist[3] < MIN(sdist[1],sdist[2])) 18428 { 18429 k1 = 0; k2 = 3; 18430 } 18431 else if (sdist[1] < MIN(sdist[0],sdist[3]) && 18432 sdist[2] < MIN(sdist[0],sdist[3])) 18433 { 18434 k1 = 1; k2 = 2; 18435 } 18436 else if (sdist[0] < MIN(sdist[2],sdist[3]) && 18437 sdist[1] < MIN(sdist[2],sdist[3])) 18438 { 18439 k1 = 0; k2 = 1; 18440 } 18441 else if (sdist[2] < MIN(sdist[0],sdist[1]) && 18442 sdist[3] < MIN(sdist[0],sdist[1])) 18443 { 18444 k1 = 2; k2 = 3; 18445 } 18446 else 18447 { 18448 *jstat = 0; 18449 goto out; 18450 } 18451 18452 /* Compute closest point to the midpoint between the two closest 18453 corners. */ 18454 18455 sparc1[8] = (double)0.5*(sparc1[2*k1] + sparc1[2*k2]); 18456 sparc1[9] = (double)0.5*(sparc1[2*k1+1] + sparc1[2*k2+1]); 18457 18458 /* Evaluate point. */ 18459 18460 s1421(ps1, 0, sparc1+8, &kleft1, &kleft2, scorn1+4*kdim, 18461 snorm1, &kstat); 18462 if (kstat < 0) goto error; 18463 18464 /* Find the closest point in the other surface. First express 18465 the corner as a SISLPoint. */ 18466 18467 if ((qp = newPoint(scorn1+4*kdim, kdim, 1)) == SISL_NULL) goto err101; 18468 s1773(qp, ps2, aepsge, start2, send2, spar2, sparc2+8, &kstat); 18469 if (kstat < 0) goto error; 18470 18471 if (qp != SISL_NULL) freePoint(qp); qp = SISL_NULL; 18472 18473 /* Evaluate surface. */ 18474 18475 s1421(ps2, 0, sparc2+8, &kleft1, &kleft2, scorn2+4*kdim, 18476 snorm2, &kstat); 18477 if (kstat < 0) goto error; 18478 18479 /* Find middle points between the sets of closest points. */ 18480 18481 for (ki=0; ki<kdim; ki++) 18482 { 18483 scorn1[k1*kdim+ki] = (double)0.5*(scorn1[k1*kdim+ki] + scorn2[k1*kdim+ki]); 18484 scorn1[k2*kdim+ki] = (double)0.5*(scorn1[k2*kdim+ki] + scorn2[k2*kdim+ki]); 18485 scorn1[4*kdim+ki] = (double)0.5*(scorn1[4*kdim+ki] + scorn2[4*kdim+ki]); 18486 } 18487 18488 /* Compute splitting cylinder. */ 18489 18490 sh6splitgeom_s9circle(scorn1+k1*kdim, scorn1+4*kdim, scorn1+k2*kdim, 18491 aepsge, ecentre, eaxis, crad, &kstat); 18492 if (kstat < 0) goto error; 18493 if (kstat > 0 || *crad > tmaxrad) 18494 { 18495 /* Make plane. */ 18496 18497 *jstat = 1; 18498 memcopy(ecentre, scorn1+4*kdim, kdim, DOUBLE); 18499 s6diff(scorn1+k1*kdim, scorn1+4*kdim, kdim, scorn1+k1*kdim); 18500 s6diff(scorn1+k2*kdim, scorn1+4*kdim, kdim, scorn1+k2*kdim); 18501 s6crss(scorn1+k1*kdim, scorn1+k2*kdim, eaxis); 18502 } 18503 else 18504 18505 /* Output cylinder. */ 18506 18507 *jstat = 3; 18508 } 18509 else *jstat = 0; 18510 18511 goto out; 18512 18513 err101 : *jstat = -101; 18514 goto out; 18515 18516 error : *jstat = kstat; 18517 goto out; 18518 18519 out : 18520 return; 18521 } 18522 18523 //=========================================================================== 18524 void sh6findsplit (SISLSurf *ps1, SISLSurf *ps2, double aepsge, int *jstat) 18525 //=========================================================================== 18526 { 18527 int kstat = 0; /* Local status variable. */ 18528 int kdim = ps1->idim; /* Dimension of space. */ 18529 int ratflag = 0; /* Indicates if surface is rational. */ 18530 double tepsge; /* Local tolerance. */ 18531 double tdist; /* Large radius of torus. */ 18532 double trad; /* Radius of sphere, cylinder or torus. */ 18533 double scentre[3]; /* Centre of splitting geometry. */ 18534 double saxis[3]; /* Axis of splitting geometry. */ 18535 double simpli[16]; /* Array containing torus info. */ 18536 double splitgeom[16]; /* Matrix description of a sphere 18537 or cylinder. */ 18538 SISLSurf *qs1 = SISL_NULL; /* 1D surface. */ 18539 SISLSurf *qs2 = SISL_NULL; /* 1D surface. */ 18540 18541 /* Still overlap. Try to find splitting geometry object. */ 18542 18543 sh6splitgeom(ps1, ps2, aepsge, scentre, saxis, &tdist, 18544 &trad, &kstat); 18545 if (kstat < 0) goto error; 18546 18547 /* 18548 if (kstat == 0) nmb0++; 18549 else if (kstat == 1) nmb1++; 18550 else if (kstat == 2) nmb2++; 18551 else if (kstat == 3) nmb3++; 18552 else if (kstat == 4) nmb4++; 18553 */ 18554 18555 /* If kstat = 0 is returned, no splitting geometry is found, 18556 and no further interception is to be tried. */ 18557 18558 if (kstat > 0) 18559 { 18560 if (kstat == 1) 18561 { 18562 /* The splitting geometry is a plane. Set the two surfaces 18563 into the plane equation. */ 18564 18565 s1329 (ps1, scentre, saxis, kdim, &qs1, &kstat); 18566 if (kstat < 0) 18567 goto error; 18568 s1329 (ps2, scentre, saxis, kdim, &qs2, &kstat); 18569 if (kstat < 0) 18570 goto error; 18571 18572 18573 /* Set local tolerance. */ 18574 18575 tepsge = aepsge; 18576 } 18577 else if (kstat == 2 || kstat == 3) 18578 { 18579 if (kstat == 2) 18580 { 18581 /* The splitting geometry object is a sphere. 18582 Make a matrix of dimension (idim+1)x(idim+1) describing a hyper 18583 sphere as an implicit function. */ 18584 18585 s1321(scentre,trad,kdim,1,splitgeom,&kstat); 18586 if (kstat < 0) goto error; 18587 18588 } 18589 else if (kstat == 3) 18590 { 18591 /* The splitting geometry object is a cylinder. 18592 Make a matrix of dimension (idim+1)x(idim+1) describing a 18593 cylinder as an implicit function. */ 18594 18595 s1322(scentre,saxis,trad,kdim,1,splitgeom,&kstat); 18596 if (kstat < 0) goto error; 18597 } 18598 /* 18599 * Put the description of the surfaces into the implicit 18600 * equation for the sphere or cylinder. 18601 * ---------------------------------------------------------- 18602 */ 18603 18604 ratflag = (ps1->ikind == 2 || ps1->ikind == 4) ? 1 : 0; 18605 s1320(ps1,splitgeom,1,ratflag,&qs1,&kstat); 18606 if (kstat < 0) goto error; 18607 18608 ratflag = (ps2->ikind == 2 || ps2->ikind == 4) ? 1 : 0; 18609 s1320(ps2,splitgeom,1,ratflag,&qs2,&kstat); 18610 if (kstat < 0) goto error; 18611 18612 /* Set up local tolerance. */ 18613 18614 tepsge = (double)2.0*trad*aepsge; 18615 } 18616 else if (kstat == 4) 18617 { 18618 /* Set surfaces into torus equation. */ 18619 18620 /* 18621 * Put the information concerning the torus in the following sequence 18622 * into simpli: Center, normal, big radius, small radius 18623 * ------------------------------------------------------------------ 18624 */ 18625 18626 memcopy(simpli,scentre,3,DOUBLE); 18627 memcopy(simpli+3,saxis,3,DOUBLE); 18628 simpli[6] = tdist; 18629 simpli[7] = trad; 18630 18631 /* 18632 * Put surfaces into torus equation 18633 * ------------------------------- 18634 */ 18635 18636 s1378(ps1,simpli,1001,kdim,&qs1,&kstat); 18637 if (kstat<0) goto error; 18638 18639 s1378(ps2,simpli,1001,kdim,&qs2,&kstat); 18640 if (kstat<0) goto error; 18641 18642 /* Set up local tolerance. */ 18643 18644 tepsge = (double)8.0*aepsge*trad*tdist*tdist; 18645 } 18646 18647 18648 /* Make box of first 1D surface. */ 18649 18650 sh1992su(qs1,2,tepsge,&kstat); 18651 if (kstat < 0) goto error; 18652 18653 /* Make box of second 1D surface. */ 18654 18655 sh1992su(qs2,2,tepsge,&kstat); 18656 if (kstat < 0) goto error; 18657 18658 /* Check if the boxes overlap. */ 18659 18660 if (qs1->pbox->e2min[2][0] > qs2->pbox->e2max[2][0] || 18661 qs1->pbox->e2max[2][0] < qs2->pbox->e2min[2][0]) 18662 { 18663 /* 18664 nmbsuccess++; 18665 */ 18666 18667 /* No intersection is possible. */ 18668 18669 *jstat = 0; 18670 } 18671 else *jstat = 1; /* Mark possibility of intersection. */ 18672 } 18673 else *jstat = 1; /* Mark possibility of intersection. */ 18674 18675 goto out; 18676 18677 error : *jstat = kstat; 18678 goto out; 18679 18680 out: 18681 if (qs1) freeSurf(qs1); 18682 if (qs2) freeSurf(qs2); 18683 18684 return; 18685 } 18686 18687 18688 //=========================================================================== 18689 void sh1834_s9mat3d(double emat[],double edir1[],double edir2[]) 18690 //=========================================================================== 18691 { 18692 int kstat = 0; /* Local status variable. */ 18693 double snorm[3]; /* Cross-product of edir1 and edir2. */ 18694 double sdir[3]; /* Normalized vertion of edir1. */ 18695 double *s1; /* Pointer into emat array. */ 18696 double tleng1,tleng2; /* Length of snorm and edir1 respectively. */ 18697 double ta1,ta2,ta3,tb1,tb2,tb3,td1,td2,tl1,tl2,tl3; /* Help variables. */ 18698 18699 /* Calculate cross-product of edir1 and edir2. */ 18700 18701 s6crss(edir1,edir2,snorm); 18702 18703 /* Normalize snorm. */ 18704 18705 tleng1 = s6norm(snorm,3,snorm,&kstat); 18706 18707 /* Normalize edir1. */ 18708 18709 tleng2 = s6norm(edir1,3,sdir,&kstat); 18710 18711 /* Initialize help variables. */ 18712 18713 ta1 = snorm[0]; 18714 ta2 = snorm[1]; 18715 ta3 = snorm[2]; 18716 tl1 = sqrt(ta2*ta2+ta3*ta3); 18717 18718 /* Set up rotation matrix. */ 18719 18720 if ((DEQUAL(tleng1,DZERO) || DEQUAL(tl1,DZERO)) && DEQUAL(tleng2,DZERO)) 18721 18722 /* The rotation matrix is the identity matrix. */ 18723 18724 emat[0] = emat[4] = emat[8] = (double)1.0; 18725 else if (DEQUAL(tleng1,DZERO) || DEQUAL(tl1,DZERO)) 18726 { 18727 18728 /* The rotation matrix is supposed to rotate edir1 to be parallell 18729 to the x-axis. */ 18730 18731 tb1 = sdir[0]; 18732 tb2 = sdir[1]; 18733 tb3 = sdir[2]; 18734 tl3 = sqrt(tb1*tb1+tb2*tb2); 18735 18736 if (DEQUAL(tl3,DZERO)) emat[0] = emat[4] = emat[8] = (double)1.0; 18737 else 18738 { 18739 s1 = emat; 18740 *(s1++) = tb1; 18741 *(s1++) = tb2; 18742 *(s1++) = tb3; 18743 *(s1++) = -tb2/tl3; 18744 *(s1++) = tb1/tl3; 18745 *(s1++) = DZERO; 18746 *(s1++) = -tb1*tb3/tl3; 18747 *(s1++) = -tb2*tb3/tl3; 18748 *(s1++) = tl3; 18749 } 18750 } 18751 else 18752 { 18753 td1 = edir1[0]/tl1; 18754 td2 = (ta3*edir1[1] - ta2*edir1[2])/tl1; 18755 tl2 = sqrt(td1*td1+td2*td2); 18756 18757 if (DEQUAL(tl2,DZERO)) 18758 { 18759 18760 /* The normal snorm is rotated to be parallell to the z-axis. */ 18761 18762 s1 = emat; 18763 *(s1++) = tl1; 18764 *(s1++) = -ta1*ta2/tl1; 18765 *(s1++) = -ta1*ta3/tl1; 18766 *(s1++) = DZERO; 18767 *(s1++) = ta3/tl1; 18768 *(s1++) = -ta2/tl1; 18769 *(s1++) = ta1; 18770 *(s1++) = ta2; 18771 *(s1++) = ta3; 18772 } 18773 else 18774 { 18775 18776 /* The normal is rotated to be parallell to the z-axis and edir1 18777 to be parallell to the x-axis. */ 18778 18779 s1 = emat; 18780 *(s1++) = td1*tl1/tl2; 18781 *(s1++) = (-ta1*ta2*td1 + ta3*td2)/(tl1*tl2); 18782 *(s1++) = (-ta1*ta3*td1 - ta2*td2)/(tl1*tl2); 18783 *(s1++) = -td2*tl1/tl2; 18784 *(s1++) = (ta1*ta2*td2 + ta3*td1)/(tl1*tl2); 18785 *(s1++) = (ta1*ta3*td2 - ta2*td1)/(tl1*tl2); 18786 *(s1++) = ta1; 18787 *(s1++) = ta2; 18788 *(s1++) = ta3; 18789 } 18790 } 18791 } 18792 18793 18794 //=========================================================================== 18795 void sh1834_s9mat2d(double emat[],double edir[]) 18796 //=========================================================================== 18797 { 18798 int kstat = 0; /* Local status variable. */ 18799 double tlength; /* Length of vector edir. */ 18800 double sdir[2]; /* Normalized vertion of vector edir. */ 18801 18802 tlength = s6norm(edir,2,sdir,&kstat); 18803 if (kstat == 0) 18804 18805 /* Length of edir equal to zero. Let the rotation matrix be 18806 the identity matrix. */ 18807 18808 emat[0] = emat[3] = (double)1.0; 18809 else 18810 { 18811 18812 /* Make rotation matrix. */ 18813 18814 emat[0] = sdir[0]; 18815 emat[1] = sdir[1]; 18816 emat[2] = sdir[1]; 18817 emat[3] = -sdir[0]; 18818 } 18819 } 18820 18821 //=========================================================================== 18822 void sh1834(SISLObject *po1,SISLObject *po2,double aepsge,int idim, 18823 double edir1[],double edir2[],int *jstat) 18824 //=========================================================================== 18825 { 18826 int kstat = 0; /* Local status variable. */ 18827 int kpos = 0; /* Position of error. */ 18828 int kinnerexp = 12; /* Expand box in the inner. No rotation. */ 18829 int kn1=0,kn2=0; /* Number of coefficients of objects. */ 18830 double *sc1,*sc2;/* Pointers to coefficients of objects. */ 18831 double *scoef1=SISL_NULL; /* Rotated coefficients of first object. */ 18832 double *scoef2=SISL_NULL; /* Rotated coefficients of second object.*/ 18833 double *smat=SISL_NULL; /* Rotation matrix. */ 18834 double *s1,*s2,*s3,*s4,*s5; /* Pointers used to traverse arrays. */ 18835 SISLObject *qo1=SISL_NULL; /* First object after rotation. */ 18836 SISLObject *qo2=SISL_NULL; /* Second object after rotation. */ 18837 /* long time_before; 18838 long time_used=0; */ 18839 18840 double *rc1,*rc2; /* Pointers to homogeneous coefficients. */ 18841 double *rcoef1=SISL_NULL; /* Possibly homogeneous coefficients. */ 18842 double *rcoef2=SISL_NULL; /* Possibly homogeneous coefficients. */ 18843 int ikind1=0, ikind2=0; /* Kinds of objects 1 and 2. */ 18844 int i,i1,i2,j,k; /* Loop variables. */ 18845 18846 /* Test input. */ 18847 18848 if (idim != 2 && idim != 3) goto err105; 18849 18850 /* Fetch coefficients of the objects. */ 18851 18852 if (po1->iobj == SISLCURVE) 18853 { 18854 kn1 = po1->c1->in; 18855 sc1 = po1->c1->ecoef; 18856 rc1 = po1->c1->rcoef; 18857 ikind1 = po1->c1->ikind; 18858 } 18859 else if (po1->iobj == SISLSURFACE) 18860 { 18861 kn1 = po1->s1->in1*po1->s1->in2; 18862 sc1 = po1->s1->ecoef; 18863 rc1 = po1->s1->rcoef; 18864 ikind1 = po1->s1->ikind; 18865 } 18866 else 18867 { 18868 kn1 = 1; 18869 sc1 = po1->p1->ecoef; 18870 rc1 = SISL_NULL; 18871 ikind1 = 1; 18872 } 18873 18874 if (po2->iobj == SISLCURVE) 18875 { 18876 kn2 = po2->c1->in; 18877 sc2 = po2->c1->ecoef; 18878 rc2 = po2->c1->rcoef; 18879 ikind2 = po2->c1->ikind; 18880 } 18881 else if (po2->iobj == SISLSURFACE) 18882 { 18883 kn2 = po2->s1->in1*po2->s1->in2; 18884 sc2 = po2->s1->ecoef; 18885 rc2 = po2->s1->rcoef; 18886 ikind2 = po2->s1->ikind; 18887 } 18888 else 18889 { 18890 kn2 = 1; 18891 sc2 = po2->p1->ecoef; 18892 rc2 = SISL_NULL; 18893 ikind2 = 1; 18894 } 18895 18896 /* Allocate space for local parameters. */ 18897 18898 if ((scoef1 = newarray(idim*kn1,DOUBLE)) == SISL_NULL) goto err101; 18899 if ((scoef2 = newarray(idim*kn2,DOUBLE)) == SISL_NULL) goto err101; 18900 if ((smat = new0array(idim*idim,DOUBLE)) == SISL_NULL) goto err101; 18901 18902 /* Find the rotation matrix. */ 18903 18904 if (idim == 2) 18905 18906 /* After normalization edir1[0] will contain the cosine of the 18907 rotation angle and edir1[1] will contain the sine. */ 18908 18909 sh1834_s9mat2d(smat,edir1); 18910 else 18911 18912 /* Set up the rotation matrix when idim = 3. (edir1 x edir2) is 18913 rotated to be parallell to the z-axis and edir1 to be parallell 18914 to the x-axis. */ 18915 18916 sh1834_s9mat3d(smat,edir1,edir2); 18917 18918 /* The objects is moved into the new coordinate system by rotating 18919 them using the rotation matrix. */ 18920 18921 /* Rotate first object. */ 18922 18923 for (s2=sc1,s4=s2+idim*kn1,s5=scoef1; s2<s4; s2+=idim) 18924 for (s1=smat,s3=smat+idim*idim; s1<s3; s1+=idim,s5++) 18925 *s5 = s6scpr(s1,s2,idim); 18926 18927 /* Rotate second object. */ 18928 18929 for (s2=sc2,s4=s2+idim*kn2,s5=scoef2; s2<s4; s2+=idim) 18930 for (s1=smat,s3=smat+idim*idim; s1<s3; s1+=idim,s5++) 18931 *s5 = s6scpr(s1,s2,idim); 18932 18933 /* Make rotated objects. */ 18934 18935 if ((qo1 = newObject(po1->iobj)) == SISL_NULL) goto err101; 18936 if ((qo2 = newObject(po2->iobj)) == SISL_NULL) goto err101; 18937 18938 if(ikind1 == 2 || ikind1 == 4) 18939 { 18940 if ((rcoef1 = newarray((idim+1)*kn1,DOUBLE)) == SISL_NULL) goto err101; 18941 for(i=0,i1=0,i2=0; i<kn1; i++) 18942 { 18943 k = i1 + idim; 18944 for(j=0; j<idim; j++, i1++, i2++) 18945 { 18946 rcoef1[i1] = scoef1[i2] * rc1[k]; 18947 } 18948 rcoef1[i1] = rc1[k]; 18949 i1++; 18950 } 18951 } 18952 else 18953 { 18954 rcoef1 = scoef1; 18955 } 18956 18957 if(ikind2 == 2 || ikind2 == 4) 18958 { 18959 if ((rcoef2 = newarray((idim+1)*kn2,DOUBLE)) == SISL_NULL) goto err101; 18960 for(i=0,i1=0,i2=0; i<kn2; i++) 18961 { 18962 k = i1 + idim; 18963 for(j=0; j<idim; j++, i1++, i2++) 18964 { 18965 rcoef2[i1] = scoef2[i2] * rc2[k]; 18966 } 18967 rcoef2[i1] = rc2[k]; 18968 i1++; 18969 } 18970 } 18971 else 18972 { 18973 rcoef2 = scoef2; 18974 } 18975 18976 18977 if (po1->iobj == SISLCURVE) 18978 { 18979 if ((qo1->c1 = newCurve(po1->c1->in,po1->c1->ik,po1->c1->et, 18980 rcoef1,po1->c1->ikind,idim,0)) == SISL_NULL) 18981 goto err101; 18982 /* printf("Rotated box test. Curve - "); */ 18983 } 18984 else if (po1->iobj == SISLSURFACE) 18985 { 18986 if ((qo1->s1 = newSurf(po1->s1->in1,po1->s1->in2,po1->s1->ik1, 18987 po1->s1->ik2,po1->s1->et1,po1->s1->et2, 18988 rcoef1,po1->s1->ikind,idim,0)) == SISL_NULL) 18989 goto err101; 18990 /* printf("Rotated box test. Surface - "); */ 18991 18992 } 18993 else 18994 { 18995 if ((qo1->p1 = newPoint(rcoef1,idim,0)) == SISL_NULL) goto err101; 18996 } 18997 18998 if (po2->iobj == SISLCURVE) 18999 { 19000 if ((qo2->c1 = newCurve(po2->c1->in,po2->c1->ik,po2->c1->et, 19001 rcoef2,po2->c1->ikind,idim,0)) == SISL_NULL) 19002 goto err101; 19003 /* printf("curve. "); */ 19004 } 19005 else if (po2->iobj == SISLSURFACE) 19006 { 19007 if ((qo2->s1 = newSurf(po2->s1->in1,po2->s1->in2,po2->s1->ik1, 19008 po2->s1->ik2,po2->s1->et1,po2->s1->et2, 19009 rcoef2,po2->s1->ikind,idim,0)) == SISL_NULL) 19010 goto err101; 19011 /* printf("surface. "); */ 19012 } 19013 else 19014 { 19015 if ((qo2->p1 = newPoint(rcoef2,idim,0)) == SISL_NULL) goto err101; 19016 } 19017 19018 /* Make box test. */ 19019 19020 /* time_before = clock(); 19021 boxrot_nmb++; */ 19022 sh1790(qo1,qo2,kinnerexp,aepsge,&kstat); 19023 /* time_used = clock() - time_before; 19024 boxrot_time += time_used; */ 19025 if (kstat < 0) goto error; 19026 /* printf("Status = %d \n",kstat); */ 19027 19028 /* Box-test permformed. */ 19029 19030 *jstat = kstat; 19031 goto out; 19032 19033 /* Error in space allocation. */ 19034 19035 err101: *jstat = -101; 19036 s6err("sh1834",*jstat,kpos); 19037 goto out; 19038 19039 /* Error in input. Dimension not equal to 2 or 3. */ 19040 19041 err105: *jstat = -105; 19042 s6err("sh1834",*jstat,kpos); 19043 goto out; 19044 19045 /* Error in lower level routine. */ 19046 19047 error : *jstat = kstat; 19048 goto out; 19049 19050 out: 19051 19052 /* Free space occupied by local arrays and objects. */ 19053 19054 if (qo1 != SISL_NULL) freeObject(qo1); 19055 if (qo2 != SISL_NULL) freeObject(qo2); 19056 if (rcoef1 != SISL_NULL && rcoef1 != scoef1) freearray(rcoef1); 19057 if (rcoef2 != SISL_NULL && rcoef2 != scoef2) freearray(rcoef2); 19058 if (scoef1 != SISL_NULL) freearray(scoef1); 19059 if (scoef2 != SISL_NULL) freearray(scoef2); 19060 if (smat != SISL_NULL) free0array(smat); 19061 19062 return; 19063 } 19064 19065 19066 19067 //=========================================================================== 19068 void sh1839(SISLObject *po1,SISLObject *po2,double aepsge,int *jstat) 19069 //=========================================================================== 19070 { 19071 int kstat = 0; /* Local status variable. */ 19072 int kpos = 0; /* Position of error. */ 19073 int ki,kj; /* Counter. */ 19074 int kdim; /* Dimension of geometry space. */ 19075 int kn1,kn2; /* Number of vertices in each parameter 19076 direction of surface. */ 19077 int kk1,kk2; /* Order in each parameter direction of surface. */ 19078 int kvec; /* Number of direction vectors to calculate. */ 19079 int klap; /* Indcates whether SISLbox of surface overlap point.*/ 19080 double tang1,tang2; /* Angles between direction vectors. */ 19081 double *scoef; /* Vertices of surface. */ 19082 register double *s1,*s2, 19083 *s3,*s4; /* Pointers used to traverse arrays. */ 19084 double *sdir = SISL_NULL; /* Array containing direction vectors. */ 19085 19086 /* Test kind of first object. */ 19087 19088 if (po1->iobj != SISLSURFACE) goto err122; 19089 19090 /* Copy surface to local parameters. */ 19091 19092 kdim = po1 -> s1 -> idim; 19093 kn1 = po1 -> s1 -> in1; 19094 kn2 = po1 -> s1 -> in2; 19095 kk1 = po1 -> s1 -> ik1; 19096 kk2 = po1 -> s1 -> ik2; 19097 scoef = po1 -> s1 -> ecoef; 19098 19099 /* Find number of rotations to make. */ 19100 19101 if (kk1 > 2 || kk2 > 2) kvec = 10; else kvec = 2; 19102 19103 /* Allocate space for vectors with which the x-axis is to be parallell. */ 19104 19105 sdir = newarray(kvec*kdim,double); 19106 if (sdir == SISL_NULL) goto err101; 19107 19108 if (kvec == 2) 19109 { 19110 /* Make diagonal from lower left to upper right corner of patch. 19111 s1 points to the array which contains the results, s3 points to the 19112 lower left corner and s4 to the upper right corner. */ 19113 19114 for (s1=sdir,s2=s1+kdim,s3=scoef,s4=scoef+kdim*(kn1*kn2-1); s1<s2; 19115 s1++,s3++,s4++) 19116 *s1 = *s4 - *s3; 19117 19118 /* Make diagonal from upper left to lower right corner of patch. s1 19119 points to the array which contains the results, s3 points to the 19120 upper left and s4 to the lower right corner. */ 19121 19122 for (s1=sdir+kdim,s2=s1+kdim,s3=scoef+kdim*kn1*(kn2-1), 19123 s4=scoef+kdim*(kn1-1); s1<s2; s1++,s3++,s4++) 19124 *s1 = *s4 - *s3; 19125 } 19126 19127 if (kvec > 2) 19128 { 19129 19130 /* The surface is not linear in both parameter directions. Make 19131 horizontal and vertical tangent in lower left corner. s1 points 19132 to the array which contain the results and s3 to the corner. */ 19133 19134 for (s1=sdir+2*kdim,s2=s1+kdim,s3=scoef; s1<s2; s1++,s3++) 19135 { 19136 *s1 = *(s3+kdim) - *s3; 19137 *(s1+kdim) = *(s3+kdim*kn1) - *s3; 19138 } 19139 19140 /* Make the horizontal and vertical tangent in lower right corner. s1 19141 points to the array which contain the results and s3 to the corner.*/ 19142 19143 for (s1=sdir+4*kdim,s2=s1+kdim,s3=scoef+kdim*(kn1-1); s1<s2; s1++,s3++) 19144 { 19145 *s1 = *(s3-kdim) - *s3; 19146 *(s1+kdim) = *(s3+kdim*kn1) - *s3; 19147 } 19148 19149 /* Make the horizontal and vertical tangent in upper left corner. s1 19150 points to the result array and s3 to the corner. */ 19151 19152 for (s1=sdir+6*kdim,s2=s1+kdim,s3=scoef+kdim*kn1*(kn2-1);s1<s2;s1++,s3++) 19153 { 19154 *s1 = *(s3+kdim) - *s3; 19155 *(s1+kdim) = *(s3-kdim*kn1) - *s3; 19156 } 19157 19158 /* Make the horizontal and vertical tangent in upper right corner. 19159 s1 points to the result array and s3 to the corner. */ 19160 19161 for (s1=sdir+8*kdim,s2=s1+kdim,s3=scoef+kdim*(kn1*kn2-1);s1<s2;s1++,s3++) 19162 { 19163 *s1 = *(s3-kdim) - *s3; 19164 *(s1+kdim) = *(s3-kn1*kdim) - *s3; 19165 } 19166 } 19167 19168 /* Rotate coordinate system according to the vectors found and perform 19169 box-test. First use the diagonal vectors. */ 19170 19171 klap = 1; 19172 if (kvec == 2) 19173 { 19174 sh1834(po1,po2,aepsge,kdim,sdir,sdir+kdim,&kstat); 19175 if (kstat < 0) goto error; 19176 klap = kstat; 19177 19178 if (klap == 1) 19179 { 19180 sh1834(po1,po2,aepsge,kdim,sdir+kdim,sdir,&kstat); 19181 if (kstat < 0) goto error; 19182 klap = kstat; 19183 } 19184 } 19185 19186 /* If the box-tests performed till now show overlap and the surface 19187 is non-linear in at least one direction rotate the geometry according 19188 to the tangent information gathered. */ 19189 /* First remove superfluous rotation directions. */ 19190 19191 for (ki=4; ki<kvec; ) 19192 { 19193 for (kj=2; kj<4; kj+=2) 19194 { 19195 /* Test if the found vectors are aproximately equal. */ 19196 19197 tang1 = s6ang(sdir+ki*kdim,sdir+kj*kdim,kdim); 19198 tang2 = s6ang(sdir+(ki+1)*kdim,sdir+(kj+1)*kdim,kdim); 19199 19200 if (tang1 < ANGULAR_TOLERANCE && tang2 < ANGULAR_TOLERANCE) break; 19201 } 19202 19203 if (kj < 4) 19204 { 19205 /* Remove set of rotation vectors. */ 19206 19207 if (ki+2 < kvec) 19208 memcopy(sdir+ki*kdim, sdir+(ki+2)*kdim, (kvec-ki-2)*kdim, DOUBLE); 19209 kvec -= 2; 19210 } 19211 else ki+=2; 19212 } 19213 19214 ki = 2; 19215 while (ki<kvec && klap == 1) 19216 { 19217 sh1834(po1,po2,aepsge,kdim,sdir+ki*kdim,sdir+(ki+1)*kdim,&kstat); 19218 if (kstat < 0) goto error; 19219 klap = kstat; 19220 19221 if (klap && 19222 fabs(s6ang(sdir+ki*kdim,sdir+(ki+1)*kdim,kdim)-PIHALF) 19223 > ANGULAR_TOLERANCE) 19224 { 19225 /* VSK, 01/93. Use the other partial derivative as x-axis in 19226 the rotation. */ 19227 19228 sh1834(po1,po2,aepsge,kdim,sdir+(ki+1)*kdim,sdir+ki*kdim,&kstat); 19229 if (kstat < 0) goto error; 19230 klap = kstat; 19231 } 19232 ki += 2; 19233 } 19234 19235 /* Improved boxtest performed. */ 19236 19237 *jstat = klap; 19238 goto out; 19239 19240 /* Error in space allocation. */ 19241 19242 err101: *jstat = -101; 19243 s6err("sh1839",*jstat,kpos); 19244 goto out; 19245 19246 /* Error in input. Unexpected object found. */ 19247 19248 err122: *jstat = -122; 19249 s6err("sh1839",*jstat,kpos); 19250 goto out; 19251 19252 /* Error in lower level routine. */ 19253 19254 error : *jstat = kstat; 19255 s6err("sh1839",*jstat,kpos); 19256 goto out; 19257 19258 out: 19259 19260 /* Free allocated space. */ 19261 19262 if (sdir != SISL_NULL) freearray(sdir); 19263 19264 return; 19265 } 19266 19267 19268 //=========================================================================== 19269 int sh6isconnect(SISLIntpt *pt0, SISLIntpt *pt1, SISLIntpt *pt2) 19270 //=========================================================================== 19271 { 19272 int kstat = 0; /* Status on wether a connection is found. */ 19273 int ki; /* Counter. */ 19274 SISLIntpt *qt; /* Intersection point. */ 19275 int been_here = -199; 19276 19277 /* Test if the points are equal. */ 19278 19279 if (pt1 == pt2) return 1; 19280 19281 /* UJK, aug 93, oo-loop in sh6isconn. */ 19282 if (pt1->marker == been_here) return 0; 19283 pt1->marker = been_here; 19284 19285 /* Traverse the intersection points connected to pt1. */ 19286 19287 for (ki=0; ki<pt1->no_of_curves; ki++) 19288 { 19289 qt = sh6getnext(pt1,ki); 19290 if (qt == pt0) continue; 19291 19292 kstat = sh6isconnect(pt1,qt,pt2); 19293 19294 if (kstat) return 1; 19295 } 19296 19297 /* No connection is found. */ 19298 19299 return 0; 19300 } 19301 19302 19303 //=========================================================================== 19304 void sh6floop(SISLIntpt *vedgept[],int inum,int *jpt,int *jstat) 19305 //=========================================================================== 19306 { 19307 int kstat2 = -1; /* Status of traversing the first list. */ 19308 int kpt = 0; /* Current number of intersections in first loop. */ 19309 int ki,kj; /* Counters. */ 19310 SISLIntpt *qstart; /* First intersection point around the edges. */ 19311 SISLIntpt *qprev; /* Previous intersection point found. */ 19312 SISLIntpt *qt; /* Current intersection point in list. */ 19313 SISLIntpt *qnext = SISL_NULL; /* The next point to enter the list. */ 19314 SISLIntpt *qhelp; /* Help point used in sorting vedgept. */ 19315 19316 /* Check if there is a list. */ 19317 19318 *jpt = 0; 19319 if (inum == 0) goto out; 19320 19321 /* Set start point. */ 19322 19323 qstart = vedgept[0]; 19324 19325 /* Traverse the edge intersections to fetch a list starting in qstart. 19326 The elements in the list must lie on the edges of the objects. */ 19327 19328 for (qprev=SISL_NULL, qt=qstart; ; qt=vedgept[kpt]) 19329 { 19330 if (kstat2 == 0) 19331 { 19332 /* Open list. Travers in the opposite direction. */ 19333 19334 qt = qstart; 19335 qprev = (kpt > 0) ? vedgept[1] : SISL_NULL; 19336 } 19337 19338 for (ki=0; ki<qt->no_of_curves; ki++) 19339 { 19340 /* Search all curves in this points to find the list. */ 19341 19342 qnext = sh6getnext(qt,ki); 19343 19344 if (qnext == SISL_NULL) 19345 { 19346 kstat2 = 0; break; /* No point. */ 19347 } 19348 if (qnext == qprev) continue; /* Traversing of list have turned. 19349 Try next curve. */ 19350 if (qnext == qstart) 19351 { 19352 kstat2 = 1; break; /* A closed loop is found. */ 19353 } 19354 19355 /* An intersection is found. Check if it lies on the current 19356 edges. */ 19357 19358 for (kj=kpt+1; kj<inum; kj++) 19359 if (qnext == vedgept[kj]) break; 19360 19361 if (kj == inum) continue; /* The point lies not at an edge. */ 19362 19363 /* Change position in the array in such a way that the members 19364 of the list are placed first. */ 19365 19366 kpt++; 19367 qhelp = vedgept[kj]; 19368 vedgept[kj] = vedgept[kpt]; 19369 vedgept[kpt] = qhelp; 19370 19371 /* Set previous pointer. */ 19372 19373 qprev = qt; 19374 19375 /* Check if we are finished or may continue with the next point. */ 19376 19377 if (qnext == SISL_NULL || (qnext == qstart && qnext != qprev) || 19378 qprev == qt) break; 19379 } 19380 19381 /* Check if we have found the entire list. */ 19382 19383 if (qnext == qstart || kpt >= inum) break; 19384 else if (ki == qt->no_of_curves) 19385 { 19386 if (kstat2 < 0) kstat2 = 0; 19387 else break; 19388 } 19389 } 19390 19391 /* Set number of points in list and output status. */ 19392 19393 *jpt = kpt + 1; 19394 if (kpt == 0) *jstat = 2; 19395 else if (kstat2 == 1) *jstat = 1; 19396 else *jstat = 0; 19397 19398 out : 19399 return; 19400 } 19401 19402 //=========================================================================== 19403 void sh6closevert(SISLCurve *pcurve,SISLSurf *psurf,double *cpar1, double epar2[]) 19404 //=========================================================================== 19405 { 19406 int ki,kj,kl; /* Counters. */ 19407 int kdim = pcurve->idim; /* Dimension of geometry space. */ 19408 int kminc; /* Number of closest vertex of curve. */ 19409 int kmins1,kmins2; /* Numbers of closest vertex of surface. */ 19410 int kn = pcurve->in; /* Number of coefficients of curve. */ 19411 int kn1 = psurf->in1; /* Number of coefficients of surface, 1. par. dir. */ 19412 int kn2 = psurf->in2; /* Number of coefficients of surface, 2. par. dir. */ 19413 int kk = pcurve->ik; /* Order of curve. */ 19414 int kk1 = psurf->ik1; /* Order of surface, 1. par. dir. */ 19415 int kk2 = psurf->ik2; /* Order of surface, 2. par. dir. */ 19416 double tdist; /* Distance. */ 19417 double tmin = HUGE; /* Minimum distance. */ 19418 double tpar; /* Used to compute parameter values. */ 19419 double *s1,*s2; /* Pointers into arrays. */ 19420 19421 /* Find position of closest vertices. */ 19422 19423 for (s1=pcurve->ecoef, ki=0; ki<kn; s1+=kdim, ki++) 19424 for (s2=psurf->ecoef, kj=0; kj<kn1; kj++) 19425 for (kl=0; kl<kn2; s2+=kdim, kl++) 19426 { 19427 tdist = s6dist(s1,s2,kdim); 19428 if (tdist < tmin) 19429 { 19430 tmin = tdist; 19431 kminc = ki; 19432 kmins1 = kj; 19433 kmins2 = kl; 19434 } 19435 } 19436 19437 /* Estimate parameter values of vertices. */ 19438 19439 for (ki=kminc+1, s1=pcurve->et+ki, tpar=DZERO; 19440 ki<kminc+kk; tpar+=(*s1), s1++, ki++); 19441 *cpar1 = tpar/(double)(kk-1); 19442 19443 for (ki=kmins1+1, s1=psurf->et1+ki, tpar=DZERO; 19444 ki<kmins1+kk1; tpar+=(*s1), s1++, ki++); 19445 epar2[0] = tpar/(double)(kk1-1); 19446 19447 for (ki=kmins2+1, s1=psurf->et2+ki, tpar=DZERO; 19448 ki<kmins2+kk2; tpar+=(*s1), s1++, ki++); 19449 epar2[1] = tpar/(double)(kk2-1); 19450 19451 19452 goto out; 19453 19454 out: 19455 return; 19456 } 19457 19458 //=========================================================================== 19459 void sh6cvvert(SISLCurve *pc1, SISLCurve *pc2, double *cpar1, double *cpar2) 19460 //=========================================================================== 19461 { 19462 int ki,kj, kh; /* Counters. */ 19463 int kdim = pc1->idim; /* Dimension of geometry space. */ 19464 int kminc1; /* Number of closest vertex of 1. curve. */ 19465 int kminc2; /* Number of closest vertex of 2. curve. */ 19466 int kn1 = pc1->in; /* Number of coefficients of 1. curve. */ 19467 int kn2 = pc2->in; /* Number of coefficients of 2. curve. */ 19468 int kk1 = pc1->ik; /* Order of 1. curve. */ 19469 int kk2 = pc2->ik; /* Order of 2. curve. */ 19470 double tdist; /* Distance. */ 19471 double tmin = HUGE; /* Minimum distance. */ 19472 double tpar; /* Used to compute parameter values. */ 19473 double *s1,*s2; /* Pointers into arrays. */ 19474 19475 /* Find position of closest vertices. */ 19476 19477 for (s1=pc1->ecoef, ki=0; ki<kn1; s1+=kdim, ki++) 19478 for (s2=pc2->ecoef, kj=0; kj<kn2; s2+=kdim, kj++) 19479 { 19480 for (tdist=0.0, kh=kdim-1; kh>=0; kh--) 19481 tdist += (s2[kh]-s1[kh])*(s2[kh]-s1[kh]); 19482 // tdist = s6dist(s1,s2,kdim); 19483 if (tdist < tmin) 19484 { 19485 tmin = tdist; 19486 kminc1 = ki; 19487 kminc2 = kj; 19488 } 19489 } 19490 19491 /* Estimate parameter values of vertices. */ 19492 19493 for (ki=kminc1+1, s1=pc1->et+ki, tpar=0.0; 19494 ki<kminc1+kk1; tpar+=(*s1), s1++, ki++); 19495 *cpar1 = tpar/(double)(kk1-1); 19496 19497 for (ki=kminc2+1, s1=pc2->et+ki, tpar=0.0; 19498 ki<kminc2+kk2; tpar+=(*s1), s1++, ki++); 19499 *cpar2 = tpar/(double)(kk2-1); 19500 19501 return; 19502 } 19503 19504 //=========================================================================== 19505 void s1711(SISLSurf *ps,int ipar,double apar,SISLSurf **rsnew1, 19506 SISLSurf **rsnew2,int *jstat) 19507 //=========================================================================== 19508 { 19509 int kstat; /* Local status variable. */ 19510 int kpos=0; /* Position of error. */ 19511 int kmy; /* An index to the knot-vector. */ 19512 int kv,kv1; /* Number of knots we have to insert. */ 19513 int kpl,kfi,kla; /* To posisjon elements in trans.-matrix.*/ 19514 int kk,kksec; /* Order of the input surface. */ 19515 int kn,knsec; /* Number of the vertices in input curves.*/ 19516 int kdim=ps->idim; /* Dimensjon of the space in whice surface 19517 lies. */ 19518 int kind=ps->ikind; /* Type of surface ps is. */ 19519 int kn1,kn2; /* Number of vertices in the new surfaces.*/ 19520 int knum; /* Number of knots less and equal than 19521 the intersection point. */ 19522 int ki,ki1,ki2; /* Control variable in loop. */ 19523 int kj,kj1,kj2; /* Control variable in loop. */ 19524 int k1m,k2m,k3m,k4m; /* Variables to mark directons in array.*/ 19525 int newkind=1; /* Type of surface subsurfaces are. */ 19526 double *s1,*s2,*s3,*s4;/* Pointers used in loop. */ 19527 double *st,*stsec; /* The old knot-vectors. */ 19528 double *st1=SISL_NULL; /* The first first new knot-vector. */ 19529 double *st1sec=SISL_NULL; /* The first second new knot-vector. */ 19530 double *st2=SISL_NULL; /* The second first new knot-vector. */ 19531 double *st2sec=SISL_NULL; /* The second second new knot-vector. */ 19532 double *salfa=SISL_NULL; /* A line of the trans.-matrix. */ 19533 double *scoef; /* Pointer to vertices. */ 19534 double *scoef1=SISL_NULL; /* The first new vertice. */ 19535 double *scoef2=SISL_NULL; /* The second new vertice. */ 19536 SISLSurf *q1=SISL_NULL; /* Pointer to new surface-object. */ 19537 SISLSurf *q2=SISL_NULL; /* Pointer to new surface-object. */ 19538 double salfa_local[5];/* Local help array. */ 19539 19540 /* if ps is rational, do subdivision in homogeneous coordinates */ 19541 /* just need to set up correct dim and kind for the new surfaces at end of routine */ 19542 if(kind == 2 || kind == 4) 19543 { 19544 scoef = ps->rcoef; 19545 kdim++; 19546 newkind++; 19547 } 19548 else 19549 { 19550 scoef = ps->ecoef; 19551 } 19552 19553 /* Check that we have a surface to subdivide. */ 19554 19555 if (!ps) goto err150; 19556 19557 /* Making constants and ponters to mark direction. */ 19558 19559 if (ipar==1) 19560 { 19561 /* If ipar is 1 we have to split the "three" dimentional 19562 coeffisient matrix along a column. In this case k4m is 19563 the distance beetween each element in the clumn. 19564 For each element in the column we have to treat a part 19565 of a line, to march along the line we use k1m.*/ 19566 19567 st = ps->et1; 19568 stsec = ps->et2; 19569 kn = ps->in1; 19570 knsec = ps->in2; 19571 kk = ps->ik1; 19572 kksec = ps->ik2; 19573 k1m = kdim; 19574 k4m = kdim*kn; 19575 } 19576 else 19577 { 19578 /* If ipar is 2 we have to split the "three" dimentional 19579 coeffisient matrix along a line. In this case k4m is 19580 the distance beetween each element in the line. 19581 For each element in the line we have to treat a part 19582 of a column, to march along the column we use k1m.*/ 19583 19584 st = ps->et2; 19585 stsec = ps->et1; 19586 kn = ps->in2; 19587 knsec = ps->in1; 19588 kk = ps->ik2; 19589 kksec = ps->ik1; 19590 k1m = kdim*knsec; 19591 k4m = kdim; 19592 } 19593 19594 /* Check that the intersection point is an interior point. */ 19595 19596 if ((apar < *st && DNEQUAL(apar, *st)) || 19597 (apar > st[kn+kk-1] && DNEQUAL(apar, st[kn+kk-1]))) 19598 goto err158; 19599 19600 /* Allocate space for the kk elements which may not be zero in eache 19601 line of the basic transformation matrix.*/ 19602 19603 if (kk > 5) 19604 { 19605 if ((salfa = newarray (kk, double)) == SISL_NULL) goto err101; 19606 } 19607 else salfa = salfa_local; 19608 19609 /* Find the number of the knots which is smaller or like 19610 the intersection point, and how many knots we have to insert.*/ 19611 19612 s1 = st; 19613 kv = kk; /* The maximum number of knots we have to insert. */ 19614 19615 if ((apar > s1[0] && DNEQUAL(apar, s1[0])) && 19616 (apar < s1[kn+kk-1] && DNEQUAL(apar, s1[kn+kk-1]))) 19617 { 19618 /* Using binear search*/ 19619 kj1=0; 19620 kj2=kk+kn-1; 19621 knum = (kj1+kj2)/2; 19622 while (knum != kj1) 19623 { 19624 if ((s1[knum] < apar ) && DNEQUAL(s1[knum], apar)) 19625 kj1=knum; else kj2=knum; 19626 knum = (kj1+kj2)/2; 19627 } 19628 knum++; /* The smaller knots.*/ 19629 19630 while (DEQUAL(s1[knum], apar)) 19631 { 19632 apar = s1[knum]; 19633 knum++; 19634 kv--; 19635 } 19636 /* The knots thats like the */ 19637 /* intersection point. */ 19638 } 19639 else if (DEQUAL(apar,s1[0])) 19640 { 19641 apar = s1[0]; 19642 knum = 0; 19643 while (s1[knum] == apar) 19644 /* The knots thats like the intersection point. */ 19645 knum++; 19646 } 19647 else if (DEQUAL(apar,s1[kn+kk-1])) 19648 { 19649 apar = s1[kn+kk-1]; 19650 knum = kn+kk-1; 19651 while (s1[knum-1] == apar) 19652 /* The knots thats like the intersection point. */ 19653 knum--; 19654 } 19655 /* Find the number of vertices in the two new curves. */ 19656 19657 kn1 = knum + kv - kk; 19658 kn2 = kn + kk - knum; 19659 19660 /* Allocating the new arrays to the two new curves. */ 19661 19662 if ((st1=newarray(kn1+kk,double))==SISL_NULL) goto err101; 19663 if ((st1sec=newarray(knsec+kksec,double))==SISL_NULL) goto err101; 19664 if ((st2=newarray(kn2+kk,double))==SISL_NULL) goto err101; 19665 if ((st2sec=newarray(knsec+kksec,double))==SISL_NULL) goto err101; 19666 if ((scoef1=newarray(kn1*kdim*knsec,double))==SISL_NULL) goto err101; 19667 if ((scoef2=newarray(kn2*kdim*knsec,double))==SISL_NULL) goto err101; 19668 19669 /* Copying the knotvectors from the old curve to the new curves */ 19670 19671 memcopy(st1,st,kn1,double); 19672 memcopy(st2+kk,st+knum,kn2,double); 19673 memcopy(st1sec,stsec,knsec+kksec,double); 19674 memcopy(st2sec,stsec,knsec+kksec,double); 19675 19676 /* Updating the knotvectors by inserting the new k-touple knot */ 19677 19678 for(s2=st1+kn1,s3=st2,s4=s3+kk;s3<s4;s2++,s3++) *s2 = *s3 = apar; 19679 19680 /* Copying the coefisientvectors to the new curves.*/ 19681 19682 if (ipar == 1) 19683 for (ki=0; ki<knsec; ki++) 19684 { 19685 memcopy(scoef1+ki*kdim*kn1,scoef+ki*kdim*kn, 19686 kdim*kn1,double); 19687 memcopy(scoef2+ki*kdim*kn2,scoef+kdim*(ki*kn+knum-kk), 19688 kdim*kn2,double); 19689 } 19690 else 19691 { 19692 memcopy(scoef1,scoef,kdim*kn1*knsec,double); 19693 memcopy(scoef2,scoef+kdim*(knum-kk)*knsec, 19694 kdim*kn2*knsec,double); 19695 } 19696 19697 /* Updating the coefisientvectors to the new surfaces.*/ 19698 19699 /* Updating the first surface. */ 19700 19701 /* If we imagine that the matrix is turned in such a way that we are 19702 splitting it along a column, then for each element in the column 19703 we have to treat a par of a line, to march along the line 19704 in the first new matrix we use k1m, And we use k3m as a mark 19705 at the end of the column in this new matrix.*/ 19706 19707 if(ipar==1) 19708 { 19709 k2m=kdim*kn1; 19710 k3m=kdim*kn1*knsec; 19711 } 19712 else 19713 { 19714 k2m=kdim; 19715 k3m=kdim*knsec; 19716 } 19717 knum -= kk - 1; 19718 for (ki=max(0,knum),kv1=max(0,-knum),s1=scoef1+ki*k1m;ki<kn1;ki++,s1+=k1m) 19719 { 19720 /* Initialising: 19721 knum = knum-kk+1, Index of the first vertice to change. 19722 ki = knum, Index of the vertices we are going to 19723 change. Starting with knum, but if 19724 knum is negativ we start at zero. 19725 kv1 = 0, Number if new knots between index ki 19726 and ki+kk. We are starting one below 19727 becase we are counting up before using 19728 it. If knum is negativ we are not 19729 starting at zero but at -knum. 19730 s1=scoef1+ki*k1m Pointer at the first vertice to 19731 change. */ 19732 19733 /* Using the Oslo-algorithm to make a transformation-vector 19734 from the old vertices to one new vertice. */ 19735 19736 kmy=ki; 19737 s1700(kmy,kk,kn,++kv1,&kpl,&kfi,&kla,st,apar,salfa,&kstat); 19738 if (kstat) goto err153; 19739 19740 /* Compute the knsec*kdim vertices with the "same index". */ 19741 19742 for (s2=s1,s3=s2+k3m,ki2=0; s2<s3; s2+=k2m,ki2+=k4m) 19743 for (kj=0,s4=s2; kj<kdim; kj++,s4++) 19744 for (*s4=0,kj1=kfi,kj2=kfi+kpl; kj1<=kla;kj1++,kj2++) 19745 *s4 += salfa[kj2] * scoef[k1m*kj1+ki2+kj]; 19746 } 19747 19748 /* And the second surface. */ 19749 19750 /* If we imagine that the matrix is turned in such a way that we are 19751 splitting it along a column, then for each element in the column 19752 we have to treat a par of a line, to march along the line 19753 in the second new matrix we use k1m, And we use k3m as a mark 19754 at the end of the column in this new matrix.*/ 19755 19756 if(ipar==1) 19757 { 19758 k2m=kdim*kn2; 19759 k3m=kdim*kn2*knsec; 19760 } 19761 else 19762 { 19763 k2m=kdim; 19764 k3m=kdim*knsec; 19765 } 19766 19767 for (ki1=min(kn1+kv-1,kn+kv),s1=scoef2; ki<ki1; ki++,s1+=k1m) 19768 { 19769 /* Initialising: 19770 ki1 = kn1+kv-1, the index of the vertice next to the 19771 last vertice we have to change. 19772 If we do not have so many vertices, 19773 we have to use the index next to the 19774 last vertice we have, kn+kv. 19775 s1=scoef2 Pointer at the first vertice to 19776 change. */ 19777 19778 19779 /* Using the Oslo-algorithm to make a transformation-vector 19780 from the old vertices to one new vertice. */ 19781 19782 s1700(kmy,kk,kn,kv1--,&kpl,&kfi,&kla,st,apar,salfa,&kstat); 19783 if (kstat) goto err153; 19784 19785 19786 /* Compute the knsec*kdim vertices with the "same index". */ 19787 19788 for (s2=s1,s3=s2+k3m,ki2=0; s2<s3; s2+=k2m,ki2+=k4m) 19789 for (kj=0,s4=s2; kj<kdim; kj++,s4++) 19790 for (*s4=0,kj1=kfi,kj2=kfi+kpl; kj1<=kla;kj1++,kj2++) 19791 *s4 += salfa[kj2] * scoef[k1m*kj1+ki2+kj]; 19792 } 19793 19794 19795 /* Allocating new surface-objects.*/ 19796 /* use ps->idim rather than kdim in case ps is rational */ 19797 19798 19799 if (ipar==1) 19800 { 19801 if ((q1=newSurf(kn1,knsec,kk,kksec,st1,st1sec, /* PFU 15/07-94 */ 19802 scoef1,newkind,ps->idim,2)) == SISL_NULL) goto err101; 19803 if ((q2=newSurf(kn2,knsec,kk,kksec,st2,st2sec, /* PFU 15/07-94 */ 19804 scoef2,newkind,ps->idim,2)) == SISL_NULL) goto err101; 19805 } 19806 else 19807 { 19808 if ((q1=newSurf(knsec,kn1,kksec,kk,st1sec,st1, /* PFU 15/07-94 */ 19809 scoef1,newkind,ps->idim,2)) == SISL_NULL) goto err101; 19810 if ((q2=newSurf(knsec,kn2,kksec,kk,st2sec,st2, /* PFU 15/07-94 */ 19811 scoef2,newkind,ps->idim,2)) == SISL_NULL) goto err101; 19812 } 19813 19814 19815 /* Updating output. */ 19816 19817 *rsnew1 = q1; 19818 *rsnew2 = q2; 19819 *jstat = 0; 19820 goto out; 19821 19822 19823 /* Error. Error in lower level function. */ 19824 19825 err153: *jstat = kstat; 19826 goto outfree; 19827 19828 19829 /* Error. No surface to subdevice. */ 19830 19831 err150: *jstat = -150; 19832 s6err("s1711",*jstat,kpos); 19833 goto out; 19834 19835 19836 /* Error. The intersection-point is outside the surface. */ 19837 19838 err158: *jstat = -158; 19839 s6err("s1711",*jstat,kpos); 19840 goto out; 19841 19842 19843 /* Error. Allocation error, not enough memory. */ 19844 19845 err101: *jstat = -101; 19846 s6err("s1711",*jstat,kpos); 19847 goto outfree; 19848 19849 19850 outfree: 19851 if(q1) freeSurf(q1); 19852 if(q2) freeSurf(q2); 19853 19854 /* Free local used memory. */ 19855 19856 out: 19857 if(!q1) 19858 { 19859 if (st1) freearray(st1); 19860 if (st1sec) freearray(st1sec); 19861 if (scoef1) freearray(scoef1); 19862 } 19863 19864 if(!q2) 19865 { 19866 if (st2) freearray(st2); 19867 if (st2sec) freearray(st2sec); 19868 if (scoef2) freearray(scoef2); 19869 } 19870 19871 if (kk > 5 && salfa) 19872 freearray (salfa); 19873 return; 19874 } 19875 19876 19877 //=========================================================================== 19878 void s6idcpt(SISLIntdat *pintdat,SISLIntpt *pintpt,SISLIntpt **rintpt) 19879 //=========================================================================== 19880 { 19881 if (pintdat == SISL_NULL) 19882 *rintpt = SISL_NULL; 19883 else 19884 { 19885 int ki,knr; /* Counters. */ 19886 double tdist,td; /* To store distanse. */ 19887 19888 if (pintpt == pintdat->vpoint[0]) 19889 tdist = HUGE; 19890 else 19891 tdist = s6dist(pintdat->vpoint[0]->epar,pintpt->epar,pintpt->ipar); 19892 19893 for (knr=0,ki=1; ki<pintdat->ipoint; ki++) 19894 { 19895 if (pintpt == pintdat->vpoint[ki]) 19896 td = HUGE; 19897 else 19898 td = s6dist(pintdat->vpoint[ki]->epar,pintpt->epar,pintpt->ipar); 19899 19900 if (td < tdist) 19901 { 19902 knr = ki; 19903 tdist = td; 19904 } 19905 } 19906 19907 if (tdist == HUGE) 19908 *rintpt = SISL_NULL; 19909 else 19910 *rintpt = pintdat->vpoint[knr]; 19911 } 19912 } 19913 19914 //=========================================================================== 19915 void sh6insert(SISLIntdat **pintdat,SISLIntpt *pt1,SISLIntpt *pt2, 19916 SISLIntpt **ptnew,int *jstat) 19917 //=========================================================================== 19918 { 19919 int kstat; /* Local status variable. */ 19920 19921 *jstat = 0; 19922 19923 /* First we have to be sure that pintdat contains ptnew. */ 19924 19925 sh6idnpt(pintdat,ptnew,1,&kstat); 19926 if (kstat < 0) goto error; 19927 if (kstat > 0) 19928 { 19929 /* Point already existing in data structure, point killed, 19930 no insertion */ 19931 *jstat = 1; 19932 goto out; 19933 } 19934 19935 /* UJK, aug. 92 insert always mainpts if one of the neighbour is a main */ 19936 /* if (sh6ismain(pt1) && sh6ismain(pt2)) */ 19937 if (sh6ismain(pt1) || sh6ismain(pt2)) 19938 sh6tomain(*ptnew,&kstat); 19939 else 19940 sh6tohelp(*ptnew,&kstat); 19941 if (kstat < 0) goto error; 19942 19943 /* Then insert the point. */ 19944 sh6insertpt(pt1,pt2,*ptnew,&kstat); 19945 if (kstat < 0) goto error; 19946 19947 19948 goto out; 19949 19950 19951 /* Error. pt1 and pt2 are not properly connected. */ 19952 19953 19954 /* Error in sub function. */ 19955 19956 error: *jstat = kstat; 19957 s6err("sh6insert",*jstat,0); 19958 goto out; 19959 19960 out: 19961 return; 19962 } 19963 19964 //=========================================================================== 19965 void sh6idget (SISLObject * po1, SISLObject * po2, int ipar, double apar, 19966 SISLIntdat * pintdat, SISLIntdat ** rintdat, double aepsge, 19967 int *jstat) 19968 //=========================================================================== 19969 { 19970 int kstat; /* Local status variable. */ 19971 int kpos = 0; /* Position of error. */ 19972 int ki, kj, kn, kl; 19973 int keep_first; /* Flag, which object is not reduced */ 19974 double tstart[4]; 19975 double tend[4]; 19976 double spar[4]; /* Storing uppdated parametervalues. */ 19977 double tlow, thigh; 19978 double help_arr[4]; 19979 double thelp; 19980 SISLIntpt *qpt = SISL_NULL, *pinter=SISL_NULL; 19981 double *nullp = SISL_NULL; 19982 int found = FALSE; 19983 int ind_div, ind_other; 19984 SISLObject *qo_div = SISL_NULL, *qo_other = SISL_NULL; 19985 int kleftt = 0, klefts = 0; 19986 double point[3]; 19987 int log_ind; 19988 19989 /* Find out which object the parameter belongs to */ 19990 if (ipar < po1->iobj) 19991 { 19992 if(ipar == 1) log_ind = 0; 19993 else log_ind=1; 19994 qo_div = po1; 19995 qo_other = po2; 19996 ind_div = 0; 19997 ind_other = po1->iobj; 19998 keep_first = 0; 19999 } 20000 else 20001 { 20002 if(ipar == po1->iobj) log_ind = ipar +1; 20003 else log_ind=ipar-1; 20004 qo_div = po2; 20005 qo_other = po1; 20006 ind_div = po1->iobj; 20007 ind_other = 0; 20008 keep_first = 1; 20009 } 20010 20011 if (pintdat == SISL_NULL) 20012 goto out; 20013 20014 /* ----------------------------------------- */ 20015 20016 for (ki = 0; ki < pintdat->ipoint; ki++) 20017 { 20018 sh6isinside (po1, po2, pintdat->vpoint[ki], &kstat); 20019 if (kstat < 0) 20020 goto error; 20021 20022 if (kstat) 20023 { 20024 for (kj = 0; kj < (pintdat->vpoint[ki])->no_of_curves;kj++) 20025 { 20026 qpt = sh6getnext (pintdat->vpoint[ki], kj); 20027 sh6isinside (po1, po2, qpt, &kstat); 20028 if (kstat < 0) 20029 goto error; 20030 20031 /* For surface, check on curve_dir */ 20032 if (kstat && 20033 (qo_div->iobj == SISLCURVE || 20034 (qo_div->iobj == SISLSURFACE && 20035 (pintdat->vpoint[ki]->curve_dir[kj] & (1 << (log_ind + 1)))))) 20036 { 20037 /* curve: */ 20038 tlow = pintdat->vpoint[ki]->epar[ipar]; 20039 thigh = qpt->epar[ipar]; 20040 if (thigh < tlow) 20041 { 20042 thelp = thigh; 20043 thigh = tlow; 20044 tlow = thelp; 20045 } 20046 20047 if (apar > tlow && apar < thigh) 20048 { 20049 found = TRUE; 20050 break; 20051 } 20052 } 20053 } 20054 } 20055 if (found) 20056 { 20057 20058 for (kl=0; kl<qpt->ipar; kl++) 20059 help_arr[kl] = (double)0.5*(pintdat->vpoint[ki]->epar[kl] 20060 + qpt->epar[kl]); 20061 help_arr[ipar] = apar; 20062 20063 /* Prepare for iteration. */ 20064 if (qo_div->iobj == SISLCURVE) 20065 { 20066 kleftt=0; 20067 s1221 (qo_div->c1, 0, apar, &kleftt, point, &kstat); 20068 if (kstat < 0) 20069 goto error; 20070 } 20071 else 20072 { 20073 kleftt=0; 20074 klefts=0; 20075 s1421 (qo_div->s1, 0, help_arr + ind_div, 20076 &kleftt, &klefts, point, nullp, &kstat); 20077 if (kstat < 0) 20078 goto error; 20079 } 20080 20081 20082 sh6ptobj (point, qo_other, aepsge, help_arr + ind_other, 20083 help_arr + ind_other, &kstat); 20084 if (kstat == 1) 20085 { 20086 /* Point found, insert */ 20087 20088 pinter = hp_newIntpt (qpt->ipar, help_arr, DZERO, qpt->iinter, 20089 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 20090 0, 0, nullp, nullp); 20091 if (pinter == SISL_NULL) 20092 goto err101; 20093 20094 sh6insert (&pintdat, pintdat->vpoint[ki], qpt, &pinter, &kstat); 20095 if (kstat < 0) 20096 goto error; 20097 } 20098 } 20099 if (qo_div->iobj == SISLCURVE) 20100 break; 20101 else 20102 found = FALSE; 20103 } 20104 20105 20106 20107 /* ----------------------------------------- */ 20108 20109 20110 20111 if (po1->iobj == SISLCURVE) 20112 { 20113 tstart[0] = po1->c1->et[po1->c1->ik - 1]; 20114 tend[0] = po1->c1->et[po1->c1->in]; 20115 } 20116 else if (po1->iobj == SISLSURFACE) 20117 { 20118 tstart[0] = po1->s1->et1[po1->s1->ik1 - 1]; 20119 tend[0] = po1->s1->et1[po1->s1->in1]; 20120 tstart[1] = po1->s1->et2[po1->s1->ik2 - 1]; 20121 tend[1] = po1->s1->et2[po1->s1->in2]; 20122 } 20123 20124 if (po2->iobj == SISLCURVE) 20125 { 20126 tstart[po1->iobj] = po2->c1->et[po2->c1->ik - 1]; 20127 tend[po1->iobj] = po2->c1->et[po2->c1->in]; 20128 } 20129 else if (po2->iobj == SISLSURFACE) 20130 { 20131 tstart[po1->iobj] = po2->s1->et1[po2->s1->ik1 - 1]; 20132 tend[po1->iobj] = po2->s1->et1[po2->s1->in1]; 20133 tstart[po1->iobj + 1] = po2->s1->et2[po2->s1->ik2 - 1]; 20134 tend[po1->iobj + 1] = po2->s1->et2[po2->s1->in2]; 20135 } 20136 20137 /* Fix pick values for reduced paramater. */ 20138 tstart[ipar] = tend[ipar] = apar; 20139 20140 20141 /* Uppdate the array. */ 20142 20143 for (ki = 0; ki < pintdat->ipoint; ki++) 20144 { 20145 for (kj = 0; kj < pintdat->vpoint[ki]->ipar; kj++) 20146 if ((DNEQUAL (pintdat->vpoint[ki]->epar[kj], tstart[kj]) && 20147 pintdat->vpoint[ki]->epar[kj] < tstart[kj]) || 20148 (DNEQUAL (pintdat->vpoint[ki]->epar[kj], tend[kj]) && 20149 pintdat->vpoint[ki]->epar[kj] > tend[kj])) 20150 break; 20151 20152 if (kj == pintdat->vpoint[ki]->ipar) 20153 { 20154 for (kn = 0; kn < ipar; kn++) 20155 spar[kn] = pintdat->vpoint[ki]->epar[kn]; 20156 for (; kn < pintdat->vpoint[ki]->ipar - 1; kn++) 20157 spar[kn] = pintdat->vpoint[ki]->epar[kn + 1]; 20158 20159 /* Point accepted, insert into rintdat. */ 20160 /* VSK. Let the point be a normal main point. */ 20161 20162 qpt = hp_newIntpt (pintdat->vpoint[ki]->ipar - 1, spar, 20163 pintdat->vpoint[ki]->adist,1, 20164 pintdat->vpoint[ki]->left_obj_1[0], 20165 pintdat->vpoint[ki]->right_obj_1[0], 20166 pintdat->vpoint[ki]->left_obj_2[0], 20167 pintdat->vpoint[ki]->right_obj_2[0], 20168 (keep_first ? pintdat->vpoint[ki]->size_1 : 0), 20169 (keep_first ? 0 : pintdat->vpoint[ki]->size_2), 20170 (keep_first ? pintdat->vpoint[ki]->geo_data_1 : nullp), 20171 (keep_first ? nullp : pintdat->vpoint[ki]->geo_data_2)); 20172 20173 if (qpt == SISL_NULL) 20174 goto err101; 20175 20176 sh6idnpt (rintdat, &qpt, 1, &kstat); 20177 if (kstat < 0) 20178 goto error; 20179 } 20180 } 20181 20182 *jstat = 0; 20183 goto out; 20184 20185 20186 /* Error in space allocation. */ 20187 20188 err101:*jstat = -101; 20189 s6err ("sh6idget", *jstat, kpos); 20190 goto out; 20191 20192 /* Error in sub function. */ 20193 20194 error:*jstat = kstat; 20195 s6err ("sh6idget", *jstat, kpos); 20196 goto out; 20197 20198 out:; 20199 } 20200 20201 20202 //=========================================================================== 20203 void s1700(int imy,int ik,int in,int iv, 20204 int *jpl,int *jfi,int *jla,double *et,double apar, 20205 double *galfa,int *jstat) 20206 //=========================================================================== 20207 { 20208 int kpos=0; /* Posisjon of error. */ 20209 int kj,kv; /* Help variable */ 20210 int kp; /* Control variable in loop. */ 20211 double *salfa; /* Help pointer to galfa. */ 20212 double tbeta,tbeta1; /* Help variabels */ 20213 double td1,td2; /* Help variabels */ 20214 double *t1,*t2; /* Pointers to the knot vector. */ 20215 20216 20217 /* Check that the number of knots we insert is not to large */ 20218 20219 if (iv >= ik) goto err152; 20220 20221 20222 /* Compute the negativ difference between the index in galfa and 20223 the real knot inserten matrix. */ 20224 20225 *jpl=ik-imy-1; 20226 20227 20228 /* Changing the galfa so we may use the index in the real matrix. */ 20229 20230 galfa += *jpl; 20231 20232 20233 /* Initialise the last element. */ 20234 20235 galfa[imy] = 1; 20236 20237 20238 /* Here we go one time for each new knot we insert. */ 20239 20240 for (kj=in+iv-2,in+=ik-1,kv=ik-iv,kp=0; kp<iv; kp++,kv++) 20241 { 20242 /* The initialising: The two first are not changing. 20243 kj = in+iv-2, minus the maximum of kp it 20244 gives the index of the last 20245 orginal vertices. 20246 in = in+ik-1, the index of the last element in et. 20247 kv = ik-iv , the nuber of old knots in the field. 20248 This variabel is counting up to ik 20249 (the order) during the loops. */ 20250 20251 20252 /* Here we note the special case where we are at the 20253 start of the matrix and we does not have a k-touple 20254 knot at this end. */ 20255 20256 if (kp>=imy) tbeta1=(apar - *et)* *galfa/(et[kv] - *et); 20257 else tbeta1=(double)0.0; 20258 20259 20260 *jfi=max(1,imy-kp); *jla=min(imy,kj-kp); 20261 20262 20263 /* For details about this loop look in the reference. */ 20264 20265 for (salfa=galfa+*jfi,t1=et+*jfi,t2=et+*jla; t1<=t2; t1++,salfa++) 20266 { 20267 td1 = apar - *t1; 20268 td2 = t1[kv] - apar; 20269 tbeta = *salfa/(td1 + td2); 20270 salfa[-1] = td2*tbeta + tbeta1; 20271 tbeta1 = td1*tbeta; 20272 } 20273 20274 20275 /* Here we note the special case where we are at the 20276 end of the matrix and we does not have a k-touple 20277 knot at this end. */ 20278 20279 if (*jla<imy) 20280 { 20281 t1 = et + in; 20282 *(salfa-1) = tbeta1+(*t1-apar)* *salfa/(*t1 - *(t2+1)); 20283 } else *(salfa-1) = tbeta1; 20284 } 20285 20286 20287 /* Adjusting the index of first and last in galfa. */ 20288 20289 if (iv) (*jfi)--; 20290 else *jfi = *jla = imy; 20291 20292 20293 /* Updating output. */ 20294 20295 *jstat = 0; 20296 goto out; 20297 20298 20299 /* Error, to many insertions knots. */ 20300 20301 err152: 20302 *jstat = -152; 20303 s6err("s1700",*jstat,kpos); 20304 goto out; 20305 20306 out: 20307 return; 20308 } 20309 20310 20311 //=========================================================================== 20312 void s1231(SISLCurve *pc1,double apar, 20313 SISLCurve **rcnew1,SISLCurve **rcnew2,int *jstat) 20314 //=========================================================================== 20315 { 20316 int kstat; /* Local status variable. */ 20317 int kpos=0; /* Position of error. */ 20318 int kmy; /* An index to the knot-vector. */ 20319 int kv,kv1; /* Number of knots we have to insert. */ 20320 int kpl,kfi,kla; /* To posisjon elements in trans.-matrix. */ 20321 int kk=pc1->ik; /* Order of the input curve. */ 20322 int kn=pc1->in; /* Number of the vertices in input curves. */ 20323 int kdim=pc1->idim; /* Dimensjon of the space in whice curve lies.*/ 20324 int kind=pc1->ikind; /* Type of curve pc1 is. */ 20325 int kn1,kn2; /* Number of vertices in the new curves. */ 20326 int knum; /* Number of knots less and equal than 20327 the intersection point. */ 20328 int ki,ki1; /* Control variable in loop. */ 20329 int kj,kj1,kj2; /* Control variable in loop. */ 20330 int newkind=1; /* Type of curve the subcurves are */ 20331 double *s1,*s2,*s3,*s4; /* Pointers used in loop. */ 20332 double *st1=SISL_NULL; /* The first new knot-vector. */ 20333 double *st2=SISL_NULL; /* The second new knot-vector. */ 20334 double *salfa=SISL_NULL; /* A line of the trans.-matrix. */ 20335 double *scoef; /* Pointer to vertices. */ 20336 double *scoef1=SISL_NULL; /* The first new vertice. */ 20337 double *scoef2=SISL_NULL; /* The second new vertice. */ 20338 SISLCurve *q1=SISL_NULL; /* Pointer to new curve-object. */ 20339 SISLCurve *q2=SISL_NULL; /* Pointer to new curve-object. */ 20340 int incr; /* No of extra knots copied during periodicity*/ 20341 int mu; /* Multiplisity at the k'th knot */ 20342 int kleft = kk-1; /* Knot navigator */ 20343 double delta; /* Period size in knot array. */ 20344 double salfa_local[5]; /* Local help array. */ 20345 20346 *rcnew1 = SISL_NULL; 20347 *rcnew2 = SISL_NULL; 20348 20349 20350 /* if pc1 is rational, do subdivision in homogeneous coordinates */ 20351 /* just need to set up correct dim and kind for the new curves at end of routine */ 20352 if(kind == 2 || kind == 4) 20353 { 20354 scoef = pc1->rcoef; 20355 kdim++; 20356 newkind++; 20357 } 20358 else 20359 { 20360 scoef = pc1->ecoef; 20361 } 20362 20363 /* Check that we have a curve to subdivide. */ 20364 20365 if (!pc1) goto err150; 20366 20367 /* Periodic curve treatment, UJK jan 92--------------------------------- */ 20368 if (pc1->cuopen == SISL_CRV_PERIODIC) 20369 { 20370 delta = (pc1->et[kn] - pc1->et[kk - 1]); 20371 20372 /* Check that the intersection point is an interior point. */ 20373 if (apar < *(pc1->et) || apar > *(pc1->et + kn + kk - 1)) 20374 goto err158; 20375 20376 /* If inside the knot vector, but outside well define 20377 intervall, we shift the parameter value one period. */ 20378 if (apar < *(pc1->et + kk - 1)) 20379 apar += delta; 20380 if (apar > *(pc1->et + kn)) 20381 apar -= delta; 20382 20383 /* Now we create a new curve that is a copy of pc1, 20384 but with the period repeated once, 20385 this allows us to pick a whole period. */ 20386 20387 /* Get multiplisity at start of full basis interval */ 20388 mu = s6knotmult(pc1->et, kk, kn, &kleft, pc1->et[kk-1], &kstat); 20389 if (kstat < 0) goto err153; 20390 if (mu >= kk) goto errinp; 20391 20392 /* Copy ----------------------------------- */ 20393 incr = kn - kk + mu; 20394 if ((scoef1 = newarray ((kn + incr) * kdim, double)) == SISL_NULL) 20395 goto err101; 20396 if ((st1 = newarray (kn + kk + incr, double)) == SISL_NULL) 20397 goto err101; 20398 20399 memcopy (scoef1, pc1->ecoef, kn * kdim, double); 20400 memcopy (st1, pc1->et, kn + kk, double); 20401 memcopy (scoef1 + kn * kdim, pc1->ecoef + (kk - mu) * kdim, 20402 incr * kdim, double); 20403 20404 20405 for (ki = 0; ki < incr; ki++) 20406 st1[kn + kk + ki] = st1[kn + kk + ki - 1] + 20407 (st1[2*kk - mu + ki] - st1[2*kk - mu + ki - 1]); 20408 if ((q1 = newCurve (kn + incr, kk, st1, scoef1, 20409 newkind, pc1->idim, 2)) == SISL_NULL) 20410 goto err101; 20411 q1->cuopen = SISL_CRV_OPEN; 20412 20413 /* Pick part (one period)------------------ */ 20414 s1712 (q1, apar, apar + delta, 20415 rcnew1, &kstat); 20416 if (kstat < 0) 20417 goto err153; 20418 freeCurve (q1); 20419 if (*rcnew1) 20420 (*rcnew1)->cuopen = SISL_CRV_CLOSED; 20421 20422 /* Finished, exit */ 20423 *jstat = 2; 20424 goto out; 20425 20426 } 20427 20428 /* End of periodic curve treatment, UJK jan 92------------- */ 20429 20430 20431 /* Check that the intersection point is an interior point. */ 20432 /* Changed by UJK */ 20433 /*if (apar <= *(pc1->et) || apar >= *(pc1->et+kn+kk-1)) goto err158; */ 20434 if ((apar < pc1->et[kk - 1] || DEQUAL(apar, pc1->et[kk - 1]))|| 20435 (apar > pc1->et[kn] || DEQUAL(apar, pc1->et[kn]))) 20436 goto err158; 20437 20438 20439 /* Allocate space for the kk elements which may not be zero in eache 20440 line of the basic transformation matrix.*/ 20441 20442 if (kk > 5) 20443 { 20444 if ((salfa = newarray (kk, double)) == SISL_NULL) goto err101; 20445 } 20446 else salfa = salfa_local; 20447 20448 20449 /* Find the number of the knots which is smaller or like 20450 the intersection point, and how many knots we have to insert.*/ 20451 20452 s1 = pc1->et; 20453 kv = kk; /* The maximum number of knots we may have to insert. */ 20454 20455 /* Using binear search*/ 20456 kj1=0; 20457 kj2=kk+kn-1; 20458 knum = (kj1+kj2)/2; 20459 while (knum != kj1) 20460 { 20461 if ((s1[knum] < apar) && DNEQUAL (s1[knum], apar)) 20462 kj1=knum; else kj2=knum; 20463 knum = (kj1+kj2)/2; 20464 } 20465 knum++; /* The smaller knots. */ 20466 20467 while (DEQUAL (s1[knum], apar)) 20468 /* The knots thats like the intersection point. */ 20469 { 20470 apar = s1[knum]; 20471 knum++; 20472 kv--; 20473 } 20474 20475 20476 /* Find the number of vertices in the two new curves. */ 20477 20478 kn1 = knum + kv - kk; 20479 kn2 = kn + kk - knum; 20480 20481 20482 20483 /* Allocating the new arrays to the two new curves. */ 20484 20485 if (kn1>0) 20486 { 20487 if ((scoef1=newarray(kn1*kdim,double))==SISL_NULL) goto err101; 20488 if ((st1=newarray(kn1+kk,double))==SISL_NULL) goto err101; 20489 } 20490 if (kn2>0) 20491 { 20492 if ((scoef2=newarray(kn2*kdim,double))==SISL_NULL) goto err101; 20493 if ((st2=newarray(kn2+kk,double))==SISL_NULL) goto err101; 20494 } 20495 20496 20497 /* Copying the knotvectors, all but the intersection point from 20498 the old curve to the new curves */ 20499 20500 memcopy(st1,pc1->et,kn1,double); 20501 memcopy(st2+kk,pc1->et+knum,kn2,double); 20502 20503 20504 /* Updating the knotvectors by inserting a k-touple knot in 20505 the intersection point at each curve.*/ 20506 20507 for(s2=st1+kn1,s3=st2,s4=s3+kk; s3<s4; s2++,s3++) *s2 = *s3 = apar; 20508 20509 20510 /* Copying the coefisientvectors to the new curves.*/ 20511 20512 memcopy(scoef1,scoef,kdim*kn1,double); 20513 memcopy(scoef2,scoef+kdim*(knum-kk),kdim*kn2,double); 20514 20515 20516 /* Updating the coefisientvectors to the new curves.*/ 20517 20518 /* Updating the first curve. */ 20519 knum -= kk - 1; 20520 for (ki=max(0,knum),kv1=max(0,-knum),s1=scoef1+ki*kdim; ki<kn1; ki++) 20521 { 20522 /* Initialising: 20523 knum = knum-kk+1, Index of the first vertice to change. 20524 ki = knum, Index of the vertices we are going to 20525 change. Starting with knum, but if 20526 knum is negativ we start at zero. 20527 kv1 = 0, Number if new knots between index ki 20528 and ki+kk. We are starting one below 20529 becase we are counting up before using 20530 it. If knum is negativ we are not 20531 starting at zero but at -knum. 20532 s1=scoef1+ki*kdim,SISLPointer at the first vertice to 20533 change. */ 20534 20535 20536 /* Using the Oslo-algorithm to make a transformation-vector 20537 from the old vertices to one new vertice. */ 20538 20539 kmy=ki; 20540 s1700(kmy,kk,kn,++kv1,&kpl,&kfi,&kla,pc1->et,apar,salfa,&kstat); 20541 if (kstat) goto err153; 20542 20543 20544 /* Compute the kdim vertices with the same "index". */ 20545 20546 for (kj=0; kj<kdim; kj++,s1++) 20547 for (*s1=0,kj1=kfi,kj2=kfi+kpl; kj1<=kla; kj1++,kj2++) 20548 *s1 += salfa[kj2] * scoef[kj1*kdim+kj]; 20549 } 20550 20551 /* And the second curve. */ 20552 20553 for (ki1=min(kn1+kv-1,kn+kv),s1=scoef2; ki<ki1; ki++) 20554 { 20555 /* Initialising: 20556 ki1 = kn1+kv-1, the index of the vertice next to the 20557 last vertice we have to change. 20558 If we do not have so many vertices, 20559 we have to use the index next to the 20560 last vertice we have, kn+kv. 20561 s1=scoef2 Pointer at the first vertice to 20562 change. */ 20563 20564 20565 /* Using the Oslo-algorithm to make a transformation-vector 20566 from the old vertices to one new vertice. */ 20567 20568 s1700(kmy,kk,kn,kv1--,&kpl,&kfi,&kla,pc1->et,apar,salfa,&kstat); 20569 if (kstat) goto err153; 20570 20571 20572 /* Compute the kdim vertices with the same "index". */ 20573 20574 for (kj=0; kj<kdim; kj++,s1++) 20575 for (*s1=0,kj1=kfi,kj2=kfi+kpl; kj1<=kla; kj1++,kj2++) 20576 *s1 += salfa[kj2] * scoef[kj1*kdim+kj]; 20577 } 20578 20579 20580 /* Allocating new curve-objects.*/ 20581 /* use pc1->idim rather than kdim in case pc1 is rational */ 20582 20583 if (kn1>0) 20584 if ((q1=newCurve(kn1,kk,st1,scoef1,newkind,pc1->idim,2)) == SISL_NULL) 20585 goto err101; 20586 if (kn2>0) 20587 if ((q2=newCurve(kn2,kk,st2,scoef2,newkind,pc1->idim,2)) == SISL_NULL) 20588 goto err101; 20589 20590 20591 /* Updating output. */ 20592 20593 *rcnew1 = q1; 20594 *rcnew2 = q2; 20595 *jstat = 0; 20596 goto out; 20597 20598 20599 /* Error. Error in low level routine. */ 20600 20601 err153: 20602 *jstat = kstat; 20603 goto outfree; 20604 20605 20606 /* Error. Error in input */ 20607 errinp: 20608 *jstat = -154; 20609 goto outfree; 20610 20611 /* Error. No curve to subdivide. */ 20612 err150: 20613 *jstat = -150; 20614 s6err("s1231",*jstat,kpos); 20615 goto out; 20616 20617 20618 /* Error. The parameter value is outside the curve. */ 20619 20620 err158: 20621 *jstat = -158; 20622 s6err("s1231",*jstat,kpos); 20623 goto out; 20624 20625 20626 /* Error. Allocation error, not enough memory. */ 20627 20628 err101: 20629 *jstat = -101; 20630 s6err("s1231",*jstat,kpos); 20631 goto outfree; 20632 20633 20634 outfree: 20635 if(q1) freeCurve(q1); 20636 if(q2) freeCurve(q2); 20637 20638 /* Free local used memory. */ 20639 20640 out: 20641 if(!q1) 20642 { 20643 if (st1) freearray(st1); 20644 if (scoef1) freearray(scoef1); 20645 } 20646 20647 if(!q2) 20648 { 20649 if (st2) freearray(st2); 20650 if (scoef2) freearray(scoef2); 20651 } 20652 20653 if (kk > 5 && salfa) 20654 freearray (salfa); 20655 return; 20656 } 20657 20658 20659 //=========================================================================== 20660 void s1174_s9dir(double *cdiff1, double *cdiff2,double evals[]) 20661 //=========================================================================== 20662 { 20663 double tdiv; /* Determinant */ 20664 double ta11,ta12,ta21,ta22; /* The matrix */ 20665 double tmax; /* The largest value in matrix */ 20666 double tb1,tb2; /* The right hand side. */ 20667 double tderx,tderxx; /* Derivatives */ 20668 double tdery,tderyy; 20669 double tderxy; 20670 double tdeltax,tdeltay; /* Locals for the step value to be determined. */ 20671 /* --------------------------------------------------------------------- */ 20672 20673 /* Init */ 20674 tderx = evals[1]; 20675 tdery = evals[2]; 20676 tderxx = evals[3]; 20677 tderxy = evals[4]; 20678 tderyy = evals[5]; 20679 tdeltax = DZERO; 20680 tdeltay = DZERO; 20681 *cdiff1 = DZERO; 20682 *cdiff2 = DZERO; 20683 20684 20685 /* Building the matrix. */ 20686 20687 ta11 = tderxx; 20688 ta12 = tderxy; 20689 ta21 = tderxy; 20690 ta22 = tderyy; 20691 tb1 = -tderx; 20692 tb2 = -tdery; 20693 20694 tmax = max(fabs(ta11),max(fabs(ta12),max(fabs(ta21),fabs(ta22)))); 20695 20696 if (DEQUAL(tb1+tmax,tmax) && DEQUAL(tb2+tmax,tmax)) 20697 { 20698 /* Finished, we have found a max. */ 20699 } 20700 else 20701 { 20702 tdiv = ta11*ta22 - ta21*ta12; 20703 if (fabs(tdiv) > MAX(tmax*REL_COMP_RES,REL_COMP_RES)) 20704 { 20705 /* The matrix is ok, solve the system using Cramers rule. */ 20706 tdeltax = tb1*ta22 - tb2*ta12; 20707 tdeltay = ta11*tb2 - ta21*tb1; 20708 tdeltax /= tdiv; 20709 tdeltay /= tdiv; 20710 } 20711 else if (max (fabs(ta11),fabs(ta22)) > REL_COMP_RES) 20712 { 20713 if (fabs(ta11) > fabs(ta22)) 20714 tdeltax = tb1/ta11; 20715 else 20716 tdeltay = tb2/ta22; 20717 } 20718 20719 } 20720 20721 *cdiff1 = tdeltax; 20722 *cdiff2 = tdeltay; 20723 20724 } 20725 20726 //=========================================================================== 20727 void s1174_s9corr(double gd[], double acoef1,double acoef2,double astart1, 20728 double aend1,double astart2, double aend2) 20729 //=========================================================================== 20730 { 20731 if (acoef1 + gd[0] < astart1) gd[0] = astart1 - acoef1; 20732 else if (acoef1 + gd[0] > aend1) gd[0] = aend1 - acoef1; 20733 20734 if (acoef2 + gd[1] < astart2) gd[1] = astart2 - acoef2; 20735 else if (acoef2 + gd[1] > aend2) gd[1] = aend2 - acoef2; 20736 } 20737 20738 20739 //=========================================================================== 20740 void s1174(SISLSurf *psurf,double estart[], double eend[], double enext[], 20741 double gpos[],int *jstat) 20742 //=========================================================================== 20743 { 20744 int kstat = 0; /* Local status variable. */ 20745 int kpos = 0; /* Position of error. */ 20746 int kleft1=0; /* Variables used in the evaluator. */ 20747 int kleft2=0; /* Variables used in the evaluator. */ 20748 int kder=2; /* Order of derivatives to be calulated */ 20749 int knbit; /* Number of iterations */ 20750 int kdir; /* Changing direction. */ 20751 double tdelta[2]; /* Parameter intervals of the surface. */ 20752 double tdist = 0.0; /* Euclidian norm of derivative vector */ 20753 double tprev; /* Previous Euclidian norm of derivative vector*/ 20754 double td[2],t1[2],tdn[2];/* Distances between old and new parameter 20755 value in the two parameter directions. */ 20756 double sval[7]; /* Value ,first and second derivatiev of surf. */ 20757 double *snorm=sval+7; /* Normal vector of the surface, dummy. */ 20758 double snext[2]; /* Parameter values */ 20759 double tol = (double)10000.0*REL_COMP_RES; /* Singularity tolerance */ 20760 /* --------------------------------------------------------------------- */ 20761 20762 /* Test input. */ 20763 if (psurf->idim != 1) goto err106; 20764 20765 /* Fetch endpoints and the intervals of parameter interval of curves. */ 20766 20767 tdelta[0] = psurf->et1[psurf->in1] - psurf->et1[psurf->ik1 - 1]; 20768 tdelta[1] = psurf->et2[psurf->in2] - psurf->et2[psurf->ik2 - 1]; 20769 20770 20771 /* Initiate variables. */ 20772 gpos[0] = enext[0]; 20773 gpos[1] = enext[1]; 20774 20775 /* Evaluate 0-2.st derivatives of surface */ 20776 s1421(psurf,kder,gpos,&kleft1,&kleft2,sval,snorm,&kstat); 20777 if (kstat < 0) goto error; 20778 20779 /* Get Euclidian norm of derivative vector */ 20780 tprev = sqrt(sval[1]*sval[1] + sval[2]*sval[2]); 20781 20782 /* Compute the Newton stepdistanse vector. */ 20783 s1174_s9dir(td,td+1,sval); 20784 20785 if ( (fabs(td[0]/tdelta[0]) <= REL_COMP_RES) && 20786 (fabs(td[1]/tdelta[1]) <= REL_COMP_RES)) 20787 goto stop_it; 20788 20789 /* Adjust if we are not inside the parameter intervall. */ 20790 t1[0] = td[0]; 20791 t1[1] = td[1]; 20792 s1174_s9corr(t1,gpos[0],gpos[1],estart[0],eend[0],estart[1],eend[1]); 20793 20794 /* Iterate to find the intersection point. */ 20795 20796 for (knbit = 0; knbit < 50; knbit++) 20797 { 20798 /* Evaluate 0-2.st derivatives of surface */ 20799 20800 snext[0] = gpos[0] + t1[0]; 20801 snext[1] = gpos[1] + t1[1]; 20802 20803 s1421(psurf,kder,snext,&kleft1,&kleft2,sval,snorm,&kstat); 20804 if (kstat < 0) goto error; 20805 20806 /* Get Euclidian norm of derivative vector */ 20807 tdist = sqrt(sval[1]*sval[1] + sval[2]*sval[2]); 20808 20809 /* Compute the Newton stepdistanse vector. */ 20810 s1174_s9dir(tdn,tdn+1,sval); 20811 20812 /* Check if the direction of the step have change. */ 20813 20814 kdir = (s6scpr(td,tdn,2) >= DZERO); /* 0 if changed. */ 20815 20816 if (tdist <= tprev || kdir) 20817 { 20818 /* Ordinary converging. */ 20819 20820 gpos[0] += t1[0]; 20821 gpos[1] += t1[1]; 20822 20823 td[0] = t1[0] = tdn[0]; 20824 td[1] = t1[1] = tdn[1]; 20825 20826 /* Adjust if we are not inside the parameter intervall. */ 20827 s1174_s9corr(t1,gpos[0],gpos[1],estart[0],eend[0],estart[1],eend[1]); 20828 20829 20830 if ( (fabs(t1[0]/tdelta[0]) <= REL_COMP_RES) && 20831 (fabs(t1[1]/tdelta[1]) <= REL_COMP_RES)) 20832 { 20833 gpos[0] += t1[0]; 20834 gpos[1] += t1[1]; 20835 20836 break; 20837 } 20838 20839 tprev = tdist; 20840 } 20841 20842 else 20843 { 20844 /* Not converging, half step length try again. */ 20845 20846 t1[0] /= (double)2; 20847 t1[1] /= (double)2; 20848 /* knbit--; */ 20849 } 20850 } 20851 20852 /* Iteration stopped, test if point is extremum */ 20853 20854 stop_it: 20855 20856 if (tdist <= tol) 20857 *jstat = 1; 20858 else 20859 *jstat = 0; 20860 20861 20862 /* Test if the iteration is close to a knot */ 20863 if (fabs(gpos[0] - psurf->et1[kleft1])/tdelta[0] < tol) 20864 gpos[0] = psurf->et1[kleft1]; 20865 else if (fabs(gpos[0] - psurf->et1[kleft1+1])/tdelta[0] < tol) 20866 gpos[0] = psurf->et1[kleft1+1]; 20867 20868 if (fabs(gpos[1] - psurf->et2[kleft2])/tdelta[1] < tol) 20869 gpos[1] = psurf->et2[kleft2]; 20870 else if (fabs(gpos[1] - psurf->et2[kleft2+1])/tdelta[1] < tol) 20871 gpos[1] = psurf->et2[kleft2+1]; 20872 20873 /* Iteration completed. */ 20874 goto out; 20875 20876 /* --------------------------------------------------------------------- */ 20877 /* Error in input. Dimension not equal to 1 */ 20878 err106: *jstat = -106; 20879 s6err("s1174",*jstat,kpos); 20880 goto out; 20881 20882 /* Error in lower level routine. */ 20883 error : *jstat = kstat; 20884 s6err("s1174",*jstat,kpos); 20885 goto out; 20886 20887 out:; 20888 } 20889 20890 20891 //=========================================================================== 20892 void s9simple_knot(SISLSurf* surf, int idiv, double epar[], 20893 int *fixflag, int *jstat) 20894 //=========================================================================== 20895 { 20896 int k1,k2,kstat,mult; 20897 20898 k1 = k2 = *fixflag = 0; 20899 20900 if ( idiv < 1 || idiv > 3 ) goto err202; 20901 if (idiv == 1 || idiv == 3) /* Check in first parameter direction */ 20902 { 20903 if ( surf->in1 == surf->ik1 ) 20904 { 20905 epar[0] = (surf->et1[0] + surf->et1[surf->in1+surf->ik1-1])/2.0; 20906 k1 = 1; 20907 } 20908 else 20909 { 20910 int left = surf->ik1; 20911 mult = s6knotmult(surf->et1,surf->ik1,surf->in1, &left, 20912 surf->et1[surf->ik1],&kstat); 20913 if (kstat < 0 ) goto error; 20914 if ( surf->ik1+mult == surf->in1 ) 20915 { 20916 epar[0] = surf->et1[surf->ik1]; 20917 k1 = 1; 20918 *fixflag += 1; 20919 } 20920 } 20921 } 20922 20923 if (idiv == 2 || idiv == 3) 20924 { 20925 if ( surf->in2 == surf->ik2 ) 20926 { 20927 epar[1] = (surf->et2[0] + surf->et2[surf->in2+surf->ik2-1])/2.0; 20928 k1 += 2; 20929 } 20930 else 20931 { 20932 int left = surf->ik2; 20933 mult = s6knotmult(surf->et2,surf->ik2,surf->in2, &left, 20934 surf->et2[surf->ik2],&kstat); 20935 if (kstat < 0 ) goto error; 20936 if ( surf->ik2+mult == surf->in2 ) 20937 { 20938 epar[1] = surf->et2[surf->ik2]; 20939 k1 += 2; 20940 *fixflag += 2 ; 20941 } 20942 } 20943 } 20944 20945 *jstat = ((idiv == k1 && (*fixflag)) ? 1 : 0); 20946 goto out; 20947 20948 error : *jstat = kstat; 20949 s6err("s9simple_knot",*jstat,0); 20950 goto out; 20951 20952 err202 : *jstat = -202; 20953 s6err("s9simple_knot",*jstat,0); 20954 20955 out: return; 20956 } 20957 20958 20959 //=========================================================================== 20960 double s1792(double et[],int ik,int in) 20961 //=========================================================================== 20962 { 20963 if (in > ik) 20964 { 20965 int kpar = (in + ik)/2; 20966 20967 if (DNEQUAL(et[ik-1],et[kpar]) || DNEQUAL(et[in],et[kpar])) 20968 return et[kpar]; 20969 } 20970 20971 return (et[ik-1]+et[in])*(double)0.5; 20972 } 20973 20974 //=========================================================================== 20975 int s1772_s6local_pretop(double dist,double diff[],double normal[], 20976 double f[],double f_t[],double f_tt[], 20977 double s[],double s_u[],double s_v[], 20978 double s_uu[],double s_uv[],double s_vv[], 20979 int dim, int*jstat) 20980 //=========================================================================== 20981 { 20982 int kstat = 0; /* Status variable. */ 20983 int ki; /* Counter. */ 20984 int return_val; /* For return value. */ 20985 double a1,a2,a3,a4; /* Matrix. */ 20986 double *S_u = SISL_NULL; /* Normalized s_u. */ 20987 double *S_v; /* Normalized s_v. */ 20988 double *S_uxS_v; /* Cross between S_u and S_v. */ 20989 double *s_d; /* Second derevative in diriction f_t. */ 20990 double *N; /* Normalized normal. */ 20991 double *d_uv; /* Normalized direction vector in par-plane. */ 20992 double local[17]; /* Local array for allocations. */ 20993 20994 *jstat = 0; 20995 20996 if (s6ang(diff,normal,dim) > ANGULAR_TOLERANCE) goto warn1; 20997 20998 /* Allocate local used memory and set value pointers.*/ 20999 21000 if (dim > 3) 21001 { 21002 S_u = newarray(5*dim+2,double); 21003 if (S_u == SISL_NULL) goto err101; 21004 } 21005 else 21006 S_u = local; 21007 21008 S_v = S_u+dim; 21009 S_uxS_v = S_v+dim; 21010 s_d = S_uxS_v+dim; 21011 N = s_d+dim; 21012 d_uv = N+dim; 21013 21014 s6norm(s_u,dim,S_u,&kstat); 21015 if (kstat == 0) goto warn1; 21016 s6norm(s_v,dim,S_v,&kstat); 21017 if (kstat == 0) goto warn1; 21018 s6crss(S_u,S_v,S_uxS_v); 21019 a1 = s6scpr(S_u,S_v,dim); 21020 a2 = s6scpr(f_t,S_u,dim); 21021 a3 = s6scpr(f_t,S_v,dim); 21022 if ((a4 = s6scpr(S_uxS_v,S_uxS_v,dim)) < SINGULAR) goto warn1; 21023 21024 d_uv[0] = (a2 - a1*a3)/a4; 21025 d_uv[1] = (a3 - a1*a2)/a4; 21026 s6norm(d_uv,2,d_uv,&kstat); 21027 if (kstat == 0) goto warn1; 21028 21029 a1 = d_uv[0]*d_uv[0]; 21030 a2 = d_uv[1]*d_uv[1]; 21031 a3 = 2*d_uv[0]*d_uv[1]; 21032 21033 for (ki=0; ki<dim; ki++) 21034 s_d[ki] = a1*s_uu[ki] + a3*s_uv[ki] + a2*s_vv[ki]; 21035 21036 for (ki=0; ki<dim; ki++) 21037 N[ki] = diff[ki]/dist; 21038 21039 a1 = s6scpr(N,f_tt,dim) - s6scpr(N,s_d,dim); 21040 21041 return_val = a1 > 1.0e-10; 21042 goto out; 21043 21044 /* Error in allocation */ 21045 21046 err101: 21047 *jstat = -101; 21048 s6err("s1772_s6local_pretop",*jstat,0); 21049 return_val = 0; 21050 goto out; 21051 21052 /* Degenerated system. */ 21053 21054 warn1: 21055 return_val = -1; 21056 goto out; 21057 21058 out: 21059 if (S_u != local && S_u != SISL_NULL) freearray(S_u); 21060 return return_val; 21061 } 21062 21063 //=========================================================================== 21064 void s1772_s6sekant1(SISLCurve *pcurve,SISLSurf *psurf, 21065 double par_val[], double delta, double *dist, double aepsge, 21066 double astart1,double estart2[],double aend1,double eend2[], 21067 double c0[], double s0[], double norm[], int *jstat) 21068 //=========================================================================== 21069 { 21070 int ki,kj; /* Counter. */ 21071 int kstat = 0; /* Local status variable. */ 21072 int kpos = 0; /* Position of error. */ 21073 int dim; /* Dimension of space the curves lie in */ 21074 int knbit; /* Number of iterations */ 21075 double cu_val[2]; /* Parameter values on curve. */ 21076 double new_cu_val = par_val[2]; /* New parameter value on curve. */ 21077 double *diff; /* Difference vector between curve surface. */ 21078 double y[2],new_y,delta_y;/* Signed distance. */ 21079 SISLPoint *pt=SISL_NULL; /* Point for use in closest point point/surface*/ 21080 int cu_left = 0; /* Keep left knot information for evaluator. */ 21081 int s_left1 = 0; /* Keep left knot information for evaluator. */ 21082 int s_left2 = 0; /* Keep left knot information for evaluator. */ 21083 int shift = 0; /* Mark that the diriction have been changed. */ 21084 21085 *jstat = 0; 21086 21087 /* Test input. */ 21088 21089 if (pcurve->idim != psurf->idim) goto err106; 21090 dim = pcurve->idim; 21091 diff = c0 + dim; 21092 21093 if ((pt = newPoint(c0,dim,0)) == SISL_NULL) goto err101; 21094 21095 if (delta == 0.0) delta =1e-15; 21096 21097 if ((par_val[2] == astart1 && delta < 0.0) || 21098 (par_val[2] == aend1 && delta > 0.0)) 21099 { 21100 delta = -delta; 21101 shift++; 21102 } 21103 21104 if (fabs(delta) < (aend1 -astart1)/100.0) 21105 { 21106 if (delta < 0.0) 21107 delta = (astart1 - aend1)/100.0; 21108 else 21109 delta = (aend1 - astart1)/100.0; 21110 } 21111 else if (fabs(delta) > (aend1 -astart1)/10.0) 21112 { 21113 if (delta < 0.0) 21114 delta = (astart1 - aend1)/10.0; 21115 else 21116 delta = (aend1 - astart1)/10.0; 21117 } 21118 21119 21120 cu_val[0] = par_val[2]; 21121 s1221(pcurve,0,cu_val[0],&cu_left,pt->ecoef,&kstat); 21122 if (kstat < 0) goto error; 21123 s1773(pt,psurf,aepsge,estart2,eend2,par_val,par_val,&kstat); 21124 if (kstat < 0) goto error; 21125 s1421(psurf,1,par_val,&s_left1,&s_left2,s0,norm,&kstat); 21126 if (kstat < 0) goto error; 21127 for(kj=0; kj<dim; kj++) diff[kj] = s0[kj] - pt->ecoef[kj]; 21128 new_y = s6norm(norm,dim,norm,&kstat); 21129 if (kstat == 0) 21130 { 21131 (*dist)=s6length(diff,dim,&kstat); 21132 new_cu_val = cu_val[0]; 21133 goto out; 21134 } 21135 if (((*dist)=s6length(diff,dim,&kstat)) < aepsge) 21136 { 21137 new_cu_val = cu_val[0]; 21138 goto out; 21139 } 21140 y[0] = s6scpr(norm,diff,dim); 21141 cu_val[1] = cu_val[0] + delta; 21142 21143 for (ki=0; ki<20; ki++) 21144 { 21145 s1221(pcurve,0,cu_val[1],&cu_left,pt->ecoef,&kstat); 21146 if (kstat < 0) goto error; 21147 s1773(pt,psurf,aepsge,estart2,eend2,par_val,par_val,&kstat); 21148 if (kstat < 0) goto error; 21149 s1421(psurf,1,par_val,&s_left1,&s_left2,s0,norm,&kstat); 21150 if (kstat < 0) goto error; 21151 for(kj=0; kj<dim; kj++) diff[kj] = s0[kj] - pt->ecoef[kj]; 21152 new_y = s6norm(norm,dim,norm,&kstat); 21153 if (kstat == 0) 21154 { 21155 (*dist)=s6length(diff,dim,&kstat); 21156 new_cu_val = cu_val[1]; 21157 goto out; 21158 } 21159 if (((*dist)=s6length(diff,dim,&kstat)) < aepsge) 21160 { 21161 new_cu_val = cu_val[1]; 21162 goto out; 21163 } 21164 y[1] = s6scpr(norm,diff,dim); 21165 new_y = y[1]/y[0]; 21166 if (new_y > 1.0000000000001) 21167 { 21168 if (shift) 21169 { 21170 new_cu_val = cu_val[1]; 21171 goto out; 21172 } 21173 delta = -delta; 21174 /* ALA, UJK, sept 93, update cu_val[1]*/ 21175 cu_val[1] = cu_val[0] + delta; 21176 shift++; 21177 } 21178 else if (y[0]*y[1] <= 0.0 || fabs(new_y) < 0.5) break; 21179 else 21180 { 21181 if (cu_val[1]+delta <= aend1 && 21182 cu_val[1]+delta >= astart1) cu_val[1] += delta; 21183 else if (cu_val[1] < aend1) cu_val[1] = aend1; 21184 else if (cu_val[1] > astart1) cu_val[1] = astart1; 21185 else 21186 { 21187 new_cu_val = cu_val[1]; 21188 goto out; 21189 } 21190 } 21191 } 21192 21193 if (ki == 20) 21194 { 21195 *jstat = 2; 21196 goto out; 21197 } 21198 21199 for (knbit=0; knbit < 50; knbit++) 21200 { 21201 delta_y = y[0]-y[1]; 21202 if (fabs(delta_y) < REL_COMP_RES) break; 21203 21204 new_cu_val = cu_val[1] + y[1]*(cu_val[1]-cu_val[0])/delta_y; 21205 if (new_cu_val >= aend1) 21206 { 21207 new_cu_val = aend1; 21208 if (cu_val[0] == aend1 || cu_val[1] == aend1) goto out; 21209 } 21210 else if (new_cu_val <= astart1) 21211 { 21212 new_cu_val = astart1; 21213 if (cu_val[0] == astart1 || cu_val[1] == astart1) goto out; 21214 } 21215 21216 s1221(pcurve,0,new_cu_val,&cu_left,pt->ecoef,&kstat); 21217 if (kstat < 0) goto error; 21218 s1773(pt,psurf,aepsge,estart2,eend2,par_val,par_val,&kstat); 21219 if (kstat < 0) goto error; 21220 s1421(psurf,1,par_val,&s_left1,&s_left2,s0,norm,&kstat); 21221 if (kstat < 0) goto error; 21222 for(kj=0; kj<dim; kj++) diff[kj] = s0[kj] - pt->ecoef[kj]; 21223 new_y = s6norm(norm,dim,norm,&kstat); 21224 if (kstat == 0) 21225 { 21226 (*dist) = s6length(diff,dim,&kstat); 21227 goto out; 21228 } 21229 if (((*dist)=s6length(diff,dim,&kstat)) < aepsge) goto out; 21230 new_y = s6scpr(norm,diff,dim); 21231 21232 if ((y[0] < 0.0 && y[1] > 0.0) || 21233 (y[0] > 0.0 && y[1] < 0.0)) 21234 { 21235 if ((new_y > 0.0 && y[0] > 0.0) || 21236 (new_y < 0.0 && y[0] < 0.0)) 21237 { 21238 cu_val[0] = new_cu_val; 21239 y[0] = new_y; 21240 } 21241 else 21242 { 21243 cu_val[1] = new_cu_val; 21244 y[1] = new_y; 21245 } 21246 } 21247 else 21248 { 21249 if ( y[0] < 0.0 && new_y > 0.0) 21250 { 21251 if (y[0] < y[1]) 21252 { 21253 cu_val[0] = new_cu_val; 21254 y[0] = new_y; 21255 } 21256 else 21257 { 21258 cu_val[1] = new_cu_val; 21259 y[1] = new_y; 21260 } 21261 } 21262 else if ( y[0] > 0.0 && new_y < 0.0) 21263 { 21264 if (y[0] > y[1]) 21265 { 21266 cu_val[0] = new_cu_val; 21267 y[0] = new_y; 21268 } 21269 else 21270 { 21271 cu_val[1] = new_cu_val; 21272 y[1] = new_y; 21273 } 21274 } 21275 else if (y[0] > 0.0) 21276 { 21277 if (y[0] > y[1]) 21278 { 21279 if (new_y >= y[0]) break; 21280 cu_val[0] = new_cu_val; 21281 y[0] = new_y; 21282 } 21283 else 21284 { 21285 if (new_y >= y[1]) break; 21286 cu_val[1] = new_cu_val; 21287 y[1] = new_y; 21288 } 21289 21290 } 21291 else if (y[0] < 0.0) 21292 { 21293 if (y[0] < y[1]) 21294 { 21295 if (new_y <= y[0]) break; 21296 cu_val[0] = new_cu_val; 21297 y[0] = new_y; 21298 } 21299 else 21300 { 21301 if (new_y <= y[1]) break; 21302 cu_val[1] = new_cu_val; 21303 y[1] = new_y; 21304 } 21305 } 21306 } 21307 } 21308 21309 /* Iteration completed. */ 21310 21311 goto out; 21312 21313 /* Error in allocation */ 21314 21315 err101: 21316 *jstat = -101; 21317 s6err("s1772_s6sekant1",*jstat,kpos); 21318 goto out; 21319 21320 /* Error in input. Conflicting dimensions. */ 21321 21322 err106: 21323 *jstat = -106; 21324 s6err("s1772_s6sekant1",*jstat,kpos); 21325 goto out; 21326 21327 /* Error in lower level routine. */ 21328 21329 error : 21330 *jstat = kstat; 21331 s6err("s1772_s6sekant1",*jstat,kpos); 21332 goto out; 21333 21334 out: 21335 par_val[2] = new_cu_val; 21336 if(pt) freePoint(pt); 21337 } 21338 21339 21340 //=========================================================================== 21341 void s1772_s9dir(double *dist,double diff[],double delta[], 21342 double f[],double f_t[],double f_tt[], 21343 double g[],double g_u[],double g_v[], 21344 double g_uu[],double g_uv[],double g_vv[], 21345 int dim,int second,int* jstat) 21346 //=========================================================================== 21347 { 21348 int kstat; /* Local status variable. */ 21349 double a1,a2,a3,a4,a5,a6; /* The A matrix, diagonal and A12 A13 A23.*/ 21350 double b1,b2,b3,b4; /* The B matrix, diagonal and B23. */ 21351 double A[9],mat[9]; /* Matrix in linear equation to be solved */ 21352 double h[3]; /* Left side in the equation. */ 21353 double x[3]; /* Left side in the equation. */ 21354 double r[3]; /* Left side in the equation. */ 21355 double det; /* Determinant for matrix. */ 21356 long double ss,aa,xx,bb; /* For use in iterative improvement. */ 21357 int piv[3]; /* Pivotation array */ 21358 int k,k3,j; /* Counters. */ 21359 21360 21361 /* Computing the different vector */ 21362 21363 s6diff(f,g,dim,diff); 21364 21365 /* Computing the length of the different vector. */ 21366 21367 *dist = s6length(diff,dim,&kstat); 21368 if (kstat<0) goto error; 21369 21370 if (second || dim != 3) 21371 { 21372 a1 = s6scpr(f_t,f_t,dim); 21373 a2 = s6scpr(g_u,g_u,dim); 21374 a3 = s6scpr(g_v,g_v,dim); 21375 a4 = s6scpr(f_t,g_u,dim); 21376 a5 = s6scpr(f_t,g_v,dim); 21377 a6 = s6scpr(g_u,g_v,dim); 21378 } 21379 21380 if (second) 21381 { 21382 b1 = s6scpr(diff,f_tt,dim); 21383 b2 = s6scpr(diff,g_uu,dim); 21384 b3 = s6scpr(diff,g_vv,dim); 21385 b4 = s6scpr(diff,g_uv,dim); 21386 } 21387 else b1=b2=b3=b4=0; 21388 21389 if (second || dim != 3) 21390 { 21391 mat[0] = a2-b2; mat[1] = a6-b4; mat[2] = -a4; 21392 mat[3] = a6-b4; mat[4] = a3-b3; mat[5] = -a5; 21393 mat[6] = -a4; mat[7] = -a5; mat[8] = a1+b1; 21394 21395 h[0] = s6scpr(diff,g_u,dim); 21396 h[1] = s6scpr(diff,g_v,dim); 21397 h[2] = -s6scpr(diff,f_t,dim); 21398 } 21399 else 21400 { 21401 mat[0] = g_u[0]; mat[1] = g_v[0]; mat[2] = -f_t[0]; 21402 mat[3] = g_u[1]; mat[4] = g_v[1]; mat[5] = -f_t[1]; 21403 mat[6] = g_u[2]; mat[7] = g_v[2]; mat[8] = -f_t[2]; 21404 21405 h[0] = diff[0]; 21406 h[1] = diff[1]; 21407 h[2] = diff[2]; 21408 } 21409 21410 for (k=0;k<9;k++) A[k]=mat[k]; 21411 for (k=0;k<3;k++) x[k]=h[k]; 21412 21413 det = A[0]*(A[4]*A[8]-A[5]*A[7]) 21414 - A[1]*(A[3]*A[8]-A[5]*A[6]) 21415 + A[2]*(A[3]*A[7]-A[4]*A[6]); 21416 if (fabs(det) < 1.0e-16) 21417 { 21418 *jstat = 1; 21419 goto out; 21420 } 21421 21422 /* solve the linear 3x3 system */ 21423 21424 /* s1772_s6lufacp(mat,piv,&kstat); */ 21425 s6lufacp(mat,piv,3,&kstat); 21426 if (kstat<0) goto error; 21427 if (kstat == 1) 21428 { 21429 *jstat = 1; 21430 goto out; 21431 } 21432 21433 s6lusolp(mat,x,piv,3,&kstat); 21434 if (kstat<0) goto error; 21435 if (kstat == 1) 21436 { 21437 *jstat = 1; 21438 goto out; 21439 } 21440 21441 for (k=0;k<3;k++) delta[k] = x[k]; 21442 21443 for (k=k3=0; k<3; k++,k3+=3) 21444 { 21445 for (ss=0.0,j=0; j<3; j++) 21446 { 21447 aa = A[j+k3]; 21448 xx = x[j]; 21449 ss += aa*xx; 21450 } 21451 bb = h[k]; 21452 ss = bb-ss; 21453 r[k] = ss; 21454 } 21455 s6lusolp(mat,r,piv,3,&kstat); 21456 if (kstat<0) goto error; 21457 if (kstat == 1) 21458 { 21459 *jstat = 1; 21460 goto out; 21461 } 21462 21463 for (k=0;k<3;k++) delta[k] = x[k] + r[k]; 21464 21465 /* if (debug_flag) printf("\nITERATIV IMPROVES: r = (%g %g %g) ", 21466 delta[0]-x[0],delta[1]-x[1],delta[2]-x[2]); */ 21467 21468 *jstat = 0; 21469 goto out; 21470 21471 error : 21472 *jstat = kstat; 21473 s6err("s1772_s9dir",*jstat,0); 21474 goto out; 21475 21476 out: 21477 return; 21478 } 21479 21480 21481 //=========================================================================== 21482 void s1772_s9corr(double gd[],double acoef[],double astart1,double aend1, 21483 double astart2[],double aend2[],int *corr) 21484 //=========================================================================== 21485 { 21486 int lcorr = 0; 21487 if (acoef[0] + gd[0] < astart2[0]) 21488 { 21489 gd[0] = astart2[0] - acoef[0]; 21490 lcorr=1; 21491 } 21492 else if (acoef[0] + gd[0] > aend2[0]) 21493 { 21494 gd[0] = aend2[0] - acoef[0]; 21495 lcorr=1; 21496 } 21497 21498 if (acoef[1] + gd[1] < astart2[1]) 21499 { 21500 gd[1] = astart2[1] - acoef[1]; 21501 lcorr=1; 21502 } 21503 else if (acoef[1] + gd[1] > aend2[1]) 21504 { 21505 gd[1] = aend2[1] - acoef[1]; 21506 lcorr=1; 21507 } 21508 21509 if (acoef[2] + gd[2] < astart1) 21510 { 21511 gd[2] = astart1 - acoef[2]; 21512 lcorr=1; 21513 } 21514 else if (acoef[2] + gd[2] > aend1) 21515 { 21516 gd[2] = aend1 - acoef[2]; 21517 lcorr=1; 21518 } 21519 21520 if (lcorr) 21521 (*corr)++; 21522 else 21523 (*corr) = 0; 21524 } 21525 21526 21527 //=========================================================================== 21528 void s1772(SISLCurve *pcurve,SISLSurf *psurf,double aepsge, 21529 double astart1,double estart2[],double aend1,double eend2[], 21530 double anext1,double enext2[],double *cpos1,double gpos2[], int *jstat) 21531 //=========================================================================== 21532 { 21533 int ki; /* Counter. */ 21534 int kstat = 0; /* Local status variable. */ 21535 int kpos = 0; /* Position of error. */ 21536 int left[3]; /* Variables used in the evaluator. */ 21537 int dim; /* Dimension of space the curves lie in */ 21538 int knbit; /* Number of iterations */ 21539 int p_dir; /* Changing direction in par-space. */ 21540 int g_up,ng_up,g_dir; /* Changing direction in geometric space. */ 21541 int order; /* Order of methode. */ 21542 int sing = 0; /* Mark that singularity has ocured. */ 21543 double *c0=SISL_NULL; /* Value of curve. */ 21544 double *c_t; /* First derivatiev of curve. */ 21545 double *c_tt; /* Second derivatiev of curve. */ 21546 double *s0; /* Value of surf. */ 21547 double *s_u; /* First derivatiev in first dir of surf. */ 21548 double *s_v; /* First derivatiev in second dir of surf. */ 21549 double *s_uu; /* Second derivatiev in first dir of surf. */ 21550 double *s_vv; /* Second derivatiev in second dir of surf. */ 21551 double *s_uv; /* Cross derivatiev of surf. */ 21552 double *s_v1; /* First derivatiev in second dir of surf. */ 21553 double *norm; /* Normal to the surface. */ 21554 double *diff; /* Difference between the curve and the surf. */ 21555 double *prev_diff; /* Previous difference. */ 21556 double delta[3]; /* Parameter interval of the curve and surface.*/ 21557 double d[3]; /* Clipped distances between old and new par. 21558 value in the tree parameter directions. */ 21559 double c_d[3]; /* Computed distances .... */ 21560 double nc_d[3]; /* New computed distances .... */ 21561 double dist; /* Distance between position and origo. */ 21562 double prev_dist; /* Previous difference between the curves. */ 21563 double par_val[3]; /* Parameter values */ 21564 double local[45]; 21565 int corr = 0, div2 = 0; 21566 21567 21568 21569 21570 /* Test input. */ 21571 21572 if (pcurve->idim != psurf->idim) goto err106; 21573 dim = pcurve->idim; 21574 21575 /* Fetch endpoints and the intervals of parameter interval of curves. */ 21576 21577 delta[0] = psurf->et1[psurf->in1] - psurf->et1[psurf->ik1 - 1]; 21578 delta[1] = psurf->et2[psurf->in2] - psurf->et2[psurf->ik2 - 1]; 21579 delta[2] = pcurve->et[pcurve->in] - pcurve->et[pcurve->ik - 1]; 21580 21581 /* Allocate local used memory and set value pointers.*/ 21582 21583 if (dim > 3) 21584 { 21585 c0 = newarray((15)*dim,double); 21586 if (c0 == SISL_NULL) goto err101; 21587 } 21588 else 21589 c0 = local; 21590 21591 s0 = c0 + 3*dim; 21592 diff = s0 + 10*dim; 21593 prev_diff = diff+dim; 21594 c_t = c0+dim; 21595 c_tt = c_t+dim; 21596 s_u = s0+dim; 21597 s_uu = s_u+dim; 21598 s_v1 = s_uu+dim; 21599 s_uv = s_v1+dim; 21600 s_vv = s_uv+dim+dim; 21601 norm = s_vv+dim; 21602 21603 /* Initiate variables. */ 21604 21605 s1772_copy2(par_val,enext2,2); 21606 par_val[2] = anext1; 21607 left[0]=left[1]=left[2]=0; 21608 21609 for (ki=1; ki<3; ki++) 21610 { 21611 s1772_set_order(ki); 21612 21613 /* Evaluate 0-2.st derivatives of curve */ 21614 21615 if (par_val[2] == aend1) 21616 s1227(pcurve,1+order,par_val[2],left+2,c0,&kstat); 21617 else 21618 s1221(pcurve,1+order,par_val[2],left+2,c0,&kstat); 21619 if (kstat < 0) goto error; 21620 21621 /* Evaluate 0-2.st derivatives of surface */ 21622 21623 s1424(psurf,1+order,1+order,par_val,left,left+1,s0,&kstat); 21624 if (kstat < 0) goto error; 21625 21626 /* Compute the distanse vector and value and the new step. */ 21627 21628 s1772_s9dir(&dist,diff,c_d, c0,c_t,c_tt, 21629 s0,s_u,s_v,s_uu,s_uv,s_vv, dim,order,&kstat); 21630 if (kstat < 0) goto error; 21631 if (kstat == 1) /* Singular matrix. */ 21632 { 21633 if (order == 1) goto singular; 21634 } 21635 else break; 21636 } 21637 21638 /* Correct if we are not inside the parameter intervall. */ 21639 21640 s6crss(s_u,s_v,norm); 21641 g_up = ((s6scpr(diff,norm,dim) >= DZERO) ? 1 : -1); 21642 s1772_copy2(d,c_d,3); 21643 s1772_s9corr(d,par_val, astart1,aend1,estart2,eend2,&corr); 21644 prev_dist = dist; 21645 s1772_copy2(prev_diff,diff,dim); 21646 21647 /* Iterate to find the intersection point. */ 21648 21649 for (knbit = 0; knbit < 30; knbit++) 21650 { 21651 s1772_incr2(par_val,d,3); 21652 21653 while (1) 21654 { 21655 /* Evaluate 0-2.st derivatives of curve */ 21656 21657 if (par_val[2] == aend1) 21658 s1227(pcurve,1+order,par_val[2],left+2,c0,&kstat); 21659 else 21660 s1221(pcurve,1+order,par_val[2],left+2,c0,&kstat); 21661 if (kstat < 0) goto error; 21662 21663 /* Evaluate 0-2.st derivatives of surface */ 21664 21665 s1424(psurf,1+order,1+order,par_val,left,left+1,s0,&kstat); 21666 if (kstat < 0) goto error; 21667 21668 /* Compute the distanse vector and value and the new step. */ 21669 21670 21671 s1772_s9dir(&dist,diff,nc_d, c0,c_t,c_tt, 21672 s0,s_u,s_v,s_uu,s_uv,s_vv, dim,order,&kstat); 21673 if (kstat < 0) goto error; 21674 if (kstat == 1) /* Singular matrix. */ 21675 { 21676 sing++; 21677 if (order == 1) goto singular; 21678 else s1772_set_order(2); /* Change to order 2. */ 21679 } 21680 else 21681 { 21682 s6crss(s_u,s_v,norm); 21683 ng_up = ((s6scpr(diff,norm,dim) >= DZERO) ? 1 : -1); 21684 21685 g_dir = (ng_up+g_up != 0); /* 0 if changed. */ 21686 p_dir = (s6scpr(c_d,nc_d,3) >= DZERO); /* 0 if changed. */ 21687 21688 if (!order && g_dir && (!p_dir || dist > 0.3*prev_dist)) 21689 { 21690 if (div2) div2 = 0; 21691 s1772_set_order(2); 21692 /* if (debug_flag) printf("\n order-2 ");*/ 21693 } 21694 else if (order && !g_dir) 21695 { 21696 if (sing) goto singular; 21697 if (div2) div2 = 0; 21698 s1772_set_order(1); 21699 /* if (debug_flag) printf("\n order-1 "); */ 21700 } 21701 else 21702 { 21703 if (sing) sing = 0; 21704 break; 21705 } 21706 } 21707 } 21708 21709 if (corr) 21710 if (!(p_dir && g_dir)) corr = 0; 21711 21712 if (dist < prev_dist) 21713 { 21714 if (div2) div2 = 0; 21715 21716 /* Corrigate if we are not inside the parameter intervall. */ 21717 21718 g_up = ng_up; 21719 s1772_copy3(d,c_d,nc_d,3); 21720 s1772_s9corr(d,par_val, astart1,aend1,estart2,eend2,&corr); 21721 prev_dist = dist; 21722 s1772_copy2(prev_diff,diff,dim); 21723 21724 /* Testing */ 21725 /* if (quick && corr > 3) break; */ 21726 if (corr > 3) break; 21727 } 21728 else if ( corr > 3 || 21729 ((fabs(d[0]/delta[0]) <= REL_COMP_RES) && 21730 (fabs(d[1]/delta[1]) <= REL_COMP_RES) && 21731 (fabs(d[2]/delta[2]) <= REL_COMP_RES))) break; 21732 else 21733 { 21734 /* Not converging, corrigate and try again. */ 21735 /* if (debug_flag) printf(" *h*:%d ",knbit);*/ 21736 21737 if (corr) corr++; 21738 if (dist > prev_dist && div2) break; 21739 div2++; 21740 s1772_decr2(par_val,d,3); 21741 d[0] /= 2; d[1] /= 2; d[2] /= 2; 21742 } 21743 } 21744 21745 /* Iteration stopped, test if point found is within resolution */ 21746 21747 goto not_singular; 21748 21749 singular: 21750 21751 /* if (!quick && dist > aepsge) */ 21752 if (dist > aepsge) 21753 { 21754 ki = s1772_s6local_pretop(dist,diff,norm,c0,c_t,c_tt, 21755 s0,s_u,s_v,s_uu,s_uv,s_vv,dim,&kstat); 21756 if (kstat < 0) goto error; 21757 if (ki == 0) 21758 { 21759 s1772_s6sekant1(pcurve,psurf,par_val,c_d[2],&dist,aepsge, 21760 astart1,estart2,aend1,eend2,c0,s0,norm,&kstat); 21761 if (kstat < 0) goto error; 21762 } 21763 } 21764 21765 not_singular: 21766 if (dist <= aepsge) 21767 { 21768 /* if (debug_flag) printf("\n FOUND: %d dist = %g",knbit,dist); */ 21769 21770 *jstat = 1; 21771 } 21772 else 21773 { 21774 /*if (debug_flag) printf("\n no: %d dist = %g",knbit,dist);*/ 21775 21776 s6crss(s_u,s_v,norm); 21777 if ((PIHALF-s6ang(c_t,norm,dim)) < ANGULAR_TOLERANCE) 21778 *jstat = 3; 21779 else 21780 *jstat = 2; 21781 } 21782 21783 /* if (knbit > 25) 21784 if (debug_flag) printf("\n *****status: %d dist: %f \tknbit: %d", 21785 *jstat,dist,knbit); */ 21786 21787 *cpos1 = par_val[2]; 21788 gpos2[0] = par_val[0]; 21789 gpos2[1] = par_val[1]; 21790 21791 /* Iteration completed. */ 21792 21793 goto out; 21794 21795 /* Error in allocation */ 21796 21797 err101: 21798 *jstat = -101; 21799 s6err("s1772",*jstat,kpos); 21800 goto out; 21801 21802 /* Error in input. Conflicting dimensions. */ 21803 21804 err106: 21805 *jstat = -106; 21806 s6err("s1772",*jstat,kpos); 21807 goto out; 21808 21809 /* Error in lower level routine. */ 21810 21811 error : 21812 *jstat = kstat; 21813 s6err("s1772",*jstat,kpos); 21814 goto out; 21815 21816 out: 21817 if (c0 != local && c0 != SISL_NULL) freearray(c0); 21818 } 21819 21820 21821 //=========================================================================== 21822 void s1172_s9dir(double *cdiff,double evals[]) 21823 //=========================================================================== 21824 { 21825 double a,b,c,d,d1,d2; 21826 21827 a = evals[3]; 21828 b = evals[2]; 21829 c = b*b - 2.0*a*evals[1]; 21830 21831 if (fabs(b) > DZERO) d = -evals[1]/b; 21832 else d = 0.0; 21833 21834 21835 if (c < DZERO) *cdiff = d; 21836 else if (fabs(a) > DZERO) 21837 { 21838 c = sqrt(c); 21839 d1 = (-b + c)/a; 21840 d2 = (-b - c)/a; 21841 if (DEQUAL(b,c)) *cdiff = d; 21842 else 21843 if (fabs(d1-d) < fabs(d2-d)) *cdiff = d1; 21844 else *cdiff = d2; 21845 } 21846 else *cdiff = d; 21847 } 21848 21849 //=========================================================================== 21850 void s1172_s9corr(double *cd, double acoef,double astart,double aend) 21851 //=========================================================================== 21852 { 21853 if (acoef + *cd < astart) *cd = astart - acoef; 21854 else if (acoef + *cd > aend) *cd = aend - acoef; 21855 } 21856 21857 21858 //=========================================================================== 21859 void s1172(SISLCurve *pcurve,double astart, 21860 double aend, double anext, double *cpos,int *jstat) 21861 //=========================================================================== 21862 { 21863 int kstat = 0; /* Local status variable. */ 21864 int kpos = 0; /* Position of error. */ 21865 int kleft=0; /* Variables used in the evaluator. */ 21866 int kder=3; /* Order of derivatives to be calulated */ 21867 int knbit; /* Number of iterations */ 21868 int kdir; /* Changing direction. */ 21869 double tdelta; /* Parameter intervals of the Curve. */ 21870 double tdist; /* Euclidian norm of derivative vector */ 21871 double tprev; /* Previous Euclidian norm of derivative vector*/ 21872 double td,t1,tdn; /* Distances between old and new parameter 21873 value in the two parameter directions. */ 21874 double sval[4]; /* Value ,first and second derivatiev of Curve.*/ 21875 double tnext; /* Parameter values */ 21876 double tol = (double)1000.0*REL_COMP_RES; /* Singularity tolerance */ 21877 /* --------------------------------------------------------------------- */ 21878 21879 /* Test input. */ 21880 if (pcurve->idim != 1) goto err106; 21881 21882 /* Fetch endpoints and the interval of parameter interval of curves. */ 21883 21884 tdelta = pcurve->et[pcurve->in] - pcurve->et[pcurve->ik - 1]; 21885 21886 /* Evaluate 0-2.st derivatives of curve */ 21887 s1221(pcurve,kder,anext,&kleft,sval,&kstat); 21888 if (kstat < 0) goto error; 21889 21890 /* Get Euclidian norm of derivative */ 21891 tprev = fabs(sval[1]); 21892 21893 /* Compute the Newton stepdistanse vector. */ 21894 s1172_s9dir(&td,sval); 21895 21896 /* Adjust if we are not inside the parameter intervall. */ 21897 t1 = td; 21898 s1172_s9corr(&t1,anext,astart,aend); 21899 21900 /* Iterate to find the intersection point. */ 21901 21902 for (knbit = 0; knbit < 50; knbit++) 21903 { 21904 /* Evaluate 0-3.st derivatives of curve */ 21905 21906 tnext = anext + t1; 21907 21908 s1221(pcurve,kder,tnext,&kleft,sval,&kstat); 21909 if (kstat < 0) goto error; 21910 21911 /* Get Euclidian norm of derivative */ 21912 tdist = fabs(sval[1]); 21913 21914 /* Compute the Newton stepdistanse vector. */ 21915 s1172_s9dir(&tdn,sval); 21916 21917 /* Check if the direction of the step have change. */ 21918 21919 kdir = (td*tdn >= DZERO); /* 0 if changed. */ 21920 21921 if (tdist <= tprev || kdir) 21922 { 21923 /* Ordinary converging. */ 21924 21925 anext += t1; 21926 21927 td = t1 = tdn; 21928 21929 /* Adjust if we are not inside the parameter intervall. */ 21930 s1172_s9corr(&t1,anext,astart,aend); 21931 21932 21933 if (fabs(t1/tdelta) <= REL_COMP_RES) 21934 { 21935 anext += t1; 21936 break; 21937 } 21938 21939 tprev = tdist; 21940 } 21941 21942 else 21943 { 21944 /* Not converging, half step length try again. */ 21945 21946 t1 /= (double)2; 21947 /* knbit--; */ 21948 } 21949 } 21950 21951 /* Iteration stopped, test if point is extremum */ 21952 21953 if (tdist <= tol) 21954 *jstat = 1; 21955 else 21956 *jstat = 0; 21957 21958 21959 /* Test if the iteration is close to a knot */ 21960 if (fabs(anext - pcurve->et[kleft])/tdelta < tol) 21961 anext = pcurve->et[kleft]; 21962 else if (fabs(anext - pcurve->et[kleft+1])/tdelta < tol) 21963 anext = pcurve->et[kleft+1]; 21964 21965 /* Uppdate output. */ 21966 *cpos = anext; 21967 21968 /* Iteration completed. */ 21969 goto out; 21970 21971 /* --------------------------------------------------------------------- */ 21972 /* Error in input. Dimension not equal to 1 */ 21973 err106: *jstat = -106; 21974 s6err("s1172",*jstat,kpos); 21975 goto out; 21976 21977 /* Error in lower level routine. */ 21978 error : *jstat = kstat; 21979 s6err("s1172",*jstat,kpos); 21980 goto out; 21981 21982 out:; 21983 } 21984 21985 21986 //=========================================================================== 21987 int sh6nmbhelp(SISLIntpt *pt,int *jstat) 21988 //=========================================================================== 21989 { 21990 int num; /* Number of lists. */ 21991 int ki; /* Loop variable. */ 21992 21993 num=0; 21994 21995 /* Count number of main lists pt lies in. */ 21996 21997 for(ki=0; ki<pt->no_of_curves; ki++) 21998 { 21999 if(pt->pnext[ki] == SISL_NULL) goto err1; 22000 if(sh6ishelp(pt->pnext[ki])) num++; 22001 } 22002 22003 goto out; 22004 22005 22006 err1: 22007 /* Error in data structure. */ 22008 22009 *jstat = -1; 22010 s6err("sh6nmbhelp",*jstat,0); 22011 goto out; 22012 22013 22014 out : 22015 return num; 22016 } 22017 22018 //=========================================================================== 22019 int s1791(double et[],int ik,int in) 22020 //=========================================================================== 22021 { 22022 register double tstart= et[ik - 1]; 22023 register double tend = et[in]; 22024 register double tmid = (tstart+tend)*(double)0.5; 22025 22026 /* Check if it is possible to divide the parameter interval. */ 22027 22028 if (DEQUAL(tmid,tstart) || DEQUAL(tmid,tend)) 22029 return 0; 22030 else 22031 return 1; 22032 } 22033 22034 //=========================================================================== 22035 void sh6setdir(SISLIntpt *pt1,SISLIntpt *pt2,int *jstat) 22036 //=========================================================================== 22037 { 22038 int kstat; /* error flag. */ 22039 int index1,index2; /* dummy indices. */ 22040 22041 *jstat = 0; 22042 22043 /* Check if pt1 and pt2 are already connected. */ 22044 22045 sh6getlist(pt1,pt2,&index1,&index2,&kstat); 22046 if(kstat < 0) goto err2; 22047 if(kstat > 1) goto err1; /* Not connected. */ 22048 22049 /* Set direction from pt1 to pt2. */ 22050 22051 pt1->curve_dir[index1] |= 1; 22052 /* pt2->curve_dir[index2] = (-1 ^ 33); */ 22053 pt2->curve_dir[index2] = -31; 22054 pt2->curve_dir[index2] |= pt1->curve_dir[index1]; 22055 22056 22057 goto out; 22058 22059 /* Points are not connected. */ 22060 err1: 22061 22062 *jstat = -1; 22063 s6err("sh6setdir",*jstat,0); 22064 goto out; 22065 22066 /* Error in subfuction. */ 22067 err2: 22068 22069 *jstat = -2; 22070 s6err("sh6setdir",*jstat,0); 22071 goto out; 22072 22073 out : 22074 return; 22075 } 22076 22077 22078 22079 //=========================================================================== 22080 void sh1784 (SISLCurve * pcurve, SISLSurf * psurf, double aepsge, 22081 double epar[], int icur, int idirc, double elast[], 22082 double enext[], int *jstat) 22083 //=========================================================================== 22084 { 22085 int kstat; /* Status variable */ 22086 int ki; /* Counter. */ 22087 int kleftc = 0; /* Left indicator for point calculation */ 22088 int kleft1 = 0; /* Left indicator for point calculation in 1. par. 22089 direction of surface. */ 22090 int kleft2 = 0; /* Left indicator for point calculation in 2. par dir.*/ 22091 int kleft1prev, kleft2prev; /* Previous left indicators of surface. */ 22092 int kn; /* The number of B-splines, i.e., the dimension of 22093 the spline space associated with the knot 22094 vector. */ 22095 int kk; /* The polynomial order of the curve. */ 22096 int kk1, kk2, kn1, kn2; /* Orders and nu,ber of vertices of surface */ 22097 int kdimc; /* The dimension of the space in which the curve 22098 lies. Equivalently, the number of components 22099 of each B-spline coefficient. */ 22100 int kdims; /* Dimension of space where the surface lies */ 22101 int kpos = 0; /* Position of error */ 22102 int kderc = 2; /* Number of derivatives to be claculated on curve */ 22103 int kders = 1; /* Number of derivatives to be calculated on surface 22104 If step lenght is to be generated from surface, 22105 kders must be equal to 2. */ 22106 int kdum; /* Temporary variable */ 22107 int kpar; /* Parameter value of constant parameter curve. */ 22108 int kiterate; /* Indicates if further iteration is necessary 22109 after curve-curve iteration. */ 22110 double tref; /* Referance value in equality test. */ 22111 double tclose1, tclose2; /* Parameter values of closest point between curves. */ 22112 double tangdot; /* Scalar product between curve tangents. */ 22113 double snorm[3]; /* Normal vector of surface */ 22114 double s3dinf1[10]; /* Pointer to storage for point info of curve 22115 (10 dobules prpoint when idim=3, 7 when idim=3) */ 22116 double *st; /* Pointer to the first element of the knot vector 22117 of the curve. The knot vector has [kn+kk] 22118 elements. */ 22119 double *st1; /* First knot direction of surface */ 22120 double *st2; /* Second knot direction of surface */ 22121 double sfirst[2]; /* Start parameter par in surface */ 22122 double tfirst; /* Fist parameter on curve */ 22123 double tend; /* Last parameter on curve */ 22124 double sderc[9]; /* Position, first and second derivative of curve */ 22125 double stangprev[3]; /* Previous tangent of curve. */ 22126 double sders[18]; /* Position, first and second derivatives of surface */ 22127 double tx, tx1, tx2; /* Parameter value */ 22128 double tstep; /* Final step length */ 22129 double tmaxinc; /* Maximal increment in parameter value along curve*/ 22130 double tlengthend; /* Length of 1st derivative at end of segment */ 22131 double tincre; /* Parameter value increment */ 22132 double tsmax, tcmax; /* Local maximal step length based of boxsizes of objects */ 22133 double tdist = DZERO; /* Distance */ 22134 double sstart[2]; /* Lower boundary of parameter intervals */ 22135 double send[2]; /* Upper bounadry of parameter intervals */ 22136 double snext[3]; /* Existing iteration point on surface */ 22137 double spos[3]; /* New iteration point on surface */ 22138 double snext2[2]; /* Help parameter values. */ 22139 SISLPoint *qpoint = SISL_NULL; 22140 SISLCurve *qc = SISL_NULL; /* Constant parameter curve. */ 22141 22142 /* Pointer to curve evaluator routine of the curve. */ 22143 22144 sh1784_fevalcProc fevalc; 22145 /* 22146 #if defined(SISLNEEDPROTOTYPES) 22147 void (*fevalc) (SISLCurve *, int, double, int *, double[], int *); 22148 #else 22149 void (*fevalc) (); 22150 #endif 22151 */ 22152 /* Make maximal step length based on box-size of surface */ 22153 22154 sh1992su (psurf, 0, aepsge, &kstat); 22155 if (kstat < 0) 22156 goto error; 22157 22158 tsmax = MAX (psurf->pbox->e2max[0][0] - psurf->pbox->e2min[0][0], 22159 psurf->pbox->e2max[0][1] - psurf->pbox->e2min[0][1]); 22160 tsmax = MAX (tsmax, psurf->pbox->e2max[0][2] - psurf->pbox->e2min[0][2]); 22161 22162 /* Make maximal step length based on box-size of curve */ 22163 22164 sh1992cu (pcurve, 0, aepsge, &kstat); 22165 if (kstat < 0) 22166 goto error; 22167 22168 tcmax = MAX (pcurve->pbox->e2max[0][0] - pcurve->pbox->e2min[0][0], 22169 pcurve->pbox->e2max[0][1] - pcurve->pbox->e2min[0][1]); 22170 tcmax = MAX (tcmax, pcurve->pbox->e2max[0][2] - pcurve->pbox->e2min[0][2]); 22171 22172 /* Copy curve attributes to local parameters. */ 22173 22174 kdimc = pcurve->idim; 22175 kk = pcurve->ik; 22176 kn = pcurve->in; 22177 st = pcurve->et; 22178 22179 /* Copy surface attributes to local parameters. */ 22180 22181 kdims = psurf->idim; 22182 kk1 = psurf->ik1; 22183 kk2 = psurf->ik2; 22184 kn1 = psurf->in1; 22185 kn2 = psurf->in2; 22186 st1 = psurf->et1; 22187 st2 = psurf->et2; 22188 22189 /* Set reference value. */ 22190 22191 tref = MAX(st[kn]-st[kk-1],MAX(st1[kn1]-st1[kk1-1],st2[kn2]-st2[kk2-1])); 22192 22193 /* Check that dimensions are 3 */ 22194 22195 if (kdimc != 3 || kdims != 3) 22196 goto err105; 22197 22198 sstart[0] = st1[kk1 - 1]; 22199 sstart[1] = st2[kk2 - 1]; 22200 send[0] = st1[kn1]; 22201 send[1] = st2[kn2]; 22202 22203 /* Copy interval description into local variables */ 22204 22205 if (icur == 1) 22206 { 22207 sfirst[0] = epar[1]; 22208 sfirst[1] = epar[2]; 22209 tfirst = epar[0]; 22210 tend = (idirc == 1) ? st[kn] : st[kk - 1]; 22211 } 22212 else 22213 { 22214 sfirst[0] = epar[0]; 22215 sfirst[1] = epar[1]; 22216 tfirst = epar[2]; 22217 tend = (idirc == 1) ? st[kn] : st[kk - 1]; 22218 } 22219 22220 /* To make sure we do not start outside or end outside the curve we 22221 truncate tfirst to the knot interval of the curve */ 22222 22223 tfirst = (idirc == 1) ? MAX (tfirst, st[kk - 1]) : MIN (tfirst, st[kn]); 22224 22225 /* Set start point of iteration on surface */ 22226 22227 spos[0] = sfirst[0]; 22228 spos[1] = sfirst[1]; 22229 22230 /* Set curve evaluator of the curve. */ 22231 22232 fevalc = (idirc == 1) ? s1221 : s1227; 22233 22234 /* Store knot values at start of curve */ 22235 22236 tx2 = tfirst; 22237 kdum = MAX (kk1, kk2); 22238 kdum = MAX (kdum, kk); 22239 tmaxinc = fabs (tend - tfirst) / (kdum * kdum); 22240 22241 /* Make start point of curve */ 22242 22243 fevalc (pcurve, kderc, tx2, &kleftc, sderc, &kstat); 22244 if (kstat < 0) goto error; 22245 22246 /* Make start point of surface. */ 22247 22248 s1421 (psurf, kders, spos, &kleft1, &kleft2, sders, snorm, &kstat); 22249 if (kstat < 0) goto error; 22250 22251 /* While end not reached */ 22252 22253 while (idirc * tx2 < idirc * tend) 22254 { 22255 /* Save parameters of previous step. */ 22256 22257 tx1 = tx2; 22258 snext[0] = spos[0]; 22259 snext[1] = spos[1]; 22260 kleft1prev = kleft1; 22261 kleft2prev = kleft2; 22262 22263 /* Calculate unit tangent and radius of curvature of curve. */ 22264 22265 s1307 (sderc, kdimc, s3dinf1, &kstat); 22266 if (kstat < 0) 22267 goto error; 22268 22269 /* Calculate step length based on curvature */ 22270 22271 tstep = s1311 (s3dinf1[3 * kdimc], aepsge, tsmax, &kstat); 22272 if (kstat < 0) 22273 goto error; 22274 22275 /* Remember length of start tangent, end of zero segment */ 22276 22277 tlengthend = s6length (sderc + kdimc, kdimc, &kstat); 22278 if (kstat < 0) 22279 goto error; 22280 22281 22282 /* Find candidate end point, make sure that no breaks in tangent or 22283 curvature exists between start and endpoints of the segment */ 22284 /* Make step length equal to resolution if the length is zero */ 22285 22286 if (DEQUAL (tlengthend, DZERO)) 22287 tincre = REL_PAR_RES; 22288 else 22289 tincre = tstep / tlengthend; 22290 22291 tincre = MIN (tincre, tmaxinc); 22292 22293 /* Make sure that we don't pass any knots of the curve. */ 22294 22295 if (idirc * (tx1 + tincre) > idirc * (st[kleftc + idirc] + REL_PAR_RES)) 22296 tincre = idirc * (st[kleftc + idirc] - tx1); 22297 22298 if (idirc < 0 && (tx1 - tincre < st[kleftc] - REL_PAR_RES)) 22299 tincre = idirc * (st[kleftc] - tx1); 22300 22301 /* Find parameter value of candidate end point of segment */ 22302 22303 tx2 = tx1 + idirc * tincre; 22304 22305 for (ki = 0, tx = (tx1 + tx2) / (double) 2.0; ki < 2; ki++, tx = tx2) 22306 { 22307 if (idirc * tx >= idirc * tend) 22308 break; 22309 22310 /* Make point sderc at curve at tx */ 22311 22312 fevalc (pcurve, kderc, tx, &kleftc, sderc, &kstat); 22313 if (kstat < 0) goto error; 22314 22315 /* Test if the step is legal. */ 22316 22317 if (DNEQUAL(tx1,tfirst) || ki>0) 22318 { 22319 tangdot = s6scpr(stangprev, sderc+kdimc, kdimc); 22320 while (tangdot < DZERO) 22321 { 22322 /* The step is not legal. Reduce step length. */ 22323 22324 if (ki == 0) 22325 { 22326 tx2 = tx; 22327 tx = (tx1 + tx2)/(double)2.0; 22328 } 22329 else 22330 { 22331 tx2 = tx1 + (double)0.75*(tx2-tx1); 22332 tx = tx2; 22333 } 22334 22335 /* Make point sderc at curve at tx */ 22336 22337 fevalc (pcurve, kderc, tx, &kleftc, sderc, &kstat); 22338 if (kstat < 0) goto error; 22339 22340 tangdot = s6scpr(stangprev, sderc+kdimc, kdimc); 22341 } 22342 } 22343 /* Find closest point on surface to sderc */ 22344 22345 qpoint = newPoint (sderc, kdimc, 0); 22346 if (qpoint == SISL_NULL) 22347 goto err101; 22348 22349 snext2[0] = snext[0]; 22350 snext2[1] = snext[1]; 22351 s1773 (qpoint, psurf, aepsge, sstart, send, snext2, spos, &kstat); 22352 if (kstat < 0) 22353 goto error; 22354 22355 freePoint (qpoint); 22356 qpoint = SISL_NULL; 22357 22358 /* Check to see if we have crossed an edge of the 22359 surface, i.e. we have gone outside the parameter 22360 area for psurf. */ 22361 22362 if(spos[0] <= st1[kk1-1] || spos[0] >= st1[kn1] || 22363 spos[1] <= st2[kk2-1] || spos[1] >= st2[kn2]) 22364 { 22365 /* Coincidence! Finish with a message. */ 22366 goto edge_of_surf; 22367 } 22368 22369 /* Calculate point and derivatives in surface */ 22370 22371 s1421 (psurf, kders, spos, &kleft1, &kleft2, sders, snorm, &kstat); 22372 if (kstat < 0) 22373 goto error; 22374 22375 /* Check if point on curve and surface are within positional and 22376 angular tolerances */ 22377 22378 tdist = s6dist (sderc, sders, kdimc); 22379 22380 if (tdist > aepsge) 22381 { 22382 /* Points not within tolerances, curve and surface do not 22383 coincide */ 22384 goto no_coin; 22385 } 22386 22387 /* Check if any parameter lines of the surface is crossed in the 1. 22388 parameter direction. */ 22389 22390 if (kleft1 != kleft1prev && 22391 ((DNEQUAL(spos[0]+tref,st1[kleft1]+tref) && 22392 DNEQUAL(snext[0]+tref,st1[kleft1]+tref)) || 22393 kleft1 != kleft1prev+1) && 22394 ((DNEQUAL(snext[0]+tref,st1[kleft1prev]+tref) && 22395 DNEQUAL(spos[0]+tref,st1[kleft1prev]+tref)) || 22396 kleft1 != kleft1prev - 1)) 22397 { 22398 /* At least one parameter line is crossed. Fetch the constant parameter 22399 curve at the closest parameter line in the direction of the marching. */ 22400 22401 if (kleft1 > kleft1prev) 22402 kpar = kleft1prev + 1; 22403 else if (snext[0] != st1[kleft1prev]) 22404 kpar = kleft1prev; 22405 else 22406 kpar = kleft1prev - 1; 22407 22408 /* Pick constant parameter curve. */ 22409 22410 s1437 (psurf, st1[kpar], &qc, &kstat); 22411 if (kstat < 0) 22412 goto error; 22413 22414 /* Find the closest point between the input curve and the constant 22415 parameter curve. */ 22416 22417 /* UJK Oct 91, Nice trap ! tx1 > tx */ 22418 /* s1770 (pcurve, qc, aepsge, tx1, st2[kk2 - 1], tx, st2[kn2], (tx1 + tx) / (double) 2.0, 22419 st2[kleft2], &tclose1, &tclose2, &kstat); */ 22420 s1770 (pcurve, qc, aepsge, min(tx1,tx), st2[kk2 - 1], max(tx1,tx), 22421 st2[kn2], (tx1 + tx) / (double) 2.0, 22422 (double)0.5*(st2[kleft2]+st2[kleft2+1]), 22423 &tclose1, &tclose2, &kstat); 22424 if (kstat < 0) 22425 goto error; 22426 22427 if (kstat == 2 || fabs(tclose1-tx1) < REL_PAR_RES) 22428 /* No intersection point is found. Mark that surface-point 22429 iteration is necessary. */ 22430 22431 kiterate = 1; 22432 else kiterate = 0; 22433 22434 /* Set new parameter values to the iteration. */ 22435 22436 spos[0] = st1[kpar]; 22437 spos[1] = tclose2; 22438 if (fabs(tclose1-tx1) > REL_PAR_RES) tx2 = tclose1; 22439 22440 /* Test midpoint of reduced step. First evaluate curve in midpoint. */ 22441 22442 tx = (tx1 + tx2) / (double) 2.0; 22443 22444 fevalc (pcurve, kderc, tx, &kleftc, sderc, &kstat); 22445 if (kstat < 0) goto error; 22446 22447 /* Find closest point on surface to sderc */ 22448 22449 qpoint = newPoint (sderc, kdimc, 0); 22450 if (qpoint == SISL_NULL) 22451 goto err101; 22452 22453 snext2[0] = snext[0]; 22454 snext2[1] = snext[1]; 22455 s1773 (qpoint, psurf, aepsge, sstart, send, snext2, snext2, &kstat); 22456 if (kstat < 0) 22457 goto error; 22458 22459 freePoint (qpoint); 22460 qpoint = SISL_NULL; 22461 22462 /* Calculate point and derivatives in surface */ 22463 22464 s1421 (psurf, kders, snext2, &kleft1, &kleft2, sders, snorm, &kstat); 22465 if (kstat < 0) 22466 goto error; 22467 22468 /* Check if point on curve and surface are within positional and 22469 angular tolerances */ 22470 22471 tdist = s6dist (sderc, sders, kdimc); 22472 22473 if (tdist > aepsge) 22474 { 22475 /* Points not within tolerances, curve and surface do not 22476 coincide */ 22477 goto no_coin; 22478 } 22479 22480 /* Calculate point and derivatives in the curve in the endpoint of the step. */ 22481 22482 fevalc (pcurve, kderc, tx2, &kleftc, sderc, &kstat); 22483 if (kstat < 0) goto error; 22484 22485 if (kiterate) 22486 { 22487 /* Relax the point on the curve down to the surface. */ 22488 22489 qpoint = newPoint (sderc, kdimc, 0); 22490 if (qpoint == SISL_NULL) 22491 goto err101; 22492 22493 spos[0] = snext2[0]; 22494 spos[1] = snext2[1]; 22495 s1773 (qpoint, psurf, aepsge, sstart, send, spos, spos, &kstat); 22496 if (kstat < 0) 22497 goto error; 22498 22499 freePoint (qpoint); 22500 qpoint = SISL_NULL; 22501 } 22502 22503 /* Calculate point and derivatives in the surface. */ 22504 22505 s1421 (psurf, kders, spos, &kleft1, &kleft2, sders, snorm, &kstat); 22506 if (kstat < 0) 22507 goto error; 22508 22509 /* Check if point on curve and surface are within positional and 22510 angular tolerances */ 22511 22512 tdist = s6dist (sderc, sders, kdimc); 22513 22514 if (tdist > aepsge) 22515 { 22516 /* Points not within tolerances, curve and surface do not 22517 coincide */ 22518 goto no_coin; 22519 } 22520 22521 /* Mark that a new step is to be initiated. */ 22522 22523 ki = 2; 22524 22525 /* Free constant parameter curve. */ 22526 22527 if (qc != SISL_NULL) 22528 freeCurve (qc); 22529 qc = SISL_NULL; 22530 } 22531 22532 /* Check if any parameter lines of the surface is crossed in the 2. 22533 parameter direction. */ 22534 22535 if (kleft2 != kleft2prev && 22536 ((DNEQUAL(spos[1]+tref,st2[kleft2]+tref) && 22537 DNEQUAL(snext[1]+tref,st2[kleft2]+tref)) || 22538 kleft2 != kleft2prev+1) && 22539 ((DNEQUAL(snext[1]+tref,st2[kleft2prev]+tref) && 22540 DNEQUAL(spos[1]+tref,st2[kleft2prev]+tref)) || 22541 kleft2 != kleft2prev - 1)) 22542 { 22543 /* At least one parameter line is crossed. Fetch the constant parameter 22544 curve at the closest parameter line in the direction of the marching. */ 22545 22546 if (kleft2 > kleft2prev) 22547 kpar = kleft2prev + 1; 22548 else if (snext[1] != st2[kleft2prev]) 22549 kpar = kleft2prev; 22550 else 22551 kpar = kleft2prev - 1; 22552 22553 /* Pick constant parameter curve. */ 22554 22555 s1436 (psurf, st2[kpar], &qc, &kstat); 22556 if (kstat < 0) 22557 goto error; 22558 22559 /* Find the closest point between the input curve and the constant 22560 parameter curve. */ 22561 22562 /* UJK Oct 91, Nice trap ! tx1 > tx */ 22563 s1770 (pcurve, qc, aepsge, min(tx1,tx), st1[kk1 - 1], max(tx,tx1), 22564 st1[kn1], (tx1 + tx) / (double) 2.0, 22565 (double)0.5*(st1[kleft1]+st1[kleft1+1]), 22566 &tclose1, &tclose2, &kstat); 22567 if (kstat < 0) 22568 goto error; 22569 22570 if (kstat == 2 || fabs(tclose1-tx1) < REL_PAR_RES) 22571 /* No intersection point is found. Mark that surface-point 22572 iteration is necessary. */ 22573 22574 kiterate = 1; 22575 else kiterate = 0; 22576 22577 /* Set new parameter values to the iteration. */ 22578 22579 spos[0] = tclose2; 22580 spos[1] = st2[kpar]; 22581 if (fabs(tclose1-tx1) > REL_PAR_RES) tx2 = tclose1; 22582 22583 /* Test midpoint of reduced step. First evaluate curve in midpoint. */ 22584 22585 tx = (tx1 + tx2) / (double) 2.0; 22586 22587 fevalc (pcurve, kderc, tx, &kleftc, sderc, &kstat); 22588 if (kstat < 0) goto error; 22589 22590 /* Find closest point on surface to sderc */ 22591 22592 qpoint = newPoint (sderc, kdimc, 0); 22593 if (qpoint == SISL_NULL) 22594 goto err101; 22595 22596 snext2[0] = snext[0]; 22597 snext2[1] = snext[1]; 22598 s1773 (qpoint, psurf, aepsge, sstart, send, snext2, snext2, &kstat); 22599 if (kstat < 0) 22600 goto error; 22601 22602 freePoint (qpoint); 22603 qpoint = SISL_NULL; 22604 22605 /* Calculate point and derivatives in surface */ 22606 22607 s1421 (psurf, kders, snext2, &kleft1, &kleft2, sders, snorm, &kstat); 22608 if (kstat < 0) 22609 goto error; 22610 22611 /* Check if point on curve and surface are within positional and 22612 angular tolerances */ 22613 22614 tdist = s6dist (sderc, sders, kdimc); 22615 22616 if (tdist > aepsge) 22617 { 22618 /* Points not within tolerances, curve and surface do not 22619 coincide */ 22620 goto no_coin; 22621 } 22622 22623 /* Calculate point and derivatives in the curve. */ 22624 22625 fevalc (pcurve, kderc, tx2, &kleftc, sderc, &kstat); 22626 if (kstat < 0) goto error; 22627 22628 if (kiterate) 22629 { 22630 /* Relax the point on the curve down to the surface. */ 22631 22632 qpoint = newPoint (sderc, kdimc, 0); 22633 if (qpoint == SISL_NULL) 22634 goto err101; 22635 22636 spos[0] = snext2[0]; 22637 spos[1] = snext2[1]; 22638 s1773 (qpoint, psurf, aepsge, sstart, send, spos, spos, &kstat); 22639 if (kstat < 0) 22640 goto error; 22641 22642 freePoint (qpoint); 22643 qpoint = SISL_NULL; 22644 } 22645 22646 22647 /* Calculate point and derivatives in the surface. */ 22648 22649 s1421 (psurf, kders, spos, &kleft1, &kleft2, sders, snorm, &kstat); 22650 if (kstat < 0) 22651 goto error; 22652 22653 /* Check if point on curve and surface are within positional and 22654 angular tolerances */ 22655 22656 tdist = s6dist (sderc, sders, kdimc); 22657 22658 if (tdist > aepsge) 22659 { 22660 /* Points not within tolerances, curve and surface do not 22661 coincide */ 22662 goto no_coin; 22663 } 22664 22665 /* Mark that a new step is to be initiated. */ 22666 22667 ki = 2; 22668 22669 /* Free constant parameter curve. */ 22670 22671 if (qc != SISL_NULL) 22672 freeCurve (qc); 22673 qc = SISL_NULL; 22674 } 22675 22676 /* Save tangent of curve. */ 22677 22678 memcopy(stangprev, sderc+kdimc, kdimc, DOUBLE); 22679 } 22680 } 22681 22682 /* Coincidence interval along complete curve. */ 22683 22684 *jstat = 1; 22685 if (icur == 1) 22686 { 22687 elast[0] = tx1; 22688 elast[1] = snext[0]; 22689 elast[2] = snext[1]; 22690 } 22691 else 22692 { 22693 elast[0] = snext[0]; 22694 elast[1] = snext[1]; 22695 elast[2] = tx1; 22696 } 22697 goto out; 22698 22699 /* Curve and surface not within tolerance */ 22700 no_coin:*jstat = 0; 22701 if (icur == 1) 22702 { 22703 elast[0] = tx1; 22704 elast[1] = snext[0]; 22705 elast[2] = snext[1]; 22706 enext[0] = tx2; 22707 enext[1] = spos[0]; 22708 enext[2] = spos[1]; 22709 } 22710 else 22711 { 22712 elast[0] = snext[0]; 22713 elast[1] = snext[1]; 22714 elast[2] = tx1; 22715 enext[0] = spos[0]; 22716 enext[1] = spos[1]; 22717 enext[2] = tx2; 22718 } 22719 goto out; 22720 22721 /* Curve and surface are within tolerance up to an edge 22722 of the surface. */ 22723 edge_of_surf: 22724 *jstat = 2; 22725 if (icur == 1) 22726 { 22727 elast[0] = tx1; 22728 elast[1] = snext[0]; 22729 elast[2] = snext[1]; 22730 enext[0] = tx2; 22731 enext[1] = spos[0]; 22732 enext[2] = spos[1]; 22733 } 22734 else 22735 { 22736 elast[0] = snext[0]; 22737 elast[1] = snext[1]; 22738 elast[2] = tx1; 22739 enext[0] = spos[0]; 22740 enext[1] = spos[1]; 22741 enext[2] = tx2; 22742 } 22743 goto out; 22744 22745 /* Error in memory allocation */ 22746 22747 err101:*jstat = -101; 22748 s6err ("sh1784", *jstat, kpos); 22749 goto out; 22750 22751 /* Error in input, dimension not equal to 2 or 3 */ 22752 22753 err105:*jstat = -105; 22754 s6err ("sh1784", *jstat, kpos); 22755 goto out; 22756 22757 /* Error in lower level function */ 22758 22759 error:*jstat = kstat; 22760 s6err ("sh1784", *jstat, kpos); 22761 goto out; 22762 22763 22764 out: 22765 22766 return; 22767 } 22768 22769 22770 //=========================================================================== 22771 void sh1779 (SISLObject * po1, SISLObject * po2, double aepsge, 22772 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, int *jstat) 22773 //=========================================================================== 22774 { 22775 int kstat = 0; /* Status variable. */ 22776 int ki; /* Counters. */ 22777 int kleft1 = 0, kleft2 = 0; /* Parameters to the evaluator. */ 22778 int kdim; /* Dimension of geometry space. */ 22779 int kpos = 0; /* Current position in int.pt. array. */ 22780 int kpar1, kpar2; /* Index of parameter value of object. */ 22781 int kn; /* Number of vertices of curve. */ 22782 int kk; /* Order of curve. */ 22783 int kmarch = 0; /* Indicates if marching is necessary. */ 22784 int lleft[2]; /* Array storing pre-topology information. */ 22785 int lright[2]; /* Array storing pre-topology information. */ 22786 int *ll1, *ll2, *lr1, *lr2; /* Pointers into pre-topology arrays. */ 22787 double tref; /* Referance value in equality test. */ 22788 double *st; /* Knot vector of curve. */ 22789 double sder[9]; /* Result of curve evaluation. */ 22790 double stang[3]; /* Tangent vector of curve. */ 22791 double snorm[3]; /* Normal vector of surface. */ 22792 double slast[3]; /* Last parameter value of coincidence. */ 22793 double snext[3]; /* First parameter value outside interval 22794 of coincidence. */ 22795 double *ret_val; /* Pointer to geo data from sh6getgeom */ 22796 double *ret_norm; /* Pointer to geo data from sh6getgeom */ 22797 double *sptpar = pintpt->epar;/* Pointer to parameter values of int.pt. */ 22798 SISLCurve *qc; /* Pointer to the curve. */ 22799 SISLSurf *qs; /* Pointer to the surface. */ 22800 SISLIntpt *uintpt[2]; /* Array containing new intersection points. */ 22801 SISLIntpt *qpt1, *qpt2; /* Intersection points in list. */ 22802 double *nullp = SISL_NULL; 22803 double sf_low_lim[2]; 22804 double sf_high_lim[2]; 22805 22806 /* Don't make pretop for help points ! */ 22807 if (sh6ishelp (pintpt)) 22808 { 22809 *jstat = 0; 22810 goto out; 22811 } 22812 22813 /* Set pointers into the arrays storing pre-topology information. */ 22814 22815 if (po1->iobj == SISLCURVE) 22816 { 22817 qc = po1->c1; 22818 qs = po2->s1; 22819 22820 kpar1 = 0; 22821 kpar2 = 1; 22822 ll1 = lleft; 22823 lr1 = lright; 22824 ll2 = lleft + 1; 22825 lr2 = lright + 1; 22826 } 22827 else 22828 { 22829 qc = po2->c1; 22830 qs = po1->s1; 22831 22832 kpar1 = 2; 22833 kpar2 = 0; 22834 ll1 = lleft + 1; 22835 lr1 = lright + 1; 22836 ll2 = lleft; 22837 lr2 = lright; 22838 } 22839 22840 /* Get pre-topology of intersection point. */ 22841 sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat); 22842 22843 /* Describe curve partly by local parameters. */ 22844 22845 kdim = qc->idim; 22846 kk = qc->ik; 22847 kn = qc->in; 22848 st = qc->et; 22849 tref = st[kn] - st[kk - 1]; 22850 22851 sf_low_lim[0] = qs->et1[qs->ik1 - 1] + REL_COMP_RES; 22852 sf_low_lim[1] = qs->et2[qs->ik2 - 1] + REL_COMP_RES; 22853 sf_high_lim[0] = qs->et1[qs->in1] - REL_COMP_RES; 22854 sf_high_lim[1] = qs->et2[qs->in2] - REL_COMP_RES; 22855 22856 /* Fetch geometry information, curve. */ 22857 sh6getgeom ((po1->iobj == SISLCURVE) ? po1 : po2, 22858 (po1->iobj == SISLCURVE) ? 1 : 2, 22859 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 22860 if (kstat < 0) 22861 goto error; 22862 22863 /* Local copy of curve tangent */ 22864 memcopy (stang, ret_val + kdim, kdim, DOUBLE); 22865 22866 /* Fetch geometry information, surface. */ 22867 sh6getgeom ((po1->iobj == SISLSURFACE) ? po1 : po2, 22868 (po1->iobj == SISLSURFACE) ? 1 : 2, 22869 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 22870 if (kstat < 0) 22871 goto error; 22872 22873 /* Local copy of surface normal */ 22874 memcopy (snorm, ret_norm, kdim, DOUBLE); 22875 22876 22877 /* (ALA) Test if local information may be used to compute pre-topology. */ 22878 s6length (snorm, kdim, &kstat); 22879 s6length (snorm, kdim, &ki); 22880 22881 if (!kstat || !ki || fabs (PIHALF - s6ang (snorm, stang, kdim)) < 0.05) 22882 { 22883 /* Check if the intersection point lies at the start point of 22884 the curve. */ 22885 22886 if (DEQUAL (sptpar[kpar1] + tref, st[kn] + tref)) 22887 ; 22888 else 22889 { 22890 /* Check if the intersection point is member of a list 22891 in this parameter direction of the curve. */ 22892 22893 qpt1 = qpt2 = SISL_NULL; 22894 kmarch = 1; 22895 22896 /* UPDATE (ujk) : only one list ? */ 22897 sh6getnhbrs (pintpt, &qpt1, &qpt2, &kstat); 22898 if (kstat < 0) 22899 goto error; 22900 22901 kmarch = 0; 22902 if (qpt1 != SISL_NULL && qpt1->epar[kpar1] > sptpar[kpar1]) 22903 *lr1 = SI_ON; 22904 else if (qpt2 != SISL_NULL && qpt2->epar[kpar1] > sptpar[kpar1]) 22905 *lr1 = SI_ON; 22906 else 22907 kmarch = 1; 22908 } 22909 22910 if (kmarch) 22911 { 22912 /* Perform marching to compute pre-topology. March first in the 22913 positive direction of the curve. */ 22914 22915 sh1784 (qc, qs, aepsge, sptpar, (kpar1 == 0), 1, slast, snext, &kstat); 22916 if (kstat < 0) 22917 goto error; 22918 22919 if (kstat == 1) 22920 { 22921 /* The endpoint of the curve is reached. */ 22922 ; 22923 } 22924 else if (kstat == 2) 22925 ; 22926 else 22927 { 22928 22929 if (slast[kpar2] > sf_high_lim[0] || 22930 slast[kpar2 + 1] > sf_high_lim[1] || 22931 slast[kpar2] < sf_low_lim[0] || 22932 slast[kpar2 + 1] < sf_low_lim[1]) 22933 ; 22934 else 22935 { 22936 22937 22938 /* Create help point. First fetch geometry information. */ 22939 22940 s1221 (qc, 0, slast[kpar1], &kleft1, sder, &kstat); 22941 if (kstat < 0) 22942 goto error; 22943 22944 s1221 (qc, 0, snext[kpar1], &kleft1, sder + kdim, &kstat); 22945 if (kstat < 0) 22946 goto error; 22947 s6diff (sder + kdim, sder, kdim, stang); 22948 22949 s1421 (qs, 1, slast + kpar2, &kleft1, &kleft2, sder, snorm, &kstat); 22950 if (kstat < 0) 22951 goto error; 22952 22953 /* Discuss tangent- and normal vector, and set up pre-topology 22954 in one direction of the curve. */ 22955 22956 if (s6scpr (snorm, stang, kdim) > DZERO) 22957 *lr1 = SI_OUT; 22958 else 22959 *lr1 = SI_IN; 22960 22961 /* UPDATE (ujk) : Tuning on distance */ 22962 if (s6dist (sptpar, slast, 3) > (double) 0.05 * tref) 22963 { 22964 /* Create help point. Set pre-topology data as undefined. */ 22965 /* UPDATE (ujk) : If calculated values is stored, kder must 22966 be 1 for curve and 2 for surface (sh6getgeom). Should 22967 shevalc be used in stead of s1221 ? */ 22968 22969 uintpt[kpos] = SISL_NULL; 22970 if ((uintpt[kpos] = hp_newIntpt (3, slast, DZERO, -SI_ORD, 22971 lleft[0], lright[0], lleft[1], 22972 lright[1], 0, 0, nullp, nullp)) == SISL_NULL) 22973 goto err101; 22974 22975 kpos++; 22976 } 22977 } 22978 } 22979 } 22980 22981 /* Check if the intersection point lies at the end point of 22982 the curve. */ 22983 22984 kmarch = 0; 22985 if (DEQUAL (sptpar[kpar1] + tref, st[kk - 1] + tref)) 22986 ; 22987 else 22988 { 22989 /* Check if the intersection point is member of a list 22990 in this parameter direction of the curve. */ 22991 22992 qpt1 = qpt2 = SISL_NULL; 22993 kmarch = 1; 22994 22995 /* UPDATE (ujk) : only one list ? */ 22996 /* UPDATE (ujk) : only one list ? */ 22997 sh6getnhbrs (pintpt, &qpt1, &qpt2, &kstat); 22998 if (kstat < 0) 22999 goto error; 23000 23001 kmarch = 0; 23002 if (qpt1 != SISL_NULL && qpt1->epar[kpar1] < sptpar[kpar1]) 23003 *ll1 = SI_ON; 23004 else if (qpt2 != SISL_NULL && qpt2->epar[kpar1] < sptpar[kpar1]) 23005 *ll1 = SI_ON; 23006 else 23007 kmarch = 1; 23008 23009 } 23010 23011 if (kmarch) 23012 { 23013 /* March in the negative direction of the curve. */ 23014 23015 sh1784 (qc, qs, aepsge, sptpar, (kpar1 == 0), -1, slast, snext, &kstat); 23016 if (kstat < 0) 23017 goto error; 23018 23019 if (kstat == 1) 23020 { 23021 /* The endpoint of the curve is reached. */ 23022 ; 23023 } 23024 else if (kstat == 2) 23025 ; 23026 else 23027 { 23028 if (slast[kpar2] > sf_high_lim[0] || 23029 slast[kpar2 + 1] > sf_high_lim[1] || 23030 slast[kpar2] < sf_low_lim[0] || 23031 slast[kpar2 + 1] < sf_low_lim[1]) 23032 ; 23033 else 23034 { 23035 23036 /* Create help point. First fetch geometry information. */ 23037 23038 s1221 (qc, 0, slast[kpar1], &kleft1, sder, &kstat); 23039 if (kstat < 0) 23040 goto error; 23041 23042 s1221 (qc, 0, snext[kpar1], &kleft1, sder + kdim, &kstat); 23043 if (kstat < 0) 23044 goto error; 23045 s6diff (sder + kdim, sder, kdim, stang); 23046 23047 s1421 (qs, 1, slast + kpar2, &kleft1, &kleft2, sder, snorm, &kstat); 23048 if (kstat < 0) 23049 goto error; 23050 23051 /* Discuss tangent- and normal vector, and set up pre-topology 23052 in one direction of the curve. */ 23053 23054 if (s6scpr (snorm, stang, kdim) > DZERO) 23055 *ll1 = SI_OUT; 23056 else 23057 *ll1 = SI_IN; 23058 23059 /* UPDATE (ujk) : Tuning on distance */ 23060 if (s6dist (sptpar, slast, 3) > (double) 0.05 * tref) 23061 { 23062 /* Create help point. Set pre-topology data as undefined. */ 23063 /* UPDATE (ujk) : If calculated values is stored, kder must 23064 be 1 for curve and 2 for surface (sh6getgeom). Should 23065 shevalc be used in stead of s1221 ? */ 23066 23067 uintpt[kpos] = SISL_NULL; 23068 if ((uintpt[kpos] = hp_newIntpt (3, slast, DZERO, -SI_ORD, 23069 lleft[0], lright[0], lleft[1], 23070 lright[1], 0, 0, nullp, nullp)) == SISL_NULL) 23071 goto err101; 23072 23073 kpos++; 23074 } 23075 } 23076 } 23077 } 23078 } 23079 else 23080 { 23081 /* Pre-topology data of the curve may be computed from 23082 local information. */ 23083 23084 if (s6scpr (snorm, stang, kdim) > DZERO) 23085 { 23086 *ll1 = SI_IN; 23087 *lr1 = SI_OUT; 23088 } 23089 else 23090 { 23091 *ll1 = SI_OUT; 23092 *lr1 = SI_IN; 23093 } 23094 23095 } 23096 23097 /* Update pre-topology of intersection point. */ 23098 /* UPDATE (ujk), index = -1 ?? */ 23099 sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat); 23100 23101 /* Join intersection points, and set pretopology of help points. */ 23102 23103 for (ki = 0; ki < kpos; ki++) 23104 { 23105 /* Help point ? */ 23106 if (sh6ishelp (uintpt[ki])) 23107 sh6settop (uintpt[ki], -1, *(pintpt->left_obj_1), *(pintpt->right_obj_1), 23108 *(pintpt->left_obj_2), *(pintpt->right_obj_2), &kstat); 23109 23110 sh6idcon (rintdat, &uintpt[ki], &pintpt, &kstat); 23111 if (kstat < 0) 23112 goto error; 23113 } 23114 23115 /* Pre-topology information computed. */ 23116 23117 *jnewpt = kpos; 23118 *jstat = 0; 23119 goto out; 23120 23121 /* Error in scratch allocation. */ 23122 23123 err101:*jstat = -101; 23124 goto out; 23125 23126 23127 /* Error lower level routine. */ 23128 23129 error:*jstat = kstat; 23130 goto out; 23131 23132 out: 23133 return; 23134 } 23135 23136 23137 //=========================================================================== 23138 void sh1787 (SISLObject * po1, SISLObject * po2, double aepsge, 23139 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, int *jstat) 23140 //=========================================================================== 23141 { 23142 int kstat = 0; /* Status variable. */ 23143 int kdim; /* Dimension of geometry space. */ 23144 int kn1; /* Nmb vertices of surface in 1st direc. */ 23145 int kn2; /* Nmb vertices of surface in 1st direc. */ 23146 int kk1; /* Order of surface in 1st direction. */ 23147 int kk2; /* Order of surface in 1st direction. */ 23148 int kpos = 0; /* Current position in int.pt. array. */ 23149 int lleft[2]; /* Array storing pre-topology information. */ 23150 int lright[2]; /* Array storing pre-topology information. */ 23151 int *ll1, *ll2, *lr1, *lr2; /* Pointers into pre-topology arrays. */ 23152 double tpoint[3]; /* Value of point to intersect. */ 23153 double sder[21]; /* Result of surface evaluation. */ 23154 double *st1; /* First knot vector of surface. */ 23155 double *st2; /* Second knot vector of surface. */ 23156 double tref1; /* Referance value in equality test. */ 23157 double tref2; /* Referance value in equality test. */ 23158 SISLSurf *qs; /* Pointer to current surface. */ 23159 double *ret_val; /* Pointer to geo data from sh6getgeom */ 23160 double *ret_norm; /* Pointer to geo data from sh6getgeom */ 23161 int i; /* Loop variable. */ 23162 double cross; /* utang x vtang. */ 23163 double in_out[2]; /* To be used in touchy situations */ 23164 /* ---------------------------------------------------------------------- */ 23165 23166 /* Don't make pretop for help points ! */ 23167 /* Oh, yes ?, 2D is some nice case ! */ 23168 /* if (sh6ishelp (pintpt)) 23169 { 23170 *jstat = 0; 23171 goto out; 23172 } 23173 */ 23174 23175 /* Set pointers into the arrays storing pre-topology information. */ 23176 if (po1->iobj == SISLSURFACE) 23177 { 23178 ll1 = lleft; 23179 lr1 = lright; 23180 ll2 = lleft + 1; 23181 lr2 = lright + 1; 23182 } 23183 else 23184 { 23185 ll1 = lleft + 1; 23186 lr1 = lright + 1; 23187 ll2 = lleft; 23188 lr2 = lright; 23189 } 23190 23191 /* Get pre-topology information. */ 23192 sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat); 23193 if (kstat < 0) 23194 goto error; 23195 23196 /* Test dimension of geometry space. */ 23197 if (po1->iobj == SISLSURFACE) 23198 qs = po1->s1; 23199 else 23200 qs = po2->s1; 23201 23202 kdim = qs->idim; 23203 if (kdim != 2) 23204 goto err106; 23205 23206 /* Store surface information in local parameters. */ 23207 23208 kn1 = qs->in1; 23209 kn2 = qs->in2; 23210 kk1 = qs->ik1; 23211 kk2 = qs->ik2; 23212 st1 = qs->et1; 23213 st2 = qs->et2; 23214 tref1 = st1[kn1] - st1[kk1 - 1]; 23215 tref2 = st2[kn2] - st2[kk2 - 1]; 23216 23217 /* Fetch geometry information, point. */ 23218 sh6getgeom ((po1->iobj == SISLPOINT) ? po1 : po2, 23219 (po1->iobj == SISLPOINT) ? 1 : 2, 23220 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 23221 if (kstat < 0) 23222 goto error; 23223 23224 for(i=0; i<kdim; i++) 23225 tpoint[i]=ret_val[i]; 23226 23227 23228 /* Fetch geometry information, surface. */ 23229 sh6getgeom ((po1->iobj == SISLSURFACE) ? po1 : po2, 23230 (po1->iobj == SISLSURFACE) ? 1 : 2, 23231 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 23232 if (kstat < 0) 23233 goto error; 23234 23235 for(i=0; i<kdim*3; i++) 23236 sder[i]=ret_val[i]; 23237 23238 /* Set normal vector from the 2D tangent vectors. */ 23239 23240 cross = sder[kdim]*sder[2*kdim+1] + sder[kdim+1]*sder[2*kdim]; 23241 23242 /* Could improve this test. */ 23243 if (fabs(cross) > ANGULAR_TOLERANCE) 23244 { 23245 /* Compute pre-topology using local information. */ 23246 23247 if (cross > 0) 23248 { 23249 *ll1 = SI_UNDEF; 23250 *lr1 = SI_UNDEF; 23251 *ll2 = SI_IN; 23252 *lr2 = SI_OUT; 23253 } 23254 else 23255 { 23256 *ll1 = SI_UNDEF; 23257 *lr1 = SI_UNDEF; 23258 *ll2 = SI_OUT; 23259 *lr2 = SI_IN; 23260 } 23261 23262 } 23263 else if (qs->pdir && qs->pdir->ecoef && 23264 (DNEQUAL(qs->pdir->ecoef[0],DZERO) || 23265 DNEQUAL(qs->pdir->ecoef[1],DZERO))) 23266 { 23267 /* March to find help points. 23268 Not implemented yet. */ 23269 /* UJK, I'm not sure, but something like this should work : 23270 Remeber we are in a simple case situation ! 23271 */ 23272 in_out[0] = (double)1.0; 23273 in_out[1] = -(double)1.0; 23274 23275 if (s6scpr(qs->pdir->ecoef,in_out,kdim) > 0) 23276 { 23277 *ll1 = SI_UNDEF; 23278 *lr1 = SI_UNDEF; 23279 if (*ll2 == SI_UNDEF && 23280 *lr2 == SI_UNDEF) 23281 { 23282 *ll2 = SI_IN; 23283 *lr2 = SI_OUT; 23284 } 23285 else if (!((*ll2 == SI_IN && *lr2 == SI_IN) || 23286 (*ll2 == SI_OUT && *lr2 == SI_OUT))) 23287 { 23288 if (*ll2 != SI_IN) *ll2 = SI_IN; 23289 } 23290 } 23291 else 23292 { 23293 *ll1 = SI_UNDEF; 23294 *lr1 = SI_UNDEF; 23295 if (*ll2 == SI_UNDEF && 23296 *lr2 == SI_UNDEF) 23297 { 23298 *ll2 = SI_OUT; 23299 *lr2 = SI_IN; 23300 } 23301 else if (!((*ll2 == SI_IN && *lr2 == SI_IN) || 23302 (*ll2 == SI_OUT && *lr2 == SI_OUT))) 23303 { 23304 if (*lr2 != SI_IN) *lr2 = SI_IN; 23305 } 23306 } 23307 23308 } 23309 23310 /* Update pretopology of intersection point. */ 23311 23312 sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat); 23313 if (kstat < 0) 23314 goto error; 23315 23316 /* Pre-topology information computed. */ 23317 23318 *jnewpt = kpos; 23319 *jstat = 0; 23320 goto out; 23321 23322 /* Error in input. Incorrect dimension. */ 23323 23324 err106:*jstat = -106; 23325 goto out; 23326 23327 /* Error lower level routine. */ 23328 23329 error:*jstat = kstat; 23330 goto out; 23331 23332 out: 23333 return; 23334 } 23335 23336 23337 23338 //=========================================================================== 23339 void sh1786 (SISLObject * po1, SISLObject * po2, double aepsge, 23340 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, int *jstat) 23341 //=========================================================================== 23342 { 23343 int kstat = 0; /* Status variable. */ 23344 int ki, kj; /* Counters. */ 23345 int kleft = 0; /* Parameter to evaluator. */ 23346 int korgleft = 0; /* Knot index. */ 23347 int kdim; /* Dimension of geometry space. */ 23348 int kn; /* Number of vertices of curve. */ 23349 int kk; /* Order of curve. */ 23350 int kpos = 0; /* Current position in int.pt. array. */ 23351 double tpoint[3]; /* Value of point to intersect. */ 23352 double tpar0, tpar; /* Parameter value of point on curve. */ 23353 double spar[1]; /* Parameter value of endpoint of curve. */ 23354 double sder[6]; /* Result of curve evaluation. */ 23355 double stang1[2]; /* Tangent vector of curve. */ 23356 double stang2[2]; /* Tangent vector of level value. */ 23357 double *st; /* Pointer to knot vector of curve. */ 23358 double *sptpar = pintpt->epar;/* Pointer to parameter array of int.pt. */ 23359 double tref; /* Referance value in equality test. */ 23360 SISLCurve *qc; /* Pointer to current curve. */ 23361 SISLIntpt *uintpt[2]; /* Array storing new intersection points. */ 23362 double *ret_val; /* Pointer to geo data from sh6getgeom */ 23363 double *ret_norm; /* Pointer to geo data from sh6getgeom */ 23364 double *nullp = SISL_NULL; 23365 double dist; /* Distance from curve to point. */ 23366 double tot_ang; /* Sum of angles between curve deriv. and 1*/ 23367 int i; /* Loop variable. */ 23368 int make_hp; /* Flag, make/not make help pt. */ 23369 /* --------------------------------------------------------------------- */ 23370 23371 /* Don't make help point for help points ! */ 23372 if (sh6ishelp (pintpt)) 23373 { 23374 *jstat = 0; 23375 goto out; 23376 } 23377 23378 23379 /* Test dimension of geometry space. */ 23380 if (po1->iobj == SISLCURVE) 23381 { 23382 qc = po1->c1; 23383 } 23384 else 23385 { 23386 qc = po2->c1; 23387 } 23388 23389 kdim = qc->idim; 23390 if (kdim != 2) goto err106; 23391 23392 /* Store curve information in local parameters. */ 23393 23394 kn = qc->in; 23395 kk = qc->ik; 23396 st = qc->et; 23397 tref = st[kn] - st[kk - 1]; 23398 23399 /* Fetch geometry information, point. */ 23400 sh6getgeom ((po1->iobj == SISLPOINT) ? po1 : po2, 23401 (po1->iobj == SISLPOINT) ? 1 : 2, 23402 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 23403 if (kstat < 0) 23404 goto error; 23405 23406 for(i=0; i<kdim; i++) 23407 tpoint[i] = ret_val[i]; 23408 23409 /* Fetch geometry information, curve. */ 23410 sh6getgeom ((po1->iobj == SISLCURVE) ? po1 : po2, 23411 (po1->iobj == SISLCURVE) ? 1 : 2, 23412 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 23413 if (kstat < 0) 23414 goto error; 23415 23416 s1219(st,kk,kn,&korgleft,sptpar[0],&kstat); 23417 if (kstat < 0) goto error; 23418 23419 for(i=0; i<kdim*2; i++) 23420 sder[i] = ret_val[i]; 23421 23422 /* Set tangent vectors. */ 23423 23424 stang1[0] = (double)1.0; 23425 stang2[0] = (double)1.0; 23426 stang2[1] = DZERO; 23427 tot_ang = (double)0.0; 23428 23429 for(i=0; i<kdim; i++) 23430 { 23431 stang1[1] = sder[kdim+i]; 23432 tot_ang += s6ang(stang1,stang2,2); 23433 } 23434 23435 /* tune */ 23436 if (fabs(tot_ang) <= ANGULAR_TOLERANCE) 23437 { 23438 /* Test if the intersection point lies at the endpoint of 23439 the curve. */ 23440 23441 if (DEQUAL (sptpar[0] + tref, st[kn] + tref)) 23442 { 23443 23444 } 23445 else 23446 { 23447 /* Find endpoint of coincidence interval in the positive 23448 direction of the curve. */ 23449 ki = 0; 23450 tpar = sptpar[0] + (double) 2.0 *sqrt (aepsge); 23451 tpar = min (tpar, st[kn]); 23452 tpar0 = tpar = min (tpar, st[korgleft+1]); 23453 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 23454 dist=s6dist(sder,tpoint,kdim); 23455 if (dist <= aepsge) 23456 { 23457 make_hp = TRUE; 23458 for (ki = kleft - kk + 1; ki < kn; ki++) 23459 { 23460 for (tpar = DZERO, kj = ki + 1; kj < ki + kk; kj++) 23461 tpar += st[kj]; 23462 tpar /= (double) (kk - 1); 23463 23464 if (tpar > sptpar[0]) 23465 { 23466 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 23467 dist=s6dist(sder,tpoint,kdim); 23468 if (dist > aepsge) break; 23469 23470 tpar0 = tpar; /* Store parameter value of 23471 intersection point. */ 23472 } 23473 } 23474 } 23475 else make_hp = FALSE; 23476 23477 /* Test if there is coincidence along the entire curve part. */ 23478 23479 if (ki != kn && make_hp) 23480 { 23481 /* Create help point. */ 23482 23483 spar[0] = tpar0; 23484 uintpt[kpos] = SISL_NULL; 23485 if ((uintpt[kpos] = hp_newIntpt (1, spar, DZERO, -SI_ORD, 23486 SI_UNDEF, SI_UNDEF, SI_UNDEF, 23487 SI_UNDEF, 0, 0, nullp, nullp)) == SISL_NULL) 23488 goto err101; 23489 23490 /* Insert the point into the data structure. */ 23491 23492 sh6idnpt (rintdat, &uintpt[kpos], 1, &kstat); 23493 if (kstat < 0) 23494 goto error; 23495 23496 kpos++; 23497 } 23498 } 23499 23500 /* Test if the intersection point lies at the startpoint 23501 of the curve. */ 23502 23503 if (DEQUAL (sptpar[0] + tref, st[kk - 1] + tref)) 23504 { 23505 } 23506 else 23507 { 23508 /* Find endpoint of coincidence interval in the negative 23509 direction of the curve. */ 23510 23511 ki = kn; 23512 while (sptpar[0] == st[korgleft]) korgleft--; 23513 tpar = sptpar[0] - (double) 2.0 *sqrt (aepsge); 23514 tpar = max (tpar, st[kk - 1]); 23515 tpar0 = tpar = max (tpar, st[korgleft]); 23516 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 23517 dist=s6dist(sder,tpoint,kdim); 23518 if (dist <= aepsge) 23519 { 23520 make_hp = TRUE; 23521 23522 for (ki = kleft; ki >= 0; ki--) 23523 { 23524 for (tpar = DZERO, kj = ki + 1; kj < ki + kk; kj++) 23525 tpar += st[kj]; 23526 tpar /= (double) (kk - 1); 23527 23528 if (tpar < sptpar[0]) 23529 { 23530 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 23531 dist=s6dist(sder,tpoint,kdim); 23532 if (dist > aepsge) break; 23533 23534 tpar0 = tpar; /* Store parameter value of last 23535 found intersection point. */ 23536 } 23537 } 23538 } 23539 else make_hp = FALSE; 23540 23541 /* Test if there is coincidence along the entire curve part. */ 23542 if (ki >= 0 && make_hp) 23543 { 23544 23545 /* Create intersection point. */ 23546 spar[0] = tpar0; 23547 uintpt[kpos] = SISL_NULL; 23548 if ((uintpt[kpos] = hp_newIntpt (1, spar, DZERO, -SI_ORD, 23549 SI_UNDEF,SI_UNDEF,SI_UNDEF, 23550 SI_UNDEF, 0, 0, nullp, nullp)) == SISL_NULL) 23551 goto err101; 23552 23553 /* Insert the point into the data structure. */ 23554 23555 sh6idnpt (rintdat, &uintpt[kpos], 1, &kstat); 23556 if (kstat < 0) 23557 goto error; 23558 23559 23560 kpos++; 23561 23562 } 23563 23564 } 23565 } 23566 23567 /* Join intersection points. (kpos=0,1,2)*/ 23568 for (ki = 0; ki < kpos; ki++) 23569 { 23570 sh6idnpt (rintdat, &uintpt[ki], 1, &kstat); 23571 if (kstat < 0) 23572 goto error; 23573 /* Mark that an intersection interval is found. */ 23574 if (sh6ishelp (uintpt[ki]) && uintpt[ki]->no_of_curves == 0) 23575 { 23576 sh6idcon (rintdat, &uintpt[ki], &pintpt, &kstat); 23577 if (kstat < 0) 23578 goto error; 23579 } 23580 } 23581 23582 /* Pre-topology information computed. */ 23583 23584 *jnewpt = kpos; 23585 *jstat = 0; 23586 goto out; 23587 23588 /* Error in scratch allocation. */ 23589 23590 err101:*jstat = -101; 23591 goto out; 23592 23593 /* Error in input. Incorrect dimension. */ 23594 23595 err106:*jstat = -106; 23596 goto out; 23597 23598 /* Error lower level routine. */ 23599 23600 error:*jstat = kstat; 23601 goto out; 23602 23603 out: 23604 return; 23605 } 23606 23607 23608 //=========================================================================== 23609 void s1307(double ep[],int idim,double egeo[],int *jstat) 23610 //=========================================================================== 23611 { 23612 int k2dim=2*idim; /* The dimension *2, Start of double derivative*/ 23613 int kstat; /* Local status variable */ 23614 int ki,kj; /* Variables in loop */ 23615 double tlength; /* Length of first derivative vector */ 23616 double tdum; /* Dummy variable */ 23617 23618 /* Let c = c(w) be a parameterized curve. 23619 * The curvature vector is defined as the derivative of the unit tangent 23620 * vector with respect to the arc length a. If we don't have an arclength 23621 * parametrization then this parametrization can be written as a function 23622 * of the arc length w = w(a). By using the kernel rule for differentiation 23623 * we get: 23624 * 23625 * d d dw d c'(w) dw d c'(w) da 23626 * k(a) = -- T(w(a)) = -- T(w) -- = -- ---------- -- = -- ---------- / -- 23627 * da dw da dw sqrt(c'c') da dw sqrt(c'c') dw 23628 * 23629 * 23630 * d c'(w) c" c' (c'c'') 23631 * -- ----------------- = ---------- - ------------- 23632 * dw sqrt(c'(w) c'(w)) sqrt(c'c') sqrt(c'c')**3 23633 * 23634 * 23635 * 23636 * da 23637 * -- = sqrt(c'c') 23638 * dw 23639 */ 23640 23641 /* Copy position */ 23642 23643 memcopy(egeo,ep,idim,DOUBLE); 23644 23645 /* First we normalize the tangent vector */ 23646 23647 tlength = s6norm(ep+idim,idim,egeo+idim,&kstat); 23648 23649 if (DEQUAL(tlength,(double)0.0)) goto war101; 23650 23651 /* Make curvature vector */ 23652 23653 tdum = s6scpr(ep+k2dim,egeo+idim,idim)/tlength; 23654 23655 for (ki=idim,kj=k2dim;ki<k2dim;ki++,kj++) 23656 { 23657 egeo[kj] = (ep[kj]/tlength - egeo[ki]*tdum)/tlength; 23658 } 23659 23660 /* Make radius of curvature */ 23661 23662 tdum = s6length(egeo+k2dim,idim,&kstat); 23663 23664 if (tdum!=DZERO && ((double)1.0/tdum) > MAXIMAL_RADIUS_OF_CURVATURE) 23665 goto war101; 23666 23667 if (DNEQUAL(tdum,(double)0.0)) 23668 { 23669 egeo[3*idim] = (double)1.0/tdum; 23670 } 23671 else 23672 { 23673 goto war101; 23674 } 23675 23676 /* Everyting is ok */ 23677 23678 *jstat = 0; 23679 goto out; 23680 23681 /* Infinit radius of curvature */ 23682 23683 war101: *jstat=1; 23684 egeo[3*idim] = (double)-1.0; 23685 goto out; 23686 23687 out: 23688 return; 23689 } 23690 23691 23692 //=========================================================================== 23693 void sh1992_s9mbox2(double ecoef[],int icoef1,int icoef2,double aeps1, 23694 double aeps2,double e2max[],double e2min[]) 23695 //=========================================================================== 23696 { 23697 int ki,kj; /* Counters. */ 23698 int kant = 4; /* Number of box sides. */ 23699 int kinset = 0; /* Indicates if an inner box is found. */ 23700 double teps1 = aeps1+aeps1; /* Double tolerance in the inner. */ 23701 double teps2; /* Tolerance at edge. */ 23702 double teps3; /* Double tolerance at edge. */ 23703 double t1,t2,t3; /* To store elements of the rotation matrix. */ 23704 double *tmin,*tmax; /* Pointers used to traverse e2min and e2max. */ 23705 double sminin[4],smaxin[4]; /* Box boundaries in the inner. */ 23706 double sminedg[4],smaxedg[4]; /* Box boundaries at the edge. */ 23707 double *sc1,*sc2; /* Pointers into coefficient array. */ 23708 23709 /* Set tolerances at edge. If the tolerance is positive or dimension 23710 is 1D, the input tolerance is used, otherwise we must make sure 23711 that the maximum distance from the total box at the edges to the 23712 reduced box is aeps2. */ 23713 23714 if (aeps2 >= DZERO) 23715 teps2 = aeps2; 23716 else 23717 teps2 = (double)0.38268343*aeps2; /* aeps2 * sin(PI/8). */ 23718 teps3 = teps2 + teps2; 23719 23720 /* Initiate box boundaries of inner box. */ 23721 23722 for (ki=0; ki<kant; ki++) 23723 { 23724 sminin[ki] = HUGE; 23725 smaxin[ki] = -HUGE; 23726 } 23727 23728 /* Fetch value of first vertex. */ 23729 23730 sc1 = ecoef; sc2 = sc1 + 1; 23731 t1= ROTM * sc1[0]; 23732 t2= ROTM * sc2[0]; 23733 23734 tmin = sminedg; 23735 tmax = smaxedg; 23736 *tmin = *tmax = *sc1; 23737 tmin++; tmax++; 23738 *tmin = *tmax = *sc2; 23739 tmin++; tmax++; 23740 *tmin = *tmax = t1-t2; 23741 tmin++; tmax++; 23742 *tmin = *tmax = t1+t2; 23743 23744 /* For each vertex check and corrigate the box. */ 23745 23746 for (ki=0,sc1+=2,sc2+=2; ki<icoef2; ki++) 23747 /* UJK, writing error */ 23748 /*for (kj=(ki==1); kj<icoef1; kj++,sc1+=2,sc2+=2) */ 23749 23750 for (kj=(ki==0); kj<icoef1; kj++,sc1+=2,sc2+=2) 23751 { 23752 /* Set correct box boundaries. */ 23753 23754 if (((ki==0 || ki==icoef2-1) && icoef2>1) || 23755 ((kj==0 || kj==icoef1-1) && icoef1>1)) 23756 tmin = sminedg, tmax = smaxedg; 23757 else 23758 kinset = 1, tmin = sminin, tmax = smaxin; 23759 23760 t1= ROTM * sc1[0]; 23761 t2= ROTM * sc2[0]; 23762 23763 if(*sc1 < *tmin) *tmin = *sc1; 23764 if(*sc1 > *tmax) *tmax = *sc1; 23765 tmin++; tmax++; 23766 if(*sc2 < *tmin) *tmin = *sc2; 23767 if(*sc2 > *tmax) *tmax = *sc2; 23768 tmin++; tmax++; 23769 t3= t1 - t2; 23770 if(t3 < *tmin) *tmin = t3; 23771 if(t3 > *tmax) *tmax = t3; 23772 tmin++; tmax++; 23773 t3= t1 + t2; 23774 if(t3 < *tmin) *tmin = t3; 23775 if(t3 > *tmax) *tmax = t3; 23776 } 23777 23778 /* Merge the inner and the outer box, and adjust with the 23779 tolerance. */ 23780 23781 if (!kinset) 23782 { 23783 memcopy(sminin,sminedg,kant,DOUBLE); 23784 memcopy(smaxin,smaxedg,kant,DOUBLE); 23785 } 23786 for (ki=0; ki<kant; ki++) 23787 { 23788 e2min[ki] = MIN(sminin[ki]-aeps1,sminedg[ki]-teps2); 23789 e2max[ki] = MAX(smaxin[ki]+aeps1,smaxedg[ki]+teps2); 23790 e2min[kant+ki] = MIN(sminin[ki]-teps1,sminedg[ki]-teps3); 23791 e2max[kant+ki] = MAX(smaxin[ki]+teps1,smaxedg[ki]+teps3); 23792 } 23793 } 23794 23795 //=========================================================================== 23796 void sh1992_s9mbox(double ecoef[],int icoef1,int icoef2,int idim, 23797 double aeps1,double aeps2,double e2max[], 23798 double e2min[],int *jstat) 23799 //=========================================================================== 23800 { 23801 int ki,ki1,kj; /* Counters. */ 23802 int kant = idim; /* Number of box sides. */ 23803 int kinset = 0; /* Indicates if the inner box is set. */ 23804 double noice = (double)100.0*REL_COMP_RES; /* Noice killer. */ 23805 double teps1 = aeps1+aeps1; /* Double tolerance in the inner. */ 23806 double teps2; /* Tolerance at edge. */ 23807 double teps3; /* Double tolerance at edge. */ 23808 double *tmin,*tmax; /* Pointers into box boundary arrays. */ 23809 double *sc; /* Pointer into coefficient array. */ 23810 double *sminin=SISL_NULL,*smaxin=SISL_NULL; /* Box boundaries of the inner. */ 23811 double *sminedg=SISL_NULL,*smaxedg=SISL_NULL; /* Box boundaries of the edge. */ 23812 23813 /* Set tolerances at edge. If the tolerance is positive or dimension 23814 is 1D, the input tolerance is used, otherwise we must make sure 23815 that the maximum distance from the total box at the edges to the 23816 reduced box is aeps2. */ 23817 23818 if (idim == 1 || aeps2 >= DZERO) 23819 teps2 = aeps2; 23820 else 23821 teps2 = aeps2/sqrt((double)idim); 23822 teps3 = teps2 + teps2; 23823 23824 /* Allocate scratch for intermediate box arrays. */ 23825 23826 if ((sminin = newarray(kant,double)) == SISL_NULL) goto err101; 23827 if ((smaxin = newarray(kant,double)) == SISL_NULL) goto err101; 23828 if ((sminedg = newarray(kant,double)) == SISL_NULL) goto err101; 23829 if ((smaxedg = newarray(kant,double)) == SISL_NULL) goto err101; 23830 23831 /* Initiate box boundaries of inner box. */ 23832 23833 for (ki=0; ki<kant; ki++) 23834 { 23835 sminin[ki] = HUGE; 23836 smaxin[ki] = -HUGE; 23837 } 23838 23839 /* Fetch value of first vertex. */ 23840 23841 for (ki = 0; ki < idim; ki++) 23842 sminedg[ki] = smaxedg[ki] = ecoef[ki]; 23843 23844 /* For each vertice check and corrigate the box. */ 23845 23846 for (sc=ecoef+idim, ki=0; ki<icoef2; ki++) 23847 for (kj=(ki==0); kj<icoef1; kj++) 23848 { 23849 /* Set correct box. */ 23850 23851 if (((ki==0 || ki==icoef2-1) && icoef2>1) || 23852 ((kj==0 || kj==icoef1-1) && icoef1>1)) 23853 tmin = sminedg, tmax = smaxedg; 23854 else 23855 kinset = 1, tmin = sminin, tmax = smaxin; 23856 23857 for (ki1=0; ki1<idim; ki1++,sc++,tmin++,tmax++) 23858 { 23859 if(*sc < *tmin) *tmin = *sc; 23860 if(*sc > *tmax) *tmax = *sc; 23861 } 23862 } 23863 23864 /* Merge the inner and the outer box, and adjust with the 23865 tolerance. */ 23866 23867 if (!kinset) 23868 { 23869 memcopy(sminin,sminedg,kant,DOUBLE); 23870 memcopy(smaxin,smaxedg,kant,DOUBLE); 23871 } 23872 for (ki=0; ki<kant; ki++) 23873 { 23874 e2min[ki] = MIN(sminin[ki]-aeps1,sminedg[ki]-teps2); 23875 e2max[ki] = MAX(smaxin[ki]+aeps1,smaxedg[ki]+teps2); 23876 if (idim > 1) 23877 { 23878 e2min[kant+ki] = MIN(sminin[ki]-teps1,sminedg[ki]-teps3); 23879 e2max[kant+ki] = MAX(smaxin[ki]+teps1,smaxedg[ki]+teps3); 23880 } 23881 } 23882 23883 /* ALA and UJK 30.10.90, remove noice near by zero. */ 23884 23885 if (idim == 1) 23886 { 23887 if (fabs(e2max[0]) < noice) e2max[0] = DZERO; 23888 if (fabs(e2min[0]) < noice) e2min[0] = DZERO; 23889 } 23890 23891 *jstat = 0; 23892 goto out; 23893 23894 /* Error in scratch allocation. */ 23895 23896 err101 : *jstat = -101; 23897 goto out; 23898 23899 out : 23900 if (sminin != SISL_NULL) freearray(sminin); 23901 if (smaxin != SISL_NULL) freearray(smaxin); 23902 if (sminedg != SISL_NULL) freearray(sminedg); 23903 if (smaxedg != SISL_NULL) freearray(smaxedg); 23904 } 23905 23906 23907 //=========================================================================== 23908 void sh1992_s9mbox3(double ecoef[],int icoef1,int icoef2,double aeps1, 23909 double aeps2,double e2max[],double e2min[]) 23910 //=========================================================================== 23911 { 23912 int ki,kj; /* Counters. */ 23913 int kant = 9; /* Number of box sides. */ 23914 int kinset = 0; /* Indicates if inner box is set. */ 23915 double teps1 = aeps1+aeps1; /* Double tolerance in the inner. */ 23916 double teps2; /* Tolerance at edge. */ 23917 double teps3; /* Double tolerance at edge. */ 23918 double t1,t2,t3,t4; /* To store elements of the rotation matrix. */ 23919 double *tmin,*tmax; /* Pointers used to traverse e2min and e2max. */ 23920 double sminin[9],smaxin[9]; /* Box boundaries in the inner. */ 23921 double sminedg[9],smaxedg[9]; /* Box boundaries at the edge. */ 23922 double *sc1,*sc2,*sc3; /* Pointers to coefficients. */ 23923 23924 /* Set tolerances at edge. If the tolerance is positive or dimension 23925 is 1D, the input tolerance is used, otherwise we must make sure 23926 that the maximum distance from the total box at the edges to the 23927 reduced box is aeps2. */ 23928 23929 if (aeps2 >= DZERO) 23930 teps2 = aeps2; 23931 else 23932 teps2 = (double)0.2767326953*aeps2; 23933 teps3 = teps2 + teps2; 23934 23935 /* Initiate box boundaries of inner box. */ 23936 23937 for (ki=0; ki<kant; ki++) 23938 { 23939 sminin[ki] = HUGE; 23940 smaxin[ki] = -HUGE; 23941 } 23942 23943 /* Fetch value of first vertex. */ 23944 23945 sc1 = ecoef; sc2 = sc1+1; sc3 = sc2 + 1; 23946 t1= ROTM * sc1[0]; 23947 t2= ROTM * sc2[0]; 23948 t3= ROTM * sc3[0]; 23949 23950 tmin = sminedg; 23951 tmax = smaxedg; 23952 *tmin = *tmax = *sc1; 23953 tmin++; tmax++; 23954 *tmin = *tmax = *sc2; 23955 tmin++; tmax++; 23956 *tmin = *tmax = *sc3; 23957 tmin++; tmax++; 23958 *tmin = *tmax = t2-t3; 23959 tmin++; tmax++; 23960 *tmin = *tmax = t2+t3; 23961 tmin++; tmax++; 23962 *tmin = *tmax = t1-t3; 23963 tmin++; tmax++; 23964 *tmin = *tmax = t1+t3; 23965 tmin++; tmax++; 23966 *tmin = *tmax = t1-t2; 23967 tmin++; tmax++; 23968 *tmin = *tmax = t1+t2; 23969 23970 /* For each vertice at the edge check and corrigate the box. */ 23971 23972 for (ki=0,sc1+=3,sc2+=3,sc3+=3; ki<icoef2; ki++) 23973 for (kj=(ki==0); kj<icoef1; kj++,sc1+=3,sc2+=3,sc3+=3) 23974 { 23975 23976 /* Set correct pointers. */ 23977 23978 if (((ki==0 || ki==icoef2-1) && icoef2>1) || 23979 ((kj==0 || kj==icoef1-1) && icoef1>1)) 23980 tmin = sminedg, tmax = smaxedg; 23981 else 23982 kinset = 1, tmin = sminin, tmax = smaxin; 23983 23984 t1= ROTM * sc1[0]; 23985 t2= ROTM * sc2[0]; 23986 t3= ROTM * sc3[0]; 23987 23988 if(*sc1 < *tmin) *tmin = *sc1; 23989 if(*sc1 > *tmax) *tmax = *sc1; 23990 tmin++; tmax++; 23991 if(*sc2 < *tmin) *tmin = *sc2; 23992 if(*sc2 > *tmax) *tmax = *sc2; 23993 tmin++; tmax++; 23994 if(*sc3 < *tmin) *tmin = *sc3; 23995 if(*sc3 > *tmax) *tmax = *sc3; 23996 tmin++; tmax++; 23997 t4= t2 - t3; 23998 if(t4 < *tmin) *tmin = t4; 23999 if(t4 > *tmax) *tmax = t4; 24000 tmin++; tmax++; 24001 t4= t2 + t3; 24002 if(t4 < *tmin) *tmin = t4; 24003 if(t4 > *tmax) *tmax = t4; 24004 tmin++; tmax++; 24005 t4= t1 - t3; 24006 if(t4 < *tmin) *tmin = t4; 24007 if(t4 > *tmax) *tmax = t4; 24008 tmin++; tmax++; 24009 t4= t1 + t3; 24010 if(t4 < *tmin) *tmin = t4; 24011 if(t4 > *tmax) *tmax = t4; 24012 tmin++; tmax++; 24013 t4= t1 - t2; 24014 if(t4 < *tmin) *tmin = t4; 24015 if(t4 > *tmax) *tmax = t4; 24016 tmin++; tmax++; 24017 t4= t1 + t2; 24018 if(t4 < *tmin) *tmin = t4; 24019 if(t4 > *tmax) *tmax = t4; 24020 } 24021 24022 /* Merge the inner and the outer box, and adjust with the 24023 tolerance. */ 24024 24025 if (!kinset) 24026 { 24027 memcopy(sminin,sminedg,kant,DOUBLE); 24028 memcopy(smaxin,smaxedg,kant,DOUBLE); 24029 } 24030 for (ki=0; ki<kant; ki++) 24031 { 24032 e2min[ki] = MIN(sminin[ki]-aeps1,sminedg[ki]-teps2); 24033 e2max[ki] = MAX(smaxin[ki]+aeps1,smaxedg[ki]+teps2); 24034 e2min[kant+ki] = MIN(sminin[ki]-teps1,sminedg[ki]-teps3); 24035 e2max[kant+ki] = MAX(smaxin[ki]+teps1,smaxedg[ki]+teps3); 24036 } 24037 } 24038 24039 24040 //=========================================================================== 24041 void s6newbox(SISLbox *pbox,int inum,int itype, double aepsge,int *jstat) 24042 //=========================================================================== 24043 { 24044 int knum = (inum == 1) ? inum : 2*inum; /* If the geometry space has 24045 dimension larger than 1, 24046 a double set of min- and 24047 max-arrays is to be made. */ 24048 24049 if (itype < 0 || itype > 2) goto err126; 24050 24051 /* Test no such box exist, create the necessary arrays. */ 24052 24053 if (pbox->e2min[itype] == SISL_NULL) 24054 { 24055 if ((pbox->e2min[itype] = newarray(knum,DOUBLE)) == SISL_NULL) goto err101; 24056 if ((pbox->e2max[itype] = newarray(knum,DOUBLE)) == SISL_NULL) goto err101; 24057 } 24058 24059 /* Set the tolerance. */ 24060 24061 if (itype != 0) pbox->etol[itype] = aepsge; 24062 24063 *jstat = 0; 24064 goto out; 24065 24066 /* Error in scratch allocation. */ 24067 24068 err101 : *jstat = -101; 24069 goto out; 24070 24071 /* Error in input. Kind of box do not exist. */ 24072 24073 err126 : *jstat = -126; 24074 goto out; 24075 24076 out : 24077 return; 24078 } 24079 24080 24081 //=========================================================================== 24082 int s6existbox(SISLbox *pbox,int itype,double aepsge) 24083 //=========================================================================== 24084 { 24085 if (pbox->e2min[itype] == SISL_NULL) return(0); /* No box is made. */ 24086 24087 if (itype != 0 && DNEQUAL(pbox->etol[itype],aepsge)) 24088 return(-1); /* Box exist, but with another size of the expansion. */ 24089 24090 return(1); 24091 } 24092 24093 24094 //=========================================================================== 24095 SISLbox * newbox (int idim) 24096 //=========================================================================== 24097 { 24098 SISLbox *qnew; /* Local pointer to new direction structure.*/ 24099 int ki; /* Counter. */ 24100 int knum; /* Number of corners in the box. */ 24101 24102 24103 /* Initialise number of corners. */ 24104 24105 if (idim == 3) 24106 knum = 12; 24107 else if (idim == 2) 24108 knum = 4; 24109 else 24110 knum = idim; 24111 24112 /* Allocate space for SISLbox structure. */ 24113 24114 if ((qnew = newarray (1, SISLbox)) != SISL_NULL) 24115 { 24116 /* Initialise new direction structure. */ 24117 24118 qnew->imin = 0; 24119 qnew->imax = 0; 24120 24121 /* Initialize arrays. */ 24122 24123 for (ki = 0; ki < 3; ki++) 24124 { 24125 qnew->e2max[ki] = SISL_NULL; 24126 qnew->e2min[ki] = SISL_NULL; 24127 qnew->etol[ki] = DZERO; 24128 } 24129 24130 if ((qnew->emax = newarray (knum, double)) == SISL_NULL) 24131 { 24132 freearray (qnew); 24133 qnew = SISL_NULL; 24134 } 24135 else if ((qnew->emin = newarray (knum, double)) == SISL_NULL) 24136 { 24137 freearray (qnew->emax); 24138 freearray (qnew); 24139 qnew = SISL_NULL; 24140 } 24141 } 24142 return (qnew); 24143 } 24144 24145 24146 //=========================================================================== 24147 void sh1992cu(SISLCurve *pc,int itype,double aepsge,int *jstat) 24148 //=========================================================================== 24149 { 24150 int kstat = 0; /* Status variable. */ 24151 int kdim = pc->idim; /* Dimension of geometry space. */ 24152 int ktype = itype % 10; /* Kind of box. */ 24153 int knum; /* Number of sides of box. */ 24154 int kbez = 0; /* Indicates if Bezier case. */ 24155 double teps_inner; /* Tolerance with which to expand in the inner. */ 24156 double teps_edge; /* Tolerance with which to expand at the edge. */ 24157 24158 /* Set number of box sides. */ 24159 24160 if (itype < 10 && kdim == 3) knum = 9; 24161 else if (itype < 10 && kdim == 2) knum = 4; 24162 else knum = kdim; 24163 24164 /* Set correct tolerances. */ 24165 24166 teps_inner = (ktype == 0) ? DZERO : (double)0.5*aepsge; 24167 teps_edge = (ktype == 2) ? -teps_inner : teps_inner; 24168 24169 if (pc->pbox == SISL_NULL) 24170 if ((pc->pbox = newbox(pc->idim)) == SISL_NULL) goto err101; 24171 24172 if (s6existbox(pc->pbox,ktype,aepsge) < 1) 24173 { 24174 /* The box do not exist already. In the Bezier case, 24175 it is not necessary to expand in the inner of the curve. */ 24176 24177 /* Create the box. */ 24178 24179 s6newbox(pc->pbox,knum,ktype,aepsge,&kstat); 24180 if (kstat < 0) goto error; 24181 24182 if (pc->ik == pc->in) 24183 { 24184 teps_inner = DZERO; 24185 kbez = 1; 24186 } 24187 24188 /* Make the requested box. First allocate scratch for 24189 box arrays. */ 24190 24191 if (knum == 9) 24192 sh1992_s9mbox3(pc->ecoef,pc->in,1,teps_inner,teps_edge, 24193 pc->pbox->e2max[ktype],pc->pbox->e2min[ktype]); 24194 else if (knum == 4) 24195 sh1992_s9mbox2(pc->ecoef,pc->in,1,teps_inner,teps_edge, 24196 pc->pbox->e2max[ktype],pc->pbox->e2min[ktype]); 24197 else 24198 { 24199 sh1992_s9mbox(pc->ecoef,pc->in,1,kdim,teps_inner,teps_edge, 24200 pc->pbox->e2max[ktype],pc->pbox->e2min[ktype],&kstat); 24201 if (kstat < 0) goto error; 24202 } 24203 } 24204 24205 *jstat = kbez; 24206 goto out; 24207 24208 /* Error in space allocation. */ 24209 24210 err101 : *jstat = -101; 24211 goto out; 24212 24213 /* Error in lower level routine. */ 24214 24215 error : *jstat = kstat; 24216 goto out; 24217 24218 out: 24219 return; 24220 } 24221 24222 24223 //=========================================================================== 24224 void sh1783_s9relax(sh1783_fevalProc fevalc1,sh1783_fevalProc fevalc2, 24225 SISLCurve * pc1, SISLCurve * pc2,int ider, double aepsge, 24226 double ax1, int *jleft1, double eder1[],double anext, 24227 double *cx2, int *jleft2, double eder2[], int *jstat) 24228 //=========================================================================== 24229 { 24230 int kstat = 0; /* Status variable. */ 24231 double tstart; /* Start parameter value of curve 2. */ 24232 double tend; /* End parameter value of curve 2. */ 24233 SISLPoint *qpoint = SISL_NULL; /* SISLPoint instance used to represent point on curve 1. */ 24234 24235 /* Find endpoints of the parameter interval of curve 2. */ 24236 24237 tstart = *(pc2->et + pc2->ik - 1); 24238 tend = *(pc2->et + pc2->in); 24239 24240 /* Make point sderc at curve at ax1 */ 24241 24242 fevalc1 (pc1, ider, ax1, jleft1, eder1, &kstat); 24243 if (kstat < 0) goto error; 24244 24245 /* Find closest point on curve 2 to eder1 */ 24246 24247 qpoint = newPoint (eder1, pc1->idim, 0); 24248 if (qpoint == SISL_NULL) goto err101; 24249 24250 s1771 (qpoint, pc2, aepsge, tstart, tend, anext, cx2, &kstat); 24251 if (kstat < 0) 24252 goto error; 24253 24254 /* Calculate point and derivatives in second curve */ 24255 24256 fevalc2 (pc2, ider, *cx2, jleft2, eder2, &kstat); 24257 if (kstat < 0) goto error; 24258 24259 *jstat = 0; 24260 goto out; 24261 24262 /* Error in space allocation. */ 24263 24264 err101: 24265 *jstat = -101; 24266 goto out; 24267 24268 /* Error in lower level routine. */ 24269 24270 error: 24271 *jstat = kstat; 24272 goto out; 24273 24274 out: 24275 if (qpoint != SISL_NULL) 24276 freePoint (qpoint); 24277 24278 return; 24279 } 24280 24281 //=========================================================================== 24282 void sh1783 (SISLCurve * pc1, SISLCurve * pc2, double aepsge, double epar[], 24283 int idir1, int idir2, double elast[], double enext[], int *jstat) 24284 //=========================================================================== 24285 { 24286 int kstat; /* Status variable */ 24287 int ki; /* Counter. */ 24288 int kleftc1 = 0; /* Left indicator for point calculation of curve 1.*/ 24289 int kleftc2 = 0; /* Left indicator for point calculation of curve 2.*/ 24290 int kk1, kk2, kn1, kn2; /* Orders and number of vertices of curves */ 24291 int kdim; /* The dimension of the space in which the curves lie. */ 24292 int kpos = 0; /* Position of error */ 24293 int kderc = 2; /* Number of derivatives to be claculated on the curves */ 24294 int kdum; /* Temporary variable */ 24295 int kchange; /* Indicates which curve that is marched along. 24296 = 0 : First curve. 24297 = 1 : Second curve. */ 24298 double s3dinf1[20]; /* Pointer to storage for point info of curve 1 24299 (10 dobules pr point when idim=3, 7 when idim=3) */ 24300 double s3dinf2[20]; /* Pointer to storage for point info of curve 2 24301 (10 dobules pr point when idim=3, 7 when idim=3) */ 24302 double *st1; /* Knot vector of first curve */ 24303 double *st2; /* Knot vector of second curve */ 24304 double tfirst1, tfirst2; /* First parameter value on curves */ 24305 double tend1, tend2; /* Last parameter on curves */ 24306 double sderc1[20]; /* Position, first and second derivatives on curve 1 */ 24307 double sderc2[20]; /* Position, first and second derivatives on curve 2 */ 24308 double tx, tx1, tx2; /* Parameter values of first curve. */ 24309 double ty, ty1, ty2; /* Parameter value of second curve. */ 24310 double tstep; /* Final step length */ 24311 double txstep, tystep; /* Step length */ 24312 double txmaxinc, tymaxinc; /* Maximal increment in parameter value along curve*/ 24313 double txlengthend, tylengthend; /* Length of 1st derivative at start of segment */ 24314 double txincre, tyincre; /* Parameter value increment */ 24315 double txmax, tymax; /* Local maximal step length */ 24316 double tdist = DZERO; /* Distance */ 24317 double tpos; /* New iteration point on curve pc2 */ 24318 24319 /* Pointer to curve evaluator routines */ 24320 24321 sh1783_fevalProc fevalc1; 24322 sh1783_fevalProc fevalc2; 24323 24324 /* Make maximal step length based on box-size of curve 1 */ 24325 24326 sh1992cu (pc1, 0, aepsge, &kstat); 24327 if (kstat < 0) 24328 goto error; 24329 24330 txmax = MAX (pc1->pbox->e2max[0][0] - pc1->pbox->e2min[0][0], 24331 pc1->pbox->e2max[0][1] - pc1->pbox->e2min[0][1]); 24332 txmax = MAX (txmax, pc1->pbox->e2max[0][2] - pc1->pbox->e2min[0][2]); 24333 24334 /* Make maximal step length based on box-size of curve 2 */ 24335 24336 sh1992cu (pc2, 0, aepsge, &kstat); 24337 if (kstat < 0) 24338 goto error; 24339 24340 tymax = MAX (pc2->pbox->e2max[0][0] - pc2->pbox->e2min[0][0], 24341 pc2->pbox->e2max[0][1] - pc2->pbox->e2min[0][1]); 24342 tymax = MAX (tymax, pc2->pbox->e2max[0][2] - pc2->pbox->e2min[0][2]); 24343 24344 /* Copy curve pc1 attributes to local parameters. */ 24345 24346 kdim = pc1->idim; 24347 kk1 = pc1->ik; 24348 kn1 = pc1->in; 24349 st1 = pc1->et; 24350 24351 /* Copy curve pc2 attributes to local parameters. */ 24352 24353 kk2 = pc2->ik; 24354 kn2 = pc2->in; 24355 st2 = pc2->et; 24356 24357 /* Check that dimensions are equal */ 24358 24359 if (kdim != pc2->idim || kdim > 3) 24360 goto err105; 24361 24362 /* Copy interval description into local variables */ 24363 24364 tfirst1 = epar[0]; 24365 tfirst2 = epar[1]; 24366 tend1 = (idir1 == 1) ? st1[kn1] : st1[kk1 - 1]; 24367 tend2 = (idir2 == 1) ? st2[kn2] : st2[kk2 - 1]; 24368 24369 /* To make sure we do not start outside or end outside the curve we 24370 truncate tfirst1 to the knot interval of the curve */ 24371 24372 tfirst1 = (idir1 == 1) ? MAX (tfirst1, st1[kk1 - 1]) : MIN (tfirst1, st1[kn1]); 24373 24374 /* To make sure we do not start outside or end outside the curve we 24375 truncate tstart2 and tend2 to the knot interval of the curve */ 24376 24377 tfirst2 = (idir2 == 1) ? MAX (tfirst2, st2[kk2 - 1]) : MIN (tfirst2, st2[kn2]); 24378 24379 /* Set curve evaluator of 1. curve. */ 24380 24381 fevalc1 = (idir1 == 1) ? s1221 : s1227; 24382 24383 /* Set curve evaluator of 2. curve. */ 24384 24385 fevalc2 = (idir2 == 1) ? s1221 : s1227; 24386 24387 /* Store knot values at start of curve */ 24388 24389 tx1 = tfirst1; 24390 kdum = MAX (kk1, kk2); 24391 txmaxinc = fabs (tend1 - tfirst1) / (kdum * kdum); 24392 24393 /* Make start point and intital step length based on first curve */ 24394 24395 fevalc1 (pc1, kderc, tx1, &kleftc1, sderc1, &kstat); 24396 if (kstat < 0) goto error; 24397 24398 ty1 = tfirst2; 24399 tymaxinc = fabs (tend2 - tfirst2) / (kdum * kdum); 24400 24401 /* Make start point and intital step length based on second curve */ 24402 24403 fevalc2 (pc2, kderc, ty1, &kleftc2, sderc2, &kstat); 24404 if (kstat < 0) goto error; 24405 24406 /* While end not reached */ 24407 24408 while (idir1 * tx1 < idir1 * tend1 && idir2 * ty1 < idir2 * tend2) 24409 { 24410 24411 /* Calculate unit tangent and radius of curvature of first curve. */ 24412 24413 s1307 (sderc1, kdim, s3dinf1, &kstat); 24414 if (kstat < 0) 24415 goto error; 24416 24417 /* Calculate step length based on curvature of first curve. */ 24418 24419 txstep = s1311 (s3dinf1[3 * kdim], aepsge, tymax, &kstat); 24420 if (kstat < 0) 24421 goto error; 24422 24423 /* Remember length of start tangent, end of zero segment */ 24424 24425 txlengthend = s6length (sderc1 + kdim, kdim, &kstat); 24426 if (kstat < 0) 24427 goto error; 24428 24429 /* Calculate unit tangent and radius of curvature of second curve. */ 24430 24431 s1307 (sderc2, kdim, s3dinf2, &kstat); 24432 if (kstat < 0) 24433 goto error; 24434 24435 /* Calculate step length based on curvature */ 24436 24437 tystep = s1311 (s3dinf2[3 * kdim], aepsge, txmax, &kstat); 24438 if (kstat < 0) 24439 goto error; 24440 24441 /* Remember length of start tangent, end of zero segment */ 24442 24443 tylengthend = s6length (sderc2 + kdim, kdim, &kstat); 24444 if (kstat < 0) 24445 goto error; 24446 24447 /* Find minimum step length. */ 24448 24449 tstep = MIN (txstep, tystep); 24450 kchange = (txstep <= tystep) ? 0 : 1; 24451 24452 /* Find candidate end point, make sure that no breaks in tangent or 24453 curvature exists between start and endpoints of the segment */ 24454 /* Compute increment in the parameter values. Use REL_PAR_RES if the 24455 tangent has zero length. */ 24456 24457 if (DEQUAL (txlengthend, DZERO)) 24458 txincre = REL_PAR_RES; 24459 else 24460 txincre = MIN (tstep / txlengthend, txmaxinc); 24461 24462 if (DEQUAL (tylengthend, DZERO)) 24463 tyincre = REL_PAR_RES; 24464 else 24465 tyincre = MIN (tstep / tylengthend, tymaxinc); 24466 24467 /* Make sure that we don't pass any knots of curve 1. */ 24468 24469 /* VSK. 01-93. Is it possible that several knots might be passed. */ 24470 24471 if (idir1 > 0 && (tx1 + txincre) > (st1[kleftc1 + 1] + REL_PAR_RES) && 24472 !(tx1 > (st1[kleftc1 + 1] - REL_PAR_RES))) 24473 { 24474 txincre = st1[kleftc1 + 1] - tx1; 24475 tstep = txincre * txlengthend; 24476 tyincre = (tylengthend > DZERO) ? tstep / tylengthend : REL_PAR_RES; 24477 kchange = 0; 24478 } 24479 24480 /* 24481 guen if (idir1 < 0 && (tx1 - txincre < st1[kleftc1] - REL_PAR_RES)) 24482 guen fixed to: 24483 */ 24484 /* VSK. 01-93. Is it possible that several knots might be passed. */ 24485 24486 if (idir1 < 0 && (tx1 - txincre) < (st1[kleftc1] - REL_PAR_RES) && 24487 !(tx1 < (st1[kleftc1] + REL_PAR_RES))) 24488 { 24489 txincre = idir1 * (st1[kleftc1] - tx1); 24490 tstep = txincre * txlengthend; 24491 tyincre = (tylengthend > DZERO) ? tstep / tylengthend : REL_PAR_RES; 24492 kchange = 0; 24493 } 24494 24495 /* Avoid passing next knot of curve 2. */ 24496 24497 /* VSK. 01-93. Is it possible that several knots might be passed. */ 24498 24499 if (idir2 > 0 && (ty1 + tyincre) > (st2[kleftc2 + 1] + REL_PAR_RES) && 24500 !(ty1 > (st2[kleftc2 + 1] - REL_PAR_RES))) 24501 { 24502 tyincre = st2[kleftc2 + 1] - ty1; 24503 tstep = tyincre * tylengthend; 24504 txincre = (txlengthend > DZERO) ? tstep / txlengthend : REL_PAR_RES; 24505 kchange = 1; 24506 } 24507 24508 /* Avoid passing previous knot of curve 2. */ 24509 24510 /* 24511 guen if (idir2 < 0 && (ty1 - tyincre < st2[kleftc2] - REL_PAR_RES)) 24512 guen fixed to: 24513 */ 24514 /* VSK. 01-93. Is it possible that several knots might be passed. */ 24515 24516 if (idir2 < 0 && (ty1 - tyincre) < (st2[kleftc2] - REL_PAR_RES) && 24517 !(ty1 > (st2[kleftc2] + REL_PAR_RES))) 24518 { 24519 tyincre = idir2 * (st2[kleftc2] - ty1); 24520 tstep = tyincre * tylengthend; 24521 txincre = (txlengthend > DZERO) ? tstep / txlengthend : REL_PAR_RES; 24522 kchange = 1; 24523 } 24524 24525 24526 /* Set endpoints of step. */ 24527 24528 tx2 = tx1 + idir1 * txincre; 24529 ty2 = ty1 + idir2 * tyincre; 24530 24531 for (tx = (tx1 + tx2) / (double) 2.0, ty = (ty1 + ty2) / (double) 2.0, ki = 0; 24532 ki < 2; ki++, tx = tx2, ty = ty2) 24533 { 24534 if (kchange == 0) 24535 { 24536 if (idir1 * tx >= idir1 * tend1) 24537 break; 24538 24539 /* March along first curve. Iterate down to the second. */ 24540 24541 sh1783_s9relax (fevalc1, fevalc2, pc1, pc2, kderc, aepsge, tx, &kleftc1, sderc1, ty, 24542 &tpos, &kleftc2, sderc2, jstat); 24543 if (kstat < 0) 24544 goto error; 24545 } 24546 else 24547 { 24548 if (idir2 * ty >= idir2 * tend2) 24549 break; 24550 24551 /* March along second curve. Iterate down to the first. */ 24552 24553 sh1783_s9relax (fevalc2, fevalc1, pc2, pc1, kderc, aepsge, ty, &kleftc2, sderc2, tx, 24554 &tpos, &kleftc1, sderc1, jstat); 24555 if (kstat < 0) 24556 goto error; 24557 } 24558 24559 /* Check if point on curve and surface are within positional and 24560 angular tolerances */ 24561 24562 tdist = s6dist (sderc1, sderc2, kdim); 24563 24564 if (tdist > aepsge) 24565 break; /* Points not within tolerances */ 24566 } 24567 24568 if (tdist > aepsge) 24569 break; /* Points not within tolerances */ 24570 24571 /* Update start parameter value of segment. */ 24572 24573 if (kchange == 0) 24574 { 24575 tx1 = tx2; 24576 ty1 = (idir2 > 0) ? MAX(ty1,tpos) : MIN(ty1,tpos); 24577 } 24578 else 24579 { 24580 tx1 = (idir1 > 0) ? MAX(tx1,tpos) : MIN(tx1,tpos); 24581 ty1 = ty2; 24582 } 24583 } 24584 24585 elast[0] = tx1; 24586 elast[1] = ty1; 24587 if (tdist > aepsge) 24588 { 24589 enext[0] = (kchange == 0) ? tx : tpos; 24590 enext[1] = (kchange == 1) ? ty : tpos; 24591 *jstat = 0; 24592 } 24593 else if (idir1 * tx1 >= idir1 * tend1 && idir2 * ty1 >= idir2 * tend2) 24594 *jstat = 3; 24595 else if (idir2 * ty1 >= idir2 * tend2) 24596 *jstat = 2; 24597 else 24598 *jstat = 1; 24599 24600 goto out; 24601 24602 /* Error in input, dimension not equal to 2 or 3 */ 24603 24604 err105:*jstat = -105; 24605 s6err ("sh1783", *jstat, kpos); 24606 goto out; 24607 24608 /* Error in lower level function */ 24609 24610 error:*jstat = kstat; 24611 s6err ("sh1783", *jstat, kpos); 24612 goto out; 24613 24614 out: 24615 return; 24616 } 24617 24618 24619 //=========================================================================== 24620 void sh1780 (SISLObject * po1, SISLObject * po2, double aepsge, 24621 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, 24622 int *jstat) 24623 //=========================================================================== 24624 { 24625 int kstat = 0; /* Status variable. */ 24626 int ki; /* Counters. */ 24627 int kleft1 = 0; /* Parameters to the evaluator. */ 24628 int kdim; /* Dimension of geometry space. */ 24629 int kpos = 0; /* Current position in output array. */ 24630 int kdir1, kdir2; /* Directions in which to march the curves.*/ 24631 int kk1, kk2; /* Orders of the two curves. */ 24632 int kn1, kn2; /* Number of vertices in the curves. */ 24633 int lleft[2]; /* Array storing pre-topology information. */ 24634 int lright[2]; /* Array storing pre-topology information. */ 24635 double tref; /* Reference value in equality test. */ 24636 double *st1, *st2; /* Pointers to knot vectors of curves. */ 24637 double sder[6]; /* Result of curve evaluation. */ 24638 double stang1[3]; /* Tangent vector of curve. */ 24639 double stang2[3]; /* Tangent vector of level value. */ 24640 double slast[3]; /* Last parameter value of coincidence. */ 24641 double snext[3]; /* First parameter value outside interval 24642 of coincidence. */ 24643 double *ret_val; /* Pointer to geo data from sh6getgeom */ 24644 double *ret_norm; /* Pointer to geo data from sh6getgeom */ 24645 double *sptpar = pintpt->epar;/* Parameter array of int.pt. */ 24646 SISLIntpt *uintpt[2]; /* Pointer to new intersection points. */ 24647 double *nullp = SISL_NULL; 24648 24649 /* Don't make pretop for help points ! */ 24650 if (sh6ishelp (pintpt)) 24651 { 24652 *jstat = 0; 24653 goto out; 24654 } 24655 24656 /* Test dimension of geometry space. */ 24657 24658 kdim = po1->c1->idim; 24659 if (kdim > 3) 24660 goto err108; 24661 if (kdim != po2->c1->idim) 24662 goto err106; 24663 24664 /* Express the curve by local parameters. */ 24665 24666 kn1 = po1->c1->in; 24667 kk1 = po1->c1->ik; 24668 st1 = po1->c1->et; 24669 kn2 = po2->c1->in; 24670 kk2 = po2->c1->ik; 24671 st2 = po2->c1->et; 24672 tref = MAX (st1[kn1] - st1[kk1 - 1], st2[kn2] - st2[kk2 - 1]); 24673 24674 /* Fetch already existing topology. */ 24675 sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat); 24676 24677 /* Fetch geometry information, first curve. */ 24678 sh6getgeom (po1, 1, pintpt, &ret_val, &ret_norm, aepsge, &kstat); 24679 if (kstat < 0) 24680 goto error; 24681 24682 /* Local copy of curve tangent */ 24683 memcopy (stang1, ret_val + kdim, kdim, DOUBLE); 24684 24685 /* Fetch geometry information,second curve. */ 24686 sh6getgeom (po2, 2, pintpt, &ret_val, &ret_norm, aepsge, &kstat); 24687 if (kstat < 0) 24688 goto error; 24689 24690 /* Local copy of curve tangent */ 24691 memcopy (stang2, ret_val + kdim, kdim, DOUBLE); 24692 24693 /* Compute the angle between the tangent vectors of the curves 24694 in the current intersection point, and check if marching is 24695 necessary to compute the pre-topology information. */ 24696 24697 /* UPDATE (ujk) : tune */ 24698 if (s6ang (stang1, stang2, kdim) <= ANGULAR_TOLERANCE) 24699 { 24700 /* Perform marching in positive direction of the first curve. */ 24701 24702 kdir1 = 1; 24703 kdir2 = (s6scpr (stang1, stang2, kdim) >= DZERO) ? 1 : -1; 24704 24705 /* Check if the intersection point is situated at the endpoint 24706 of a curve. */ 24707 24708 if (DEQUAL (sptpar[0] + tref, st1[kn1] + tref) || 24709 (kdir2 == 1 && DEQUAL (sptpar[1] + tref, st2[kn2] + tref)) || 24710 (kdir2 == -1 && DEQUAL (sptpar[1] + tref, st2[kk2 - 1] + tref))) 24711 { 24712 } 24713 else 24714 { 24715 /* Perform marching. */ 24716 24717 sh1783 (po1->c1, po2->c1, aepsge, sptpar, kdir1, kdir2, slast, 24718 snext, &kstat); 24719 if (kstat < 0) 24720 goto error; 24721 24722 if (kstat > 0) 24723 { 24724 /* An intersection interval is found. */ 24725 /* Set pre-topology */ 24726 24727 lright[0] = SI_ON; 24728 if (kdir2 == 1) 24729 lright[1] = SI_ON; 24730 else 24731 lleft[1] = SI_ON; 24732 } 24733 else 24734 { 24735 /* Create help point. First fetch geometry information. */ 24736 24737 s1221 (po1->c1, 0, slast[0], &kleft1, sder, &kstat); 24738 if (kstat < 0) 24739 goto error; 24740 24741 s1221 (po1->c1, 0, snext[0], &kleft1, sder + kdim, &kstat); 24742 if (kstat < 0) 24743 goto error; 24744 s6diff (sder + kdim, sder, kdim, stang1); 24745 24746 s1221 (po2->c1, 0, slast[1], &kleft1, sder, &kstat); 24747 if (kstat < 0) 24748 goto error; 24749 24750 s1221 (po2->c1, 0, snext[1], &kleft1, sder + kdim, &kstat); 24751 if (kstat < 0) 24752 goto error; 24753 s6diff (sder + kdim, sder, kdim, stang2); 24754 24755 /* Discuss directions of vectors and set up pre-topology 24756 information in one direction of the curves. */ 24757 24758 if ((stang1[0] * stang2[1] - stang1[1] * stang2[0]) * (double) kdir2 24759 < DZERO) 24760 lright[0] = SI_OUT; 24761 else 24762 lright[0] = SI_IN; 24763 24764 if (kdir2 == 1) 24765 lright[1] = (lright[0] == SI_IN) ? SI_OUT : SI_IN; 24766 else 24767 lleft[1] = (lright[0] == SI_OUT) ? SI_OUT : SI_IN; 24768 24769 /* UPDATE (ujk) : tune */ 24770 if (s6dist (sptpar, slast, 2) > (double) 0.05 * tref) 24771 { 24772 /* Create help point. Set pre-topology data as SI_UNDEF. */ 24773 24774 uintpt[kpos] = SISL_NULL; 24775 if ((uintpt[kpos] = hp_newIntpt (2, slast, DZERO, -SI_ORD, 24776 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 24777 0, 0, nullp, nullp)) == SISL_NULL) 24778 goto err101; 24779 24780 kpos++; 24781 } 24782 } 24783 } 24784 24785 /* Perform marching in negative direction of the first curve. */ 24786 24787 kdir1 = -1; 24788 kdir2 = -kdir2; 24789 24790 /* Check if the intersection point is situated at the endpoint 24791 of a curve. */ 24792 24793 if (DEQUAL (sptpar[0] + tref, st1[kk1 - 1] + tref) || 24794 (kdir2 == 1 && DEQUAL (sptpar[1] + tref, st2[kn2] + tref)) || 24795 (kdir2 == -1 && DEQUAL (sptpar[1] + tref, st2[kk2 - 1] + tref))) 24796 { 24797 } 24798 else 24799 { 24800 /* Perform marching. */ 24801 24802 sh1783 (po1->c1, po2->c1, aepsge, sptpar, kdir1, kdir2, slast, 24803 snext, &kstat); 24804 if (kstat < 0) 24805 goto error; 24806 24807 if (kstat > 0) 24808 { 24809 /* An intersection interval is found. Set pre-topology. */ 24810 24811 lleft[0] = SI_ON; 24812 if (kdir2 == 1) 24813 lright[1] = SI_ON; 24814 else 24815 lleft[1] = SI_ON; 24816 } 24817 else 24818 { 24819 /* Create help point. First fetch geometry information. */ 24820 24821 s1221 (po1->c1, 0, slast[0], &kleft1, sder, &kstat); 24822 if (kstat < 0) 24823 goto error; 24824 24825 s1221 (po1->c1, 0, snext[0], &kleft1, sder + kdim, &kstat); 24826 if (kstat < 0) 24827 goto error; 24828 s6diff (sder + kdim, sder, kdim, stang1); 24829 24830 s1221 (po2->c1, 0, slast[1], &kleft1, sder, &kstat); 24831 if (kstat < 0) 24832 goto error; 24833 24834 s1221 (po2->c1, 0, snext[1], &kleft1, sder + kdim, &kstat); 24835 if (kstat < 0) 24836 goto error; 24837 s6diff (sder + kdim, sder, kdim, stang2); 24838 24839 /* Discuss directions of vectors and set up pre-topology 24840 information in one direction of the curves. */ 24841 24842 if ((stang1[0] * stang2[1] - stang1[1] * stang2[0]) * (double) kdir2 24843 < DZERO) 24844 lleft[0] = SI_OUT; 24845 else 24846 lleft[0] = SI_IN; 24847 24848 if (kdir2 == -1) 24849 lleft[1] = (lleft[0] == SI_IN) ? SI_OUT : SI_IN; 24850 else 24851 lright[1] = (lleft[0] == SI_OUT) ? SI_OUT : SI_IN; 24852 24853 /* UPDATE (ujk) : tune */ 24854 if (s6dist (sptpar, slast, 2) > (double) 0.05 * tref) 24855 { 24856 /* Create help point. Set pre-topology data as SI_UNDEF. */ 24857 24858 uintpt[kpos] = SISL_NULL; 24859 if ((uintpt[kpos] = hp_newIntpt (2, slast, DZERO, -SI_ORD, 24860 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 24861 0, 0, nullp, nullp)) == SISL_NULL) 24862 goto err101; 24863 24864 kpos++; 24865 } 24866 } 24867 } 24868 } 24869 else 24870 { 24871 /* The pretopology may be computed using local information. */ 24872 24873 if (stang1[0] * stang2[1] - stang1[1] * stang2[0] < DZERO) 24874 { 24875 lleft[0] = SI_IN; 24876 lright[0] = SI_OUT; 24877 lleft[1] = SI_OUT; 24878 lright[1] = SI_IN; 24879 } 24880 else 24881 { 24882 lleft[0] = SI_OUT; 24883 lright[0] = SI_IN; 24884 lleft[1] = SI_IN; 24885 lright[1] = SI_OUT; 24886 } 24887 24888 24889 } 24890 24891 /* Update pre-topology of intersection point. */ 24892 /* UPDATE (ujk), index = -1 ?? */ 24893 sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat); 24894 24895 /* Join intersection points, and set pretopology of help points. */ 24896 24897 for (ki = 0; ki < kpos; ki++) 24898 { 24899 sh6idnpt (rintdat, &uintpt[ki], 1, &kstat); 24900 if (kstat < 0) 24901 goto error; 24902 24903 if (sh6ishelp (uintpt[ki]) && uintpt[ki]->no_of_curves == 0) 24904 { 24905 sh6settop (uintpt[ki], -1, *(pintpt->left_obj_1), *(pintpt->right_obj_1), 24906 *(pintpt->left_obj_2), *(pintpt->right_obj_2), &kstat); 24907 24908 /* UPDATE (ujk) : Transfer pintpt to main point ?? */ 24909 /* Mark that an intersection interval is found. */ 24910 sh6idcon (rintdat, &uintpt[ki], &pintpt, &kstat); 24911 if (kstat < 0) 24912 goto error; 24913 } 24914 } 24915 24916 /* Pre-topology information computed. */ 24917 24918 *jnewpt = kpos; 24919 *jstat = 0; 24920 goto out; 24921 24922 /* Error in scratch allocation. */ 24923 24924 err101:*jstat = -101; 24925 goto out; 24926 24927 /* Error in input. Conflicting dimensions. */ 24928 24929 err106:*jstat = -106; 24930 goto out; 24931 24932 /* Error in input. Dimension not equal to 2. */ 24933 24934 err108:*jstat = -108; 24935 goto out; 24936 24937 /* Error lower level routine. */ 24938 24939 error:*jstat = kstat; 24940 goto out; 24941 24942 out: 24943 return; 24944 } 24945 24946 24947 //=========================================================================== 24948 void sh6settop(SISLIntpt *pt,int ilist,int left1,int right1,int left2, 24949 int right2,int *jstat) 24950 //=========================================================================== 24951 { 24952 *jstat=0; 24953 24954 /* Check pt. */ 24955 24956 if(pt == SISL_NULL) goto err2; 24957 24958 /* Check ilist. */ 24959 24960 if(ilist >= 0 && ilist < pt->no_of_curves) 24961 { 24962 pt->left_obj_1[ilist]=left1; 24963 pt->right_obj_1[ilist]=right1; 24964 pt->left_obj_2[ilist]=left2; 24965 pt->right_obj_2[ilist]=right2; 24966 } 24967 else if(pt->no_of_curves == 0 && ilist == 0) 24968 { 24969 pt->left_obj_1[0]=left1; 24970 pt->right_obj_1[0]=right1; 24971 pt->left_obj_2[0]=left2; 24972 pt->right_obj_2[0]=right2; 24973 } 24974 else if(ilist == -1) 24975 { 24976 pt->left_obj_1[0]=left1; 24977 pt->right_obj_1[0]=right1; 24978 pt->left_obj_2[0]=left2; 24979 pt->right_obj_2[0]=right2; 24980 } 24981 else goto err1; 24982 24983 24984 /* Data is set. */ 24985 24986 goto out; 24987 24988 24989 err1: 24990 /* Error. ilist is out of range. */ 24991 24992 *jstat = -1; 24993 s6err("sh6settop",*jstat,0); 24994 goto out; 24995 24996 err2: 24997 /* Error in input. pt is SISL_NULL. */ 24998 24999 *jstat = -2; 25000 s6err("sh6settop",*jstat,0); 25001 goto out; 25002 25003 25004 out : 25005 return; 25006 } 25007 25008 //=========================================================================== 25009 void shevalc(SISLCurve *pc1,int ider,double ax,double aepsge,int *ileft, 25010 double eder[],int *jstat) 25011 //=========================================================================== 25012 { 25013 int kstat=0; /* Local status variable. */ 25014 int kdim = pc1->idim; /* Dimension of geometry space. */ 25015 double *scoef=SISL_NULL; /* Array storing filtered coefficients. */ 25016 double *s1,*s2,*s3,*s4; /* Pointers into coefficient arrays. */ 25017 SISLCurve *qc = SISL_NULL; /* Curve to evaluate. */ 25018 25019 /* Make sure that the filtered coefficients of the curve exist. */ 25020 25021 if (kdim == 1) 25022 { 25023 25024 /* 25025 * PFU 09-94. 25026 * There should never be a rational 1D curve here according to UJK, but 25027 * I (PFU) added a test just in case... 25028 * A rational curve would have caused a memory usage error in newCurve 25029 * when trying to divide out the weights from the coefs. 25030 * This could result in a core dump (division by zero) since the data 25031 * would be "garbage". 25032 * 25033 * If future changes requires this to handle rational 1D curves, this 25034 * must be updated to use rcoef when input is rational. 25035 * 25036 */ 25037 25038 if ( pc1->ikind == 2 || pc1->ikind == 4 ) 25039 goto err151; 25040 25041 /* Create filtered coefficients. */ 25042 25043 if ((scoef = newarray(pc1->in,DOUBLE)) == SISL_NULL) goto err101; 25044 25045 for (s1=pc1->ecoef, s2=scoef, s3=s1+pc1->in; s1<s3; s1=s4) 25046 { 25047 *s2 = *s1; 25048 for (s2++, s4=s1+1; s4<s3; s4++, s2++) 25049 { 25050 if (fabs((*s4)-(*s1)) < aepsge) *s2 = *s1; 25051 else break; 25052 } 25053 } 25054 25055 /* Create curve object. */ 25056 25057 if ((qc = newCurve(pc1->in,pc1->ik,pc1->et,scoef,pc1->ikind, 25058 kdim,0)) == SISL_NULL) goto err101; 25059 } 25060 else 25061 qc = pc1; 25062 25063 /* 25064 * This previously used AN ANACRONISM ('pdir->esmooth') - taken out 25065 * (Confirmed by VSK). 25066 */ 25067 25068 25069 25070 /* Evaluate curve. */ 25071 25072 s1221(qc,ider,ax,ileft,eder,&kstat); 25073 if (kstat < 0) goto error; 25074 25075 /* UJK Let's have a normal exit possibility !*/ 25076 *jstat = 0; 25077 goto out; 25078 25079 25080 /* Error in input (1D rationals is not handled) */ 25081 err151: 25082 *jstat = -151; 25083 goto out; 25084 25085 /* Error in scratch allocation. */ 25086 err101: 25087 *jstat = -101; 25088 goto out; 25089 25090 /* Error in lower level routine. */ 25091 25092 error: 25093 *jstat = kstat; 25094 goto out; 25095 25096 out: 25097 /* Free scratch occupied by local objects. */ 25098 25099 if (scoef != SISL_NULL) freearray(scoef); 25100 if (qc != SISL_NULL && qc != pc1 ) freeCurve(qc); 25101 25102 return; 25103 } 25104 25105 //=========================================================================== 25106 void sh6getgeom(SISLObject *ob, int obnr, SISLIntpt *pt, 25107 double **geom, double **norm, double aepsge, int *jstat) 25108 //=========================================================================== 25109 { 25110 int kgeom; /* Number of doubles pr object describing geometry. */ 25111 int dim; /* Geometric dimension. */ 25112 int kpar; /* Index of the parameter value of the object in pt. */ 25113 int kstat; 25114 int left1=0,left2=0; 25115 double *val; 25116 25117 /* UJK */ 25118 *jstat = 0; 25119 25120 kgeom = (obnr == 1 ? pt->size_1 : pt->size_2); 25121 25122 if (ob->iobj == SISLPOINT) dim = ob->p1->idim; 25123 else if (ob->iobj == SISLCURVE) dim = ob->c1->idim; 25124 else if (ob->iobj == SISLSURFACE) dim = ob->s1->idim; 25125 25126 kpar = (obnr == 1 ? 0 : (pt->ipar - ob->iobj)); 25127 25128 if (!kgeom) 25129 switch(ob->iobj) 25130 { 25131 case SISLPOINT: 25132 (*geom) = ob->p1->ecoef; 25133 (*norm) = SISL_NULL; 25134 return; 25135 case SISLCURVE: 25136 val = newarray(2*dim,DOUBLE); 25137 shevalc(ob->c1,1,pt->epar[kpar],aepsge,&left1,val,&kstat); 25138 if (kstat < 0) goto err1; 25139 if (obnr == 1) 25140 { 25141 pt->geo_data_1 = val; 25142 pt->size_1 = 2*dim; 25143 kgeom = pt->size_1; 25144 } 25145 else 25146 { 25147 pt->geo_data_2 = val; 25148 pt->size_2 = 2*dim; 25149 kgeom = pt->size_2; 25150 } 25151 25152 break; 25153 case SISLSURFACE: 25154 val = newarray(7*dim,DOUBLE); 25155 s1421(ob->s1,2,pt->epar+kpar,&left1,&left2,val,val+6*dim,&kstat); 25156 if (kstat < 0) goto err1; 25157 if (obnr == 1) 25158 { 25159 pt->geo_data_1 = val; 25160 pt->size_1 = (dim == 3 ? 7 : 6)*dim; 25161 kgeom = pt->size_1; 25162 } 25163 else 25164 { 25165 pt->geo_data_2 = val; 25166 pt->size_2 = (dim == 3 ? 7 : 6)*dim; 25167 kgeom = pt->size_2; 25168 } 25169 25170 break; 25171 } 25172 25173 25174 (*geom) = (obnr == 1 ? pt->geo_data_1 : pt->geo_data_2); 25175 25176 if (ob->iobj == SISLSURFACE) (*norm) = (*geom) + kgeom - dim; 25177 else (*norm) = SISL_NULL; 25178 goto out; 25179 25180 err1: *jstat = kstat; 25181 goto out; 25182 25183 out : 25184 return; 25185 } 25186 25187 25188 //=========================================================================== 25189 void sh6gettop(SISLIntpt *pt,int ilist,int *left1,int *right1, 25190 int *left2,int *right2,int *jstat) 25191 //=========================================================================== 25192 { 25193 *jstat=0; 25194 25195 /* Check pt. */ 25196 25197 if(pt == SISL_NULL) goto err2; 25198 25199 if(ilist >= 0 && ilist < pt->no_of_curves) 25200 { 25201 *left1=pt->left_obj_1[ilist]; 25202 *right1=pt->right_obj_1[ilist]; 25203 *left2=pt->left_obj_2[ilist]; 25204 *right2=pt->right_obj_2[ilist]; 25205 } 25206 else if(pt->no_of_curves == 0 && ilist == 0) 25207 { 25208 *left1=pt->left_obj_1[0]; 25209 *right1=pt->right_obj_1[0]; 25210 *left2=pt->left_obj_2[0]; 25211 *right2=pt->right_obj_2[0]; 25212 } 25213 /* UJK */ 25214 else if( ilist == -1) 25215 { 25216 *left1=pt->left_obj_1[0]; 25217 *right1=pt->right_obj_1[0]; 25218 *left2=pt->left_obj_2[0]; 25219 *right2=pt->right_obj_2[0]; 25220 } 25221 else goto err1; 25222 25223 25224 /* Data is set. */ 25225 25226 goto out; 25227 25228 25229 err1: 25230 /* Error. ilist is out of range. */ 25231 25232 *jstat = -1; 25233 s6err("sh6gettop",*jstat,0); 25234 goto out; 25235 25236 err2: 25237 /* Error in input. pt is SISL_NULL. */ 25238 25239 *jstat = -2; 25240 s6err("sh6gettop",*jstat,0); 25241 goto out; 25242 25243 25244 out : 25245 return; 25246 } 25247 25248 25249 //=========================================================================== 25250 void sh1781 (SISLObject * po1, SISLObject * po2, double aepsge, 25251 SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt, 25252 int *jstat) 25253 //=========================================================================== 25254 { 25255 int kstat = 0; /* Status variable. */ 25256 int ki, kj; /* Counters. */ 25257 int kleft = 0; /* Parameter to evaluator. */ 25258 int korgleft = 0; /* Knot index. */ 25259 int kdim; /* Dimension of geometry space. */ 25260 int kn; /* Number of vertices of curve. */ 25261 int kk; /* Order of curve. */ 25262 int kpos = 0; /* Current position in int.pt. array. */ 25263 int lleft[2]; /* Array storing pre-topology information. */ 25264 int lright[2]; /* Array storing pre-topology information. */ 25265 int *ll1, *ll2, *lr1, *lr2; /* Pointers into pre-topology arrays. */ 25266 double tpoint; /* Level value. */ 25267 double tpar0,tpar; /* Parameter value of point on curve. */ 25268 double spar[1]; /* Parameter value of endpoint of curve. */ 25269 double sder[2]; /* Result of curve evaluation. */ 25270 double stang1[2]; /* Tangent vector of curve. */ 25271 double stang2[2]; /* Tangent vector of level value. */ 25272 double *st; /* Pointer to knot vector of curve. */ 25273 double *sptpar = pintpt->epar;/* Pointer to parameter array of int.pt. */ 25274 double tref; /* Referance value in equality test. */ 25275 SISLCurve *qc; /* Pointer to current curve. */ 25276 SISLIntpt *uintpt[2]; /* Array storing new intersection points. */ 25277 double *ret_val; /* Pointer to geo data from sh6getgeom */ 25278 double *ret_norm; /* Pointer to geo data from sh6getgeom */ 25279 double *nullp = SISL_NULL; 25280 int make_hp; /* Flag, make/not make help pt. */ 25281 25282 /* Don't make pretop for help points ! */ 25283 if (sh6ishelp (pintpt)) 25284 { 25285 *jstat = 0; 25286 goto out; 25287 } 25288 25289 /* Set pointers into the arrays storing pre-topology information. */ 25290 25291 if (po1->iobj == SISLCURVE) 25292 { 25293 ll1 = lleft; 25294 lr1 = lright; 25295 ll2 = lleft + 1; 25296 lr2 = lright + 1; 25297 } 25298 else 25299 { 25300 ll1 = lleft + 1; 25301 lr1 = lright + 1; 25302 ll2 = lleft; 25303 lr2 = lright; 25304 } 25305 25306 /* Get pre-topology information. */ 25307 sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat); 25308 if (kstat < 0) 25309 goto error; 25310 25311 /* Test dimension of geometry space. */ 25312 if (po1->iobj == SISLCURVE) 25313 { 25314 qc = po1->c1; 25315 } 25316 else 25317 { 25318 qc = po2->c1; 25319 } 25320 25321 kdim = qc->idim; 25322 if (kdim != 1) 25323 goto err106; 25324 25325 /* Store curve information in local parameters. */ 25326 25327 kn = qc->in; 25328 kk = qc->ik; 25329 st = qc->et; 25330 tref = st[kn] - st[kk - 1]; 25331 25332 /* Fetch geometry information, point. */ 25333 sh6getgeom ((po1->iobj == SISLPOINT) ? po1 : po2, 25334 (po1->iobj == SISLPOINT) ? 1 : 2, 25335 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 25336 if (kstat < 0) 25337 goto error; 25338 25339 tpoint = ret_val[0]; 25340 25341 /* Fetch geometry information, curve. */ 25342 sh6getgeom ((po1->iobj == SISLCURVE) ? po1 : po2, 25343 (po1->iobj == SISLCURVE) ? 1 : 2, 25344 pintpt, &ret_val, &ret_norm, aepsge, &kstat); 25345 if (kstat < 0) 25346 goto error; 25347 25348 s1219(st,kk,kn,&korgleft,sptpar[0],&kstat); 25349 if (kstat < 0) goto error; 25350 25351 sder[0] = ret_val[0]; 25352 sder[1] = ret_val[1]; 25353 25354 /* Set tangent vectors. */ 25355 25356 stang1[0] = (double) 1.0; 25357 stang1[1] = ret_val[1]; 25358 stang2[0] = (double) 1.0; 25359 stang2[1] = DZERO; 25360 25361 /* UPDATE (ujk) : tune */ 25362 if (s6ang (stang1, stang2, 2) > 0.001*ANGULAR_TOLERANCE) 25363 { 25364 /* Compute pre-topology using local information. */ 25365 25366 if (sder[1] > 0) 25367 { 25368 *ll1 = SI_IN; 25369 *lr1 = SI_OUT; 25370 *ll2 = SI_OUT; 25371 *lr2 = SI_IN; 25372 } 25373 else 25374 { 25375 *ll1 = SI_OUT; 25376 *lr1 = SI_IN; 25377 *ll2 = SI_IN; 25378 *lr2 = SI_OUT; 25379 } 25380 25381 } 25382 else 25383 { 25384 /* Test if the intersection point lies at the endpoint of 25385 the curve. */ 25386 25387 if (DEQUAL (sptpar[0] + tref, st[kn] + tref)) 25388 { 25389 25390 } 25391 else 25392 { 25393 /* Find endpoint of coincidence interval in the positive 25394 direction of the curve. */ 25395 25396 ki = 0; 25397 tpar = sptpar[0] + (double) 2.0 *sqrt (aepsge); 25398 tpar = min (tpar, st[kn]); 25399 tpar0 = tpar = min (tpar, st[korgleft+1]); 25400 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 25401 if (fabs (sder[0] - tpoint) <= aepsge) 25402 { 25403 make_hp = TRUE; 25404 for (ki = kleft - kk + 1; ki < kn; ki++) 25405 { 25406 for (tpar = DZERO, kj = ki + 1; kj < ki + kk; kj++) 25407 tpar += st[kj]; 25408 tpar /= (double) (kk - 1); 25409 25410 if (tpar > sptpar[0] && DNEQUAL(tpar,sptpar[0])) 25411 { 25412 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 25413 if (fabs (sder[0] - tpoint) >= aepsge) 25414 break; 25415 25416 tpar0 = tpar; /* Remember parameter value. */ 25417 } 25418 } 25419 } 25420 /*UJK, sept 92, don't make help pt close to main */ 25421 else make_hp = FALSE; 25422 25423 /* Test if there is coincidence along the entire curve part. */ 25424 25425 if (ki == kn) 25426 { 25427 /* Set right values of original point. */ 25428 *lr1 = *lr2 = SI_ON; 25429 } 25430 else 25431 { 25432 /* Compute right values of intersection point. */ 25433 *lr1 = (sder[0] > tpoint) ? SI_OUT : SI_IN; 25434 *lr2 = (*lr1 == SI_IN) ? SI_OUT : SI_IN; 25435 25436 /*UJK, sept 92, don't make help pt close to main */ 25437 if (make_hp) 25438 { 25439 /* Create help point. */ 25440 if (sptpar[0] < st[kleft]) 25441 spar[0] = MIN(tpar0,st[kleft]); 25442 else 25443 spar[0] = tpar0; 25444 25445 uintpt[kpos] = SISL_NULL; 25446 if ((uintpt[kpos] = hp_newIntpt (1, spar, DZERO, -SI_ORD, 25447 SI_ON, lright[0], SI_ON, 25448 lright[1], 0, 0, nullp, nullp)) == SISL_NULL) 25449 goto err101; 25450 25451 /* Insert the point into the data structure. */ 25452 25453 sh6idnpt (rintdat, &uintpt[kpos], 1, &kstat); 25454 if (kstat < 0) 25455 goto error; 25456 25457 kpos++; 25458 } 25459 } 25460 } 25461 25462 /* Test if the intersection point lies at the startpoint 25463 of the curve. */ 25464 25465 if (DEQUAL (sptpar[0] + tref, st[kk - 1] + tref)) 25466 { 25467 } 25468 else 25469 { 25470 /* Find endpoint of coincidence interval in the negative 25471 direction of the curve. */ 25472 25473 ki = kn; 25474 while (sptpar[0] == st[korgleft]) korgleft--; 25475 tpar = sptpar[0] - (double) 2.0 *sqrt (aepsge); 25476 tpar = max (tpar, st[kk - 1]); 25477 tpar0 = tpar = max (tpar, st[korgleft]); 25478 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 25479 if (fabs (sder[0] - tpoint) <= aepsge) 25480 { 25481 make_hp = TRUE; 25482 for (ki = kleft; ki >= 0; ki--) 25483 { 25484 for (tpar = DZERO, kj = ki + 1; kj < ki + kk; kj++) 25485 tpar += st[kj]; 25486 tpar /= (double) (kk - 1); 25487 25488 if (tpar < sptpar[0] && DNEQUAL(tpar,sptpar[0])) 25489 { 25490 shevalc (qc, 0, tpar, aepsge, &kleft, sder, &kstat); 25491 if (fabs (sder[0] - tpoint) >= aepsge) 25492 break; 25493 25494 tpar0 = tpar; 25495 } 25496 } 25497 } 25498 /*UJK, sept 92, don't make help pt close to main */ 25499 else make_hp = FALSE; 25500 25501 /* Test if there is coincidence along the entire curve part. */ 25502 if (ki < 0) 25503 { 25504 /* Set left values of original point. */ 25505 *ll1 = *ll2 = SI_ON; 25506 } 25507 else 25508 { 25509 /* Compute left values of intersection point. */ 25510 25511 *ll1 = (sder[0] > tpoint) ? SI_OUT : SI_IN; 25512 *ll2 = (*ll1 == SI_IN) ? SI_OUT : SI_IN; 25513 25514 /*UJK, sept 92, don't make help pt close to main */ 25515 if (make_hp) 25516 { 25517 /* Create intersection point. */ 25518 if (sptpar[0] > st[kleft+1]) 25519 spar[0] = MAX(tpar0,st[kleft+1]); 25520 else 25521 spar[0] = tpar0; 25522 25523 uintpt[kpos] = SISL_NULL; 25524 if ((uintpt[kpos] = hp_newIntpt (1, spar, DZERO, -SI_ORD, 25525 lleft[0], SI_ON, lleft[1], 25526 SI_ON, 0, 0, nullp, nullp)) == SISL_NULL) 25527 goto err101; 25528 25529 /* Insert the point into the data structure. */ 25530 25531 sh6idnpt (rintdat, &uintpt[kpos], 1, &kstat); 25532 if (kstat < 0) 25533 goto error; 25534 25535 25536 kpos++; 25537 } 25538 25539 } 25540 25541 } 25542 } 25543 25544 /* Update pretopology of intersection point. */ 25545 25546 sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat); 25547 if (kstat < 0) 25548 goto error; 25549 /* Change, if necessary, pintpt to mainpoint */ 25550 sh6tomain (pintpt, &kstat); 25551 25552 /* Join intersection points. (kpos=0,1,2)*/ 25553 for (ki = 0; ki < kpos; ki++) 25554 { 25555 sh6idnpt (rintdat, &uintpt[ki], 1, &kstat); 25556 if (kstat < 0) 25557 goto error; 25558 /* Mark that an intersection interval is found. */ 25559 if (sh6ishelp (uintpt[ki]) && uintpt[ki]->no_of_curves == 0) 25560 { 25561 sh6idcon (rintdat, &uintpt[ki], &pintpt, &kstat); 25562 if (kstat < 0) 25563 goto error; 25564 } 25565 } 25566 25567 /* Pre-topology information computed. */ 25568 25569 *jnewpt = kpos; 25570 *jstat = 0; 25571 goto out; 25572 25573 /* Error in scratch allocation. */ 25574 25575 err101:*jstat = -101; 25576 goto out; 25577 25578 /* Error in input. Incorrect dimension. */ 25579 25580 err106:*jstat = -106; 25581 goto out; 25582 25583 /* Error lower level routine. */ 25584 25585 error:*jstat = kstat; 25586 goto out; 25587 25588 out: 25589 return; 25590 } 25591 25592 25593 //=========================================================================== 25594 void s6idint(SISLObject *po1,SISLObject *po2,SISLIntdat *pintdat,SISLIntpt **rpt, 25595 int iob) 25596 //=========================================================================== 25597 { 25598 register int ki,kj; 25599 int kpar1,kpar2; 25600 double sstart1[2],send1[2]; 25601 double sstart2[2],send2[2]; 25602 25603 25604 /* Initiate to emty list. */ 25605 25606 *rpt = SISL_NULL; 25607 25608 25609 /* We have to be sure that we have an intdat structure. */ 25610 25611 if (pintdat == SISL_NULL) 25612 goto out; 25613 25614 25615 if (po1 == SISL_NULL || po1->iobj == SISLPOINT) 25616 kpar1 = 0; 25617 else if (po1->iobj == SISLCURVE) 25618 { 25619 kpar1 = 1; 25620 sstart1[0] = po1->c1->et[po1->c1->ik-1]; 25621 send1[0] = po1->c1->et[po1->c1->in]; 25622 } 25623 else if (po1->iobj == SISLSURFACE) 25624 { 25625 kpar1 = 2; 25626 sstart1[0] = po1->s1->et1[po1->s1->ik1-1]; 25627 send1[0] = po1->s1->et1[po1->s1->in1]; 25628 sstart1[1] = po1->s1->et2[po1->s1->ik2-1]; 25629 send1[1] = po1->s1->et2[po1->s1->in2]; 25630 } 25631 25632 25633 if (po2 == SISL_NULL || po2->iobj == SISLPOINT) 25634 kpar2 = 0; 25635 else if (po2->iobj == SISLCURVE) 25636 { 25637 kpar2 = 1; 25638 sstart2[0] = po2->c1->et[po2->c1->ik-1]; 25639 send2[0] = po2->c1->et[po2->c1->in]; 25640 } 25641 else if (po2->iobj == SISLSURFACE) 25642 { 25643 kpar2 = 2; 25644 sstart2[0] = po2->s1->et1[po2->s1->ik1-1]; 25645 send2[0] = po2->s1->et1[po2->s1->in1]; 25646 sstart2[1] = po2->s1->et2[po2->s1->ik2-1]; 25647 send2[1] = po2->s1->et2[po2->s1->in2]; 25648 } 25649 25650 25651 if (iob == 1 && kpar1 == 0) 25652 goto out; 25653 25654 if (iob == 2 && kpar2 == 0) 25655 goto out; 25656 25657 25658 /* We have to go trough all intersection points to search for internal 25659 intersection points. */ 25660 25661 for (ki=pintdat->ipoint-1; ki>=0; ki--) 25662 { 25663 for (kj=0; kj<kpar1; kj++) 25664 if (sstart1[kj] > pintdat->vpoint[ki]->epar[kj] || 25665 send1[kj] < pintdat->vpoint[ki]->epar[kj]) 25666 goto end; 25667 for (kj=0; kj<kpar2; kj++) 25668 if (sstart2[kj] > pintdat->vpoint[ki]->epar[kpar1+kj] || 25669 send2[kj] < pintdat->vpoint[ki]->epar[kpar1+kj]) 25670 goto end; 25671 25672 if (iob == 1) 25673 { 25674 for (kj=0; kj<kpar1; kj++) 25675 if (DEQUAL(sstart1[kj],pintdat->vpoint[ki]->epar[kj]) || 25676 DEQUAL(send1[kj],pintdat->vpoint[ki]->epar[kj])) 25677 goto end; 25678 } 25679 else 25680 { 25681 for (kj=0; kj<kpar2; kj++) 25682 if (DEQUAL(sstart2[kj],pintdat->vpoint[ki]->epar[kpar1+kj]) || 25683 DEQUAL(send2[kj],pintdat->vpoint[ki]->epar[kpar1+kj])) 25684 goto end; 25685 } 25686 25687 25688 (*rpt) = pintdat->vpoint[ki]; 25689 goto out; 25690 end:; 25691 } 25692 out:; 25693 } 25694 25695 25696 //=========================================================================== 25697 void shmkhlppts (SISLObject * po1, SISLObject * po2, double aepsge, 25698 SISLIntdat ** rintdat, SISLEdge * vedge[], int *jnewpt, 25699 int *jstat) 25700 //=========================================================================== 25701 { 25702 int kstat = 0; /* Status variable. */ 25703 int knum = 0; /* Number of intpt on edges. */ 25704 int ki; /* Counter. */ 25705 int kdim; /* Dimension of geometry space. */ 25706 int knewpt = 0; /* Number of new intersection points. */ 25707 int kobj; /* Number of obj, used in s6idint */ 25708 int index1, index2; /* Dummy in this context */ 25709 SISLIntpt **up = SISL_NULL; /* Array of poiners to intersection point. */ 25710 /* SISLIntpt *lup[3];*/ /* Array of poiners to intersection point. */ 25711 SISLIntpt *qptint = SISL_NULL; /* Pointer to internal intersection point. */ 25712 SISLIntpt *qpt = SISL_NULL; /* Pointer to intersection point. */ 25713 /* --------------------------------------------------------------------- */ 25714 25715 /* Init */ 25716 *jstat = 0; 25717 *jnewpt = 0; 25718 25719 /* Test if an intersection data structure exist. */ 25720 if (*rintdat == SISL_NULL) 25721 goto out; 25722 25723 25724 /* Fetch dimension of geometry space. */ 25725 if (po1->iobj == SISLPOINT) 25726 25727 kdim = po1->p1->idim; 25728 else if (po1->iobj == SISLCURVE) 25729 kdim = po1->c1->idim; 25730 else 25731 kdim = po1->s1->idim; 25732 25733 /* Treat only cases: 25734 crv vs pt 1D 25735 crv vs crv 25736 crv vs sf 25737 crv vs pt 2D 25738 sf vs pt 2D 25739 */ 25740 25741 if (!(((po1->iobj == SISLCURVE && po2->iobj >= SISLCURVE) || 25742 (po2->iobj == SISLCURVE && po1->iobj >= SISLCURVE)) || 25743 (kdim == 1 && (po1->iobj + po2->iobj) == (SISLPOINT + SISLCURVE)) || 25744 (kdim == 2 && (po1->iobj + po2->iobj) >= (SISLPOINT + SISLCURVE)))) 25745 goto out; 25746 25747 /* Compute number of intersection points on edges, 0 1 or 2. */ 25748 if (vedge[0] == SISL_NULL) 25749 knum = 0; 25750 else 25751 knum = vedge[0]->ipoint; 25752 25753 if (vedge[1] != SISL_NULL) 25754 knum += vedge[1]->ipoint; 25755 25756 25757 if (knum > 0) 25758 { 25759 sh6edgpoint (vedge, &up, &knum, &kstat); 25760 if (kstat < 0) 25761 goto error; 25762 } 25763 25764 if (knum == 2) 25765 { 25766 /* when two edge points, check if they are connected */ 25767 sh6getlist (up[0], up[1], &index1, &index2, &kstat); 25768 if (kstat == 0) 25769 knum = 0; 25770 } 25771 25772 if (knum == 0) /* BOH & ALA Added: 200993 */ 25773 { 25774 /* Task performed. */ 25775 25776 *jstat = 0; 25777 goto out; 25778 } 25779 25780 /* Copy pointer of edge points into local pointer array */ 25781 /*for (ki = 0; ki < knum; ki++) 25782 25783 lup[ki] = up[ki]; */ 25784 25785 /* Get the internal point if any */ 25786 if (po1->iobj == SISLPOINT) 25787 kobj = 2; 25788 else 25789 kobj = 1; 25790 25791 s6idint (po1, po2, *rintdat, &qptint, kobj); 25792 if (qptint) 25793 { 25794 qpt = qptint; 25795 ki=-1; 25796 } 25797 else 25798 { 25799 ki = 0; 25800 qpt = up[0]; 25801 } 25802 25803 for (; ki < knum; ki++ ) 25804 { 25805 25806 if (ki >= 0) qpt = up[ki]; 25807 25808 /* Browse on the dimension of geometry space and the type of 25809 the input objects. */ 25810 25811 if (kdim == 1 && ((po1->iobj == SISLCURVE && po2->iobj == SISLPOINT) 25812 || (po2->iobj == SISLCURVE && po1->iobj == SISLPOINT))) 25813 { 25814 /* Compute pre-topology in one-dimensional curve-level value 25815 intersection. */ 25816 25817 sh1781 (po1, po2, aepsge, rintdat, qpt, &knewpt, &kstat); 25818 if (kstat < 0) 25819 goto error; 25820 *jnewpt += knewpt; 25821 } 25822 else if (po1->iobj == SISLCURVE && po2->iobj == SISLCURVE) 25823 { 25824 /* curve-curve intersection. */ 25825 sh1780 (po1, po2, aepsge, rintdat, qpt, &knewpt, &kstat); 25826 if (kstat < 0) 25827 goto error; 25828 *jnewpt += knewpt; 25829 } 25830 else if (kdim == 2 && 25831 ((po1->iobj == SISLCURVE && po2->iobj == SISLPOINT) 25832 || (po2->iobj == SISLCURVE && po1->iobj == SISLPOINT))) 25833 { 25834 /* 2 dimensional point-curve intersection. */ 25835 25836 sh1786 (po1, po2, aepsge, rintdat, qpt, &knewpt, &kstat); 25837 if (kstat < 0) 25838 goto error; 25839 *jnewpt += knewpt; 25840 } 25841 else if (kdim == 2 && 25842 ((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT) 25843 || (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT))) 25844 { 25845 /* 2 dimensional point-surface intersection. */ 25846 25847 sh1787 (po1, po2, aepsge, rintdat, qpt, &knewpt, &kstat); 25848 if (kstat < 0) 25849 goto error; 25850 *jnewpt += knewpt; 25851 } 25852 else if (kdim == 3 && 25853 ((po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE) || 25854 (po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE))) 25855 { 25856 /* Surface-curve intersection in 3-dimensional geometry space. */ 25857 25858 sh1779 (po1, po2, aepsge, rintdat, qpt, &knewpt, &kstat); 25859 if (kstat < 0) 25860 goto error; 25861 *jnewpt += knewpt; 25862 25863 } 25864 } 25865 25866 /* Task performed. */ 25867 25868 *jstat = 0; 25869 goto out; 25870 25871 /* Error in lower level routine. */ 25872 25873 error:*jstat = kstat; 25874 goto out; 25875 25876 out: 25877 if (up != SISL_NULL) 25878 freearray (up); 25879 25880 return; 25881 } 25882 25883 25884 //=========================================================================== 25885 void sh6tohelp(SISLIntpt *pt,int *jstat) 25886 //=========================================================================== 25887 { 25888 int kstat; /* Local status */ 25889 int num; 25890 25891 *jstat=0; 25892 25893 if(pt == SISL_NULL) goto err1; 25894 25895 if(sh6ismain(pt)) /* If pt is a help point. */ 25896 { 25897 /* ??????????? */ 25898 /* if(pt->no_of_curves > 2) goto err2; */ 25899 25900 num=sh6nmbmain(pt,&kstat); 25901 /* Problem in sh6edgred when starting reduction */ 25902 /* if(num > 1) goto err2; */ 25903 25904 pt->iinter = -pt->iinter; /* Convert status to main point. */ 25905 } 25906 else 25907 { 25908 *jstat=1; 25909 } 25910 25911 goto out; 25912 25913 25914 err1: 25915 /* Error in input. pt is null. */ 25916 25917 *jstat = -1; 25918 s6err("sh6tohelp",*jstat,0); 25919 goto out; 25920 25921 /* Error, Illegal to change status. */ 25922 25923 /* err2: 25924 *jstat = -2; 25925 s6err("sh6tohelp",*jstat,0); 25926 goto out; */ 25927 25928 25929 out : 25930 return; 25931 } 25932 25933 25934 //=========================================================================== 25935 double s1173_s9del(double *eco, double *eco1, double *eco2, int idim) 25936 //=========================================================================== 25937 { 25938 double t1,t2,t3,t4,t5,t6; /* Constants in equation. */ 25939 25940 t1 = s6scpr(eco,eco1,idim); 25941 t3 = s6scpr(eco1,eco1,idim); 25942 t2 = t3 - s6scpr(eco,eco2,idim); 25943 t4 = -(double)2 * s6scpr(eco1,eco2,idim); 25944 25945 25946 25947 if (DEQUAL(t4,DZERO)) /* The second degree part is degenerated. */ 25948 { 25949 if (DEQUAL(t2,DZERO)) 25950 { 25951 if (DEQUAL(t3,DZERO)) return DZERO; 25952 else return (t1/t3); 25953 } 25954 else return (t1/t2); 25955 } 25956 else /* An ordinary second degree equation. */ 25957 { 25958 t5 = t2*t2 - (double)2*t4*t1; 25959 if (t5 < DZERO) return (t1/t3); 25960 else 25961 { 25962 t6 = sqrt(t5); 25963 t5 = (t2 + t6)/t4; 25964 t6 = (t2 - t6)/t4; 25965 t1 *= t3; 25966 25967 25968 /* We have two solutions and we want to use the one 25969 with the same sign as we get while using an other 25970 metode t1/t3. If both solutions have the same 25971 sign we use the one with smallest value. */ 25972 25973 if (t1 < DZERO) 25974 { 25975 if (t5 <= DZERO && t6 <= DZERO) 25976 { 25977 if (t5 > t6) return t5; 25978 else return t6; 25979 } 25980 else if (t5 <= DZERO) return t5; 25981 else if (t6 <= DZERO) return t6; 25982 else return min(t5,t6); 25983 } 25984 else if (t1 > DZERO) 25985 { 25986 if (t5 >= DZERO && t6 >= DZERO) 25987 { 25988 if (t5 < t6) return t5; 25989 else return t6; 25990 } 25991 else if (t5 >= DZERO) return t5; 25992 else if (t6 >= DZERO) return t6; 25993 else return max(t5,t6); 25994 } 25995 else return min(fabs(t5),fabs(t6)); 25996 } 25997 } 25998 } 25999 26000 26001 26002 //=========================================================================== 26003 void s1173_s9dir(double *cdist, double *cdiff1, double *cdiff2, 26004 double gdiff[], double evalp[], double evals[], double aepsge) 26005 //=========================================================================== 26006 { 26007 int kstat=0; /* Local status variable. */ 26008 double tdiv; /* Determinant */ 26009 double ta11,ta12,ta21,ta22; /* The matrix */ 26010 double tmax; /* The largest value in matrix */ 26011 double tb1,tb2; /* The right hand side. */ 26012 double tval,tderx,tderxx; /* Function and deriv. 26013 values in one-dimentional case */ 26014 double tdery,tderyy; 26015 double tderxy; 26016 double tdeltax,tdeltay; /* Locals for the step value to be determined. */ 26017 double ttemp; /* Temporary value. */ 26018 26019 if (aepsge < 0) kstat=1; 26020 26021 /* Computing the different vector */ 26022 s6diff(evalp,evals,1,gdiff); 26023 26024 /* Computing the length of the different vector. */ 26025 *cdist = s6length(gdiff,1,&kstat); 26026 26027 /* Init */ 26028 tval = evals[0]; 26029 tderx = evals[1]; 26030 tdery = evals[2]; 26031 tderxx = evals[3]; 26032 tderxy = evals[4]; 26033 tderyy = evals[5]; 26034 tdeltax = DZERO; 26035 tdeltay = DZERO; 26036 *cdiff1 = DZERO; 26037 *cdiff2 = DZERO; 26038 26039 26040 /* Building the matrix. */ 26041 26042 ta11 = (gdiff[0]*tderxx - tderx*tderx); 26043 ta12 = (gdiff[0]*tderxy - tderx*tdery); 26044 ta21 = (gdiff[0]*tderxy - tderx*tdery); 26045 ta22 = (gdiff[0]*tderyy - tdery*tdery); 26046 tb1 = -gdiff[0]*tderx; 26047 tb2 = -gdiff[0]*tdery; 26048 26049 if (DEQUAL(tb1,DZERO) && DEQUAL(tb2,DZERO)) 26050 { 26051 /* Finished, we have found a max. */ 26052 } 26053 else 26054 { 26055 tdiv = ta11*ta22 - ta21*ta12; 26056 tmax = max(fabs(ta11),max(fabs(ta12),max(fabs(ta21),fabs(ta22)))); 26057 26058 if (fabs(tdiv) > tmax*REL_COMP_RES) 26059 { 26060 /* The matrix is ok, solve the system using Cramers rule. */ 26061 tdeltax = tb1*ta22 - tb2*ta12; 26062 tdeltay = ta11*tb2 - ta21*tb1; 26063 tdeltax /= tdiv; 26064 tdeltay /= tdiv; 26065 } 26066 else 26067 { 26068 /* The matrix is nearly singular, 26069 use Newton on each parameter direction*/ 26070 tdeltax = s1173_s9del(gdiff,&tderx,&tderxx,1); 26071 tdeltay = s1173_s9del(gdiff,&tdery,&tderyy,1); 26072 26073 26074 if (fabs(tdeltax) < REL_COMP_RES || fabs(tdeltay) < REL_COMP_RES ) 26075 /* If one is very small, we use them as they are. */ 26076 ; 26077 else 26078 { 26079 /* Use the shortest step; min (1-k)Dx + kDy */ 26080 ttemp = tdeltay*tdeltax/(tdeltax*tdeltax + tdeltay*tdeltay); 26081 tdeltax = tdeltay*ttemp; 26082 tdeltay = tdeltax*ttemp; 26083 26084 } 26085 26086 } 26087 } 26088 26089 *cdiff1 = tdeltax; 26090 *cdiff2 = tdeltay; 26091 26092 } 26093 26094 26095 //=========================================================================== 26096 void s1173_s9corr(double gd[], double acoef1,double acoef2,double astart1, 26097 double aend1,double astart2, double aend2) 26098 //=========================================================================== 26099 { 26100 if (acoef1 + gd[0] < astart1) gd[0] = astart1 - acoef1; 26101 else if (acoef1 + gd[0] > aend1) gd[0] = aend1 - acoef1; 26102 26103 if (acoef2 + gd[1] < astart2) gd[1] = astart2 - acoef2; 26104 else if (acoef2 + gd[1] > aend2) gd[1] = aend2 - acoef2; 26105 } 26106 26107 26108 //=========================================================================== 26109 void s1173(SISLPoint *ppoint, SISLSurf *psurf, double aepsge,double estart[], 26110 double eend[], double enext[], double gpos[],int *jstat) 26111 //=========================================================================== 26112 { 26113 int kstat = 0; /* Local status variable. */ 26114 int kpos = 0; /* Position of error. */ 26115 int kleft1=0; /* Variables used in the evaluator. */ 26116 int kleft2=0; /* Variables used in the evaluator. */ 26117 int kder=2; /* Order of derivatives to be calulated */ 26118 int kdim=1; /* Dimension of space the surface lies in */ 26119 int knbit; /* Number of iterations */ 26120 int kdir; /* Changing direction. */ 26121 double tdelta[2]; /* Parameter intervals of the surface. */ 26122 double tdist; /* Distance between position and origo. */ 26123 double td[2],t1[2],tdn[2];/* Distances between old and new parameter 26124 value in the tree parameter directions. */ 26125 double tprev; /* Previous difference between the curves. */ 26126 double *sval =SISL_NULL; /* Value ,first and second derivatiev of surf. */ 26127 double *sdiff; /* Difference between the point and the surf. */ 26128 double *snorm; /* Normal vector of the surface, dummy. */ 26129 double snext[2]; /* Parameter values */ 26130 26131 /* Test input. */ 26132 26133 if (ppoint->idim != psurf->idim) goto err106; 26134 if (ppoint->idim != kdim) goto err106; 26135 26136 /* Fetch endpoints and the intervals of parameter interval of curves. */ 26137 26138 tdelta[0] = psurf->et1[psurf->in1] - psurf->et1[psurf->ik1 - 1]; 26139 tdelta[1] = psurf->et2[psurf->in2] - psurf->et2[psurf->ik2 - 1]; 26140 26141 26142 /* Allocate local used memory */ 26143 26144 sval = newarray(8*kdim,double); 26145 if (sval == SISL_NULL) goto err101; 26146 26147 sdiff = sval + 6*kdim; 26148 snorm = sdiff + kdim; 26149 26150 /* Initiate variables. */ 26151 26152 tprev = (double)HUGE; 26153 26154 26155 /* Evaluate 0-1.st derivatives of surface */ 26156 26157 s1421(psurf,kder,enext,&kleft1,&kleft2,sval,snorm,&kstat); 26158 if (kstat < 0) goto error; 26159 26160 /* Compute the distanse vector and value and the new step. */ 26161 26162 s1173_s9dir(&tdist,td,td+1,sdiff,ppoint->ecoef,sval,aepsge); 26163 26164 26165 /* Correct if we are not inside the parameter intervall. */ 26166 26167 26168 t1[0] = td[0]; 26169 t1[1] = td[1]; 26170 s1173_s9corr(t1,enext[0],enext[1],estart[0],eend[0],estart[1],eend[1]); 26171 26172 26173 /* Iterate to find the intersection point. */ 26174 26175 for (knbit = 0; knbit < 50; knbit++) 26176 { 26177 /* Evaluate 0-1.st derivatives of surface */ 26178 26179 snext[0] = enext[0] + t1[0]; 26180 snext[1] = enext[1] + t1[1]; 26181 26182 s1421(psurf,kder,snext,&kleft1,&kleft2,sval,snorm,&kstat); 26183 if (kstat < 0) goto error; 26184 26185 26186 /* Compute the distanse vector and value and the new step. */ 26187 26188 s1173_s9dir(&tdist,tdn,tdn+1,sdiff,ppoint->ecoef,sval,aepsge); 26189 26190 26191 /* Check if the direction of the step have change. */ 26192 26193 kdir = (s6scpr(td,tdn,2) >= DZERO); /* 0 if changed. */ 26194 26195 26196 /* Ordinary converging. */ 26197 26198 if (tdist <= tprev || kdir) 26199 { 26200 enext[0] += t1[0]; 26201 enext[1] += t1[1]; 26202 26203 td[0] = t1[0] = tdn[0]; 26204 td[1] = t1[1] = tdn[1]; 26205 26206 /* Correct if we are not inside the parameter intervall. */ 26207 26208 s1173_s9corr(t1,enext[0],enext[1],estart[0],eend[0],estart[1],eend[1]); 26209 26210 26211 if ( (fabs(t1[0]/tdelta[0]) <= REL_COMP_RES) && 26212 (fabs(t1[1]/tdelta[1]) <= REL_COMP_RES)) break; 26213 26214 tprev = tdist; 26215 } 26216 26217 /* Not converging, corrigate and try again. */ 26218 26219 else 26220 { 26221 t1[0] /= (double)2; 26222 t1[1] /= (double)2; 26223 } 26224 } 26225 26226 /* Iteration stopped, test if point is within resolution */ 26227 26228 if (tdist <= aepsge) 26229 *jstat = 1; 26230 else 26231 *jstat = 2; 26232 26233 /* Test if the iteration is close to a knot */ 26234 if (DEQUAL(enext[0],psurf->et1[kleft1])) 26235 gpos[0] = psurf->et1[kleft1]; 26236 else if (DEQUAL(enext[0],psurf->et1[kleft1+1])) 26237 gpos[0] = psurf->et1[kleft1+1]; 26238 else 26239 gpos[0] = enext[0]; 26240 26241 if (DEQUAL(enext[1],psurf->et2[kleft2])) 26242 gpos[1] = psurf->et2[kleft2]; 26243 else if (DEQUAL(enext[1],psurf->et2[kleft2+1])) 26244 gpos[1] = psurf->et2[kleft2+1]; 26245 else 26246 gpos[1] = enext[1]; 26247 26248 26249 /* Iteration completed. */ 26250 26251 26252 goto out; 26253 26254 26255 /* Error in allocation */ 26256 26257 err101: *jstat = -101; 26258 s6err("s1173",*jstat,kpos); 26259 goto out; 26260 26261 /* Error in input. Conflicting dimensions. */ 26262 26263 err106: *jstat = -106; 26264 s6err("s1173",*jstat,kpos); 26265 goto out; 26266 26267 /* Error in lower level routine. */ 26268 26269 error : *jstat = kstat; 26270 s6err("s1173",*jstat,kpos); 26271 goto out; 26272 26273 out: if (sval != SISL_NULL) freearray(sval); 26274 } 26275 26276 26277 //=========================================================================== 26278 void s1773_s9dir(double *cdist,double *cdiff1,double *cdiff2, 26279 double PS[],double eval1[],double eval2[], 26280 double aepsge, int idim,int *jstat) 26281 //=========================================================================== 26282 { 26283 int kstat=0; /* Local status variable. */ 26284 register double tdet; /* Determinant */ 26285 register double t1,t2,t3,t4,t5; /* Variables in equation system */ 26286 register double *S, *Su, *Sv; 26287 /* register double *Suv, *Suu, *Svv; */ 26288 /* Pointers to surf values */ 26289 register double ref, ang; /* Referance value, angle */ 26290 register double l1, l2; /* Vector norm */ 26291 register double min_ang=10e-11; /* Min angle */ 26292 /* ____________________________________________________________ */ 26293 26294 /* Init */ 26295 *jstat = 0; 26296 *cdiff1 = DZERO; 26297 *cdiff2 = DZERO; 26298 26299 /* Set pointers */ 26300 S = eval2; 26301 Su = S + idim; 26302 Sv = Su + idim; 26303 /* Suu = Sv + idim; 26304 Suv = Suu + idim; 26305 Svv = Suv + idim; */ 26306 26307 /* Degenerate if Su=0 v Sv=0 v Su||Sv */ 26308 l1 = s6length(Su,idim,&kstat); 26309 l2 = s6length(Sv,idim,&kstat); 26310 ang = s6ang(Su,Sv,idim); 26311 if (min(l1,l2) < aepsge || ang < min_ang) *jstat = 1; 26312 26313 /* Computing difference vector and lenght */ 26314 s6diff(eval1,S,idim,PS); 26315 *cdist = s6length(PS,idim,&kstat); 26316 26317 if (*jstat == 1) 26318 { 26319 if (l1 < aepsge) 26320 { 26321 if (l2 > aepsge) 26322 /* Su = 0 */ 26323 *cdiff2 = s6scpr(PS,Sv,idim)/l2*l2; 26324 } 26325 else if (l2 < aepsge) 26326 /* Sv = 0 */ 26327 *cdiff1 = s6scpr(PS,Su,idim)/(l1*l1); 26328 else /* Su,Sv || */ 26329 { 26330 /* Best strategy? */ 26331 *cdiff1 = s6scpr(PS,Su,idim)/(l1*l1); 26332 } 26333 26334 } 26335 else /* *jstat == 0 */ 26336 26337 { 26338 26339 t1 = s6scpr(Su,Su,idim) ; /* - s6scpr(PS,Suu,idim);*/ 26340 t2 = s6scpr(Su,Sv,idim) ; /* - s6scpr(PS,Suv,idim);*/ 26341 t3 = s6scpr(Sv,Sv,idim) ; /* - s6scpr(PS,Svv,idim);*/ 26342 t4 = s6scpr(PS,Su,idim); 26343 t5 = s6scpr(PS,Sv,idim); 26344 26345 ref = max(fabs(t1),fabs(t2)); 26346 ref = max(ref,fabs(t3)); 26347 /* Computing the determinant. */ 26348 26349 tdet = t1*t3 - t2*t2; 26350 26351 if (DEQUAL(ref+fabs(tdet),ref)) 26352 { 26353 *jstat = 1; 26354 } 26355 else 26356 { 26357 /* Using Cramer's rule to find the solution of the system. */ 26358 26359 *cdiff1 = (t4*t3-t5*t2)/tdet; 26360 *cdiff2 = (t1*t5-t2*t4)/tdet; 26361 } 26362 } 26363 } 26364 26365 26366 //=========================================================================== 26367 void s1773_s9corr(double gd[],double acoef1,double acoef2, 26368 double astart1,double aend1,double astart2,double aend2) 26369 //=========================================================================== 26370 { 26371 if (acoef1 + gd[0] < astart1) gd[0] = astart1 - acoef1; 26372 else if (acoef1 + gd[0] > aend1) gd[0] = aend1 - acoef1; 26373 26374 if (acoef2 + gd[1] < astart2) gd[1] = astart2 - acoef2; 26375 else if (acoef2 + gd[1] > aend2) gd[1] = aend2 - acoef2; 26376 } 26377 26378 26379 //=========================================================================== 26380 void s1773(SISLPoint *ppoint,SISLSurf *psurf,double aepsge, 26381 double estart[],double eend[],double enext[],double gpos[],int *jstat) 26382 //=========================================================================== 26383 { 26384 int kstat = 0; /* Local status variable. */ 26385 int kpos = 0; /* Position of error. */ 26386 int kleft1=0; /* Variables used in the evaluator. */ 26387 int kleft2=0; /* Variables used in the evaluator. */ 26388 int kder=1; /* Order of derivatives to be calulated */ 26389 int kdim; /* Dimension of space the curves lie in */ 26390 int knbit; /* Number of iterations */ 26391 int kdir; /* Changing direction. */ 26392 int kdeg; /* Degenaracy flag. */ 26393 double tdelta[2]; /* Parameter intervals of the surface. */ 26394 double tdist; /* Distance between position and origo. */ 26395 double td[2],t1[2],tdn[2];/* Distances between old and new parameter 26396 value in the tree parameter directions. */ 26397 double tprev; /* Previous difference between the curves. */ 26398 double *sval =SISL_NULL; /* Value ,first and second derivatiev of surf. */ 26399 double *sdiff; /* Difference between the point and the surf. */ 26400 double *snorm; /* Normal vector of the surface, dummy. */ 26401 double snext[2]; /* Parameter values */ 26402 double guess[2]; /* Local copy of enext. */ 26403 26404 guess[0] = enext[0]; 26405 guess[1] = enext[1]; 26406 26407 /* Test input. */ 26408 26409 if (ppoint->idim != psurf->idim) goto err106; 26410 26411 kdim = ppoint -> idim; 26412 26413 if (kdim == 1) 26414 { 26415 s1173(ppoint,psurf,aepsge,estart,eend,guess,gpos,&kstat); 26416 if (kstat < 0) 26417 goto error; 26418 else 26419 { 26420 if (DNEQUAL(gpos[0],estart[0]) && 26421 DNEQUAL(gpos[0],eend[0]) && 26422 DNEQUAL(gpos[1],estart[1]) && 26423 DNEQUAL(gpos[1],eend[1])) 26424 *jstat = (kstat==1 ? 1:3); 26425 else 26426 *jstat = 0; 26427 goto out; 26428 } 26429 } 26430 26431 /* Fetch endpoints and the intervals of parameter interval of curves. */ 26432 26433 tdelta[0] = psurf->et1[psurf->in1] - psurf->et1[psurf->ik1 - 1]; 26434 tdelta[1] = psurf->et2[psurf->in2] - psurf->et2[psurf->ik2 - 1]; 26435 26436 /* Allocate local used memory */ 26437 26438 sval = newarray(8*kdim,double); 26439 if (sval == SISL_NULL) goto err101; 26440 26441 sdiff = sval + 6*kdim; 26442 snorm = sdiff + kdim; 26443 26444 /* Initiate variables. */ 26445 26446 tprev = (double)HUGE; 26447 26448 /* Evaluate 0-1.st derivatives of surface */ 26449 /* printf("\n lin: \n %#20.20g %#20.20g", 26450 guess[0],guess[1]); */ 26451 26452 s1421(psurf,kder,guess,&kleft1,&kleft2,sval,snorm,&kstat); 26453 if (kstat < 0) goto error; 26454 26455 /* Compute the distanse vector and value and the new step. */ 26456 26457 s1773_s9dir(&tdist,td,td+1,sdiff,ppoint->ecoef,sval, 26458 aepsge,kdim,&kdeg); 26459 26460 /* Correct if we are not inside the parameter intervall. */ 26461 26462 t1[0] = td[0]; 26463 t1[1] = td[1]; 26464 s1773_s9corr(t1,guess[0],guess[1],estart[0],eend[0],estart[1],eend[1]); 26465 26466 /* Iterate to find the intersection point. */ 26467 26468 for (knbit = 0; knbit < 30; knbit++) 26469 { 26470 /* Evaluate 0-1.st derivatives of surface */ 26471 26472 snext[0] = guess[0] + t1[0]; 26473 snext[1] = guess[1] + t1[1]; 26474 26475 s1421(psurf,kder,snext,&kleft1,&kleft2,sval,snorm,&kstat); 26476 if (kstat < 0) goto error; 26477 26478 /* Compute the distanse vector and value and the new step. */ 26479 26480 s1773_s9dir(&tdist,tdn,tdn+1,sdiff,ppoint->ecoef, 26481 sval,aepsge,kdim,&kdeg); 26482 26483 /* Check if the direction of the step have change. */ 26484 26485 kdir = (s6scpr(td,tdn,2) >= DZERO); /* 0 if changed. */ 26486 26487 /* Ordinary converging. */ 26488 26489 if (tdist < tprev/(double)2 || kdir) 26490 { 26491 guess[0] += t1[0]; 26492 guess[1] += t1[1]; 26493 26494 /* printf("\n %#20.20g %#20.20g", 26495 guess[0],guess[1]); */ 26496 26497 26498 td[0] = t1[0] = tdn[0]; 26499 td[1] = t1[1] = tdn[1]; 26500 26501 /* Correct if we are not inside the parameter intervall. */ 26502 26503 s1773_s9corr(t1,guess[0],guess[1],estart[0],eend[0],estart[1],eend[1]); 26504 tprev = tdist; 26505 26506 if ( (fabs(t1[0]/tdelta[0]) <= REL_COMP_RES) && 26507 (fabs(t1[1]/tdelta[1]) <= REL_COMP_RES)) break; 26508 } 26509 26510 /* Not converging, adjust and try again. */ 26511 26512 else 26513 { 26514 t1[0] /= (double)2; 26515 t1[1] /= (double)2; 26516 /* knbit--; */ 26517 } 26518 if (guess[0]==guess[0]+t1[0] && 26519 guess[1]==guess[1]+t1[1]) break; 26520 } 26521 26522 /* Iteration stopped, test if point founds found is within resolution */ 26523 26524 if (tdist <= aepsge) 26525 { 26526 *jstat = 1; 26527 /* printf("\n SUCCESS!!"); */ 26528 26529 } 26530 else if(kdeg) 26531 *jstat = 9; 26532 else 26533 *jstat = 2; 26534 26535 gpos[0] = guess[0]; 26536 gpos[1] = guess[1]; 26537 26538 /* Iteration completed. */ 26539 26540 goto out; 26541 26542 /* Error in allocation */ 26543 26544 err101: *jstat = -101; 26545 s6err("s1773",*jstat,kpos); 26546 goto out; 26547 26548 /* Error in input. Conflicting dimensions. */ 26549 26550 err106: *jstat = -106; 26551 s6err("s1773",*jstat,kpos); 26552 goto out; 26553 26554 /* Error in lower level routine. */ 26555 26556 error : *jstat = kstat; 26557 s6err("s1773",*jstat,kpos); 26558 goto out; 26559 26560 out: if (sval != SISL_NULL) freearray(sval); 26561 } 26562 26563 26564 //=========================================================================== 26565 void sh6ptobj(double *point, SISLObject *obj, double aepsge, 26566 double start[], double result[], int *jstat) 26567 //=========================================================================== 26568 { 26569 int kstat = 0; /* Local status variable. */ 26570 int kpos = 0; /* Position of error. */ 26571 double pstart[2]; 26572 double pend[2]; 26573 SISLPoint *sislpt = SISL_NULL; 26574 double loc_start[2]; 26575 26576 /* Test input. */ 26577 26578 if (obj == SISL_NULL) goto err106; 26579 26580 if ( obj->iobj == SISLSURFACE) 26581 { 26582 if ((sislpt = newPoint(point, obj->s1->idim, 0)) == SISL_NULL) 26583 goto error; 26584 26585 memcopy(loc_start,start,2,double); 26586 26587 pstart[0] = obj->s1->et1[obj->s1->ik1 - 1]; 26588 pstart[1] = obj->s1->et2[obj->s1->ik2 - 1]; 26589 pend[0] = obj->s1->et1[obj->s1->in1]; 26590 pend[1] = obj->s1->et2[obj->s1->in2]; 26591 26592 s1773(sislpt, obj->s1, aepsge, 26593 pstart, pend, loc_start, result, &kstat); 26594 if (kstat < 0) goto error; 26595 } 26596 else if ( obj->iobj == SISLCURVE) 26597 { 26598 if ((sislpt = newPoint(point, obj->c1->idim, 0)) == SISL_NULL) 26599 goto error; 26600 26601 pstart[0] = obj->c1->et[obj->c1->ik - 1]; 26602 pend[0] = obj->c1->et[obj->c1->in]; 26603 26604 loc_start[0] = start[0]; 26605 s1771(sislpt, obj->c1, aepsge, 26606 pstart[0], pend[0], loc_start[0], result, &kstat); 26607 if (kstat < 0) goto error; 26608 } 26609 else if ( obj->iobj == SISLPOINT) 26610 { 26611 if(s6dist(point,obj->p1->ecoef,obj->p1->idim) < aepsge) 26612 kstat = 1; 26613 else 26614 kstat = 2; 26615 } 26616 else goto err106; 26617 26618 *jstat = kstat; 26619 goto out; 26620 26621 /* Error in input. */ 26622 26623 err106: *jstat = -106; 26624 s6err("sh6ptobj",*jstat,kpos); 26625 goto out; 26626 26627 /* Error in lower level routine. */ 26628 26629 error : *jstat = kstat; 26630 s6err("sh6ptobj",*jstat,kpos); 26631 goto out; 26632 26633 out: if (sislpt != SISL_NULL) freePoint(sislpt); 26634 } 26635 26636 26637 //=========================================================================== 26638 void sh6idnewunite (SISLObject *po1, SISLObject *po2, SISLIntdat ** intdat, 26639 SISLIntpt ** pt1, SISLIntpt ** pt2, double weight, 26640 double aepsge, int *jstat) 26641 //=========================================================================== 26642 { 26643 int ki, kstat; 26644 int kpar; /* Number of parameter directions in 1. object. */ 26645 int kiterate; /* Indicates if iteration is necessary. */ 26646 int kleft1=0,kleft2=0; /* Parameters used in evaluation. */ 26647 double spar[4]; /* Parameter values of intersection point. */ 26648 double start[2]; /* Start parameter value to iteration. */ 26649 double spoint[3]; /* Position in curve or surface. */ 26650 double snorm[3]; /* Dummy vector. Surface normal. */ 26651 SISLIntpt *lpt; 26652 SISLIntpt *lpt1; 26653 SISLIntpt *lpt2; 26654 26655 /* Test if one object is a point. */ 26656 26657 if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT) 26658 { 26659 kpar = po1->iobj + po2->iobj; 26660 kiterate = 0; 26661 } 26662 else 26663 { 26664 kpar = po1->iobj; 26665 kiterate = 1; 26666 } 26667 26668 sh6idnpt (intdat, pt1, 0, &kstat); 26669 if (kstat < 0) 26670 goto error; 26671 sh6idnpt (intdat, pt2, 0, &kstat); 26672 if (kstat < 0) 26673 goto error; 26674 26675 if (sh6ismain (*pt1)) 26676 { 26677 lpt1 = (*pt1); 26678 lpt2 = (*pt2); 26679 } 26680 else 26681 { 26682 lpt1 = (*pt2); 26683 lpt2 = (*pt1); 26684 weight = 1.0 - weight; 26685 } 26686 26687 sh6disconnect (lpt1, lpt2, &kstat); 26688 if (kstat < 0) 26689 goto error; 26690 26691 /* UJK, Oct. 91 */ 26692 /* for (ki=0;;ki++) */ 26693 for (ki = 0;;) 26694 { 26695 if ((lpt = sh6getnext (lpt2, ki)) == SISL_NULL) 26696 break; 26697 26698 sh6disconnect (lpt2, lpt, &kstat); 26699 if (kstat < 0) 26700 goto error; 26701 26702 26703 sh6connect (lpt1, lpt, &kstat); 26704 if (kstat < 0) 26705 goto error; 26706 } 26707 26708 for (ki = 0; ki < kpar; ki++) 26709 spar[ki] = lpt1->epar[ki] * (1.0 - weight) + lpt2->epar[ki] * weight; 26710 26711 if (kiterate) 26712 { 26713 /* Compute start parameter to iteration. */ 26714 26715 for (; ki < lpt1->ipar; ki++) 26716 start[ki-kpar] = lpt1->epar[ki] * (1.0 - weight) + lpt2->epar[ki] * weight; 26717 26718 /* Iterate to closest point in second object. First evaluate 26719 value of intersection point in first object. */ 26720 26721 if (po1->iobj == SISLCURVE) 26722 { 26723 s1221(po1->c1,0,spar[0],&kleft1,spoint,&kstat); 26724 if (kstat < 0) goto error; 26725 } 26726 else 26727 { 26728 s1421(po1->s1,0,spar,&kleft1,&kleft2,spoint,snorm,&kstat); 26729 if (kstat < 0) goto error; 26730 } 26731 26732 /* Iterate. */ 26733 26734 sh6ptobj(spoint,po2,aepsge,start,spar+kpar,&kstat); 26735 if (kstat < 0) goto error; 26736 } 26737 26738 /* Copy new parameter values into intersection point. */ 26739 26740 memcopy(lpt1->epar,spar,lpt1->ipar,DOUBLE); 26741 26742 26743 sh6idkpt (intdat, &lpt2, 0, &kstat); 26744 if (kstat < 0) 26745 goto error; 26746 26747 (*pt1) = lpt1; 26748 (*pt2) = lpt2; 26749 26750 goto out; 26751 26752 error: 26753 *jstat = kstat; 26754 s6err ("sh6idunite", kstat, 0); 26755 goto out; 26756 out: 26757 ; 26758 } 26759 26760 26761 //=========================================================================== 26762 void sh6trimlist (SISLIntpt * pt, SISLIntpt *** ptlist, int *no_of_points, 26763 int *no_alloc) 26764 //=========================================================================== 26765 { 26766 int clean_up = FALSE; /* Clean up on top level */ 26767 int incr = 20; /* Allocation size */ 26768 int ki; /* Loop control */ 26769 /* --------------------------------------------------- */ 26770 26771 26772 /* Check if point is a TRIM point */ 26773 if (pt->iinter != SI_TRIM) 26774 goto out; 26775 26776 /* Check if point is treated */ 26777 if (pt->marker == -90) 26778 goto out; 26779 26780 /* Mark point as treated */ 26781 pt->marker = -90; 26782 26783 26784 if (*no_alloc <= *no_of_points) 26785 { 26786 if (*no_alloc == 0) 26787 { 26788 clean_up = TRUE; 26789 (*no_alloc) += incr; 26790 *ptlist = newarray (*no_alloc, SISLIntpt *); 26791 if (*ptlist == SISL_NULL) 26792 goto out; 26793 } 26794 else 26795 { 26796 clean_up = FALSE; 26797 (*no_alloc) += incr; 26798 *ptlist = increasearray (*ptlist, *no_alloc, SISLIntpt *); 26799 if (*ptlist == SISL_NULL) 26800 goto out; 26801 } 26802 } 26803 26804 /* Fill in */ 26805 (*ptlist)[*no_of_points] = pt; 26806 (*no_of_points)++; 26807 26808 /* Treat all neighbours */ 26809 for (ki = 0; ki < pt->no_of_curves; ki++) 26810 sh6trimlist (pt->pnext[ki], ptlist, no_of_points, no_alloc); 26811 26812 26813 /* Must unmark the points in array if no_alloc == 0 */ 26814 if (clean_up) 26815 for (ki = 0; ki < (*no_of_points); ki++) 26816 (*ptlist)[ki]->marker = 0; 26817 26818 goto out; 26819 26820 26821 out: 26822 return; 26823 } 26824 26825 26826 //=========================================================================== 26827 void sh6red (SISLObject * po1, SISLObject * po2, 26828 SISLIntdat * pintdat, int *jstat) 26829 //=========================================================================== 26830 { 26831 int kstat, i, j; 26832 double tepsge = (double)10000.0*REL_COMP_RES; 26833 double weight = (double) 0.5; 26834 int changed; 26835 SISLIntpt *pcurr,*pstart,*plast; /* to traverse list of points. */ 26836 int indstart,indlast,inddum; /* Indexes used in lists */ 26837 int log_1, log_2; 26838 26839 /* Remove all internal points in a list when along a 26840 constant parameter direction */ 26841 26842 if (((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT 26843 && po1->s1->idim == 1) || 26844 (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT 26845 && po2->s1->idim == 1) || 26846 (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE 26847 && po1->s1->idim == 3)) && 26848 pintdat != SISL_NULL) 26849 for (j = 0; j < pintdat->ipoint; j++) 26850 { 26851 26852 pcurr = pintdat->vpoint[j]; 26853 sh6isinside (po1, po2, pcurr, &kstat); 26854 if (kstat < 0) 26855 goto error; 26856 26857 /* VSK && ALA. 01.93. Do not remove points at corners. */ 26858 if (kstat != 1 && kstat != 2) continue; 26859 26860 sh6getnhbrs (pcurr, &pstart, &plast, &kstat); 26861 if (kstat < 0) 26862 goto error; 26863 26864 if (kstat == 0) 26865 { 26866 /* Two neighbours, check */ 26867 sh6getlist (pcurr, pstart, &indstart, &inddum, &kstat); 26868 if (kstat < 0) 26869 goto error; /* Error. */ 26870 if (kstat == 1) 26871 goto errinconsist; /* pcurr and pstart are not linked. */ 26872 26873 sh6getlist (pcurr, plast, &indlast, &inddum, &kstat); 26874 if (kstat < 0) 26875 goto error; /* Error. */ 26876 if (kstat == 1) 26877 goto errinconsist; /* pcurr and plast are not linked. */ 26878 26879 log_1 = pcurr->curve_dir[indstart]; 26880 log_1 = log_1>>1; 26881 log_1 &= 15; 26882 log_2 = pcurr->curve_dir[indlast]; 26883 log_2 = log_2>>1; 26884 log_2 &= 15; 26885 26886 if (log_1 & log_2 ) 26887 { 26888 sh6idkpt (&pintdat, &pcurr, 1, &kstat); 26889 if (kstat < 0) 26890 goto error; 26891 /* Recursive nature : */ 26892 j = -1; 26893 } 26894 26895 26896 } 26897 } 26898 26899 26900 if (pintdat != SISL_NULL) 26901 { 26902 /* Weight value in 3D sf vs sf case is one */ 26903 if (pintdat->vpoint[0]->ipar == 4) 26904 weight = (double) 1.0; 26905 26906 /* Reduce an illegal trim_curve to one point. */ 26907 26908 for (i = 0; i < pintdat->ipoint; i++) 26909 { 26910 if (pintdat->vpoint[i]->iinter == SI_TRIM) 26911 { 26912 SISLIntpt **trim = SISL_NULL; 26913 int no_trim = 0; 26914 int no_alloc = 0; 26915 sh6trimlist (pintdat->vpoint[i], &trim, &no_trim, &no_alloc); 26916 for (j = 0; j < no_trim; j++) 26917 { 26918 sh6isinside (po1, po2, trim[j], &kstat); 26919 if (kstat < 0) 26920 goto error; 26921 if (kstat != 1) 26922 break; 26923 } 26924 if (j == no_trim) 26925 { 26926 /* Internal trim area. */ 26927 for (j = 1; j < no_trim; j++) 26928 { 26929 /* sh6idunite (&pintdat, &trim[0], &trim[j], weight, &kstat); 26930 */ 26931 /* VSK. 01.93. */ 26932 sh6idnewunite(po1, po2, &pintdat, &trim[0], &trim[j], 26933 weight, tepsge, &kstat); 26934 if (kstat < 0) 26935 goto error; 26936 26937 /* We now need to correct the intpoint. */ 26938 } 26939 trim[0]->iinter = SI_SING; 26940 } 26941 if (trim) 26942 freearray (trim); 26943 } 26944 } 26945 26946 /* Reduse ilegal main points to help points. */ 26947 do 26948 { 26949 changed = 0; 26950 for (i = 0; i < pintdat->ipoint; i++) 26951 { 26952 sh6isinside (po1, po2, pintdat->vpoint[i], &kstat); 26953 if (kstat < 0) 26954 goto error; 26955 if (kstat == 1) 26956 { 26957 if (sh6ismain (pintdat->vpoint[i]) && 26958 sh6nmbmain (pintdat->vpoint[i], &kstat) == 1) 26959 { 26960 sh6tohelp (pintdat->vpoint[i], &kstat); 26961 if (kstat < 0) 26962 goto error; 26963 changed = 1; 26964 } 26965 } 26966 } 26967 } while (changed); 26968 26969 /*UJK, 12.08.93 */ 26970 /* Disconnect trim pts with 3 neighbours */ 26971 do 26972 { 26973 int ind_1,ind_2; 26974 SISLIntpt *p_neighb[3]; 26975 int log_check[3]; 26976 changed = 0; 26977 for (i = 0; i < pintdat->ipoint; i++) 26978 { 26979 pcurr = pintdat->vpoint[i]; 26980 sh6isinside (po1, po2, pcurr, &kstat); 26981 if (kstat < 0) 26982 goto error; 26983 if (kstat && 26984 pcurr->iinter == SI_TRIM && 26985 sh6nmbmain (pcurr, &kstat) == 3) 26986 { 26987 for (ind_1=ind_2=0;ind_1<pcurr->no_of_curves;ind_1++) 26988 if (pcurr->pnext[ind_1]->iinter == SI_TRIM) 26989 { 26990 sh6isinside (po1, po2, pcurr->pnext[ind_1], &kstat); 26991 if (kstat < 0) 26992 goto error; 26993 if (kstat) 26994 { 26995 p_neighb[ind_2] = pcurr->pnext[ind_1]; 26996 log_check[ind_2] = pcurr->curve_dir[ind_1]; 26997 log_check[ind_2] = log_check[ind_2]>>1; 26998 log_check[ind_2] &= 15; 26999 ind_2++; 27000 } 27001 } 27002 27003 if (ind_2 == 3) 27004 { 27005 if (log_check[0] & log_check[1]) 27006 ind_2 = 2; 27007 else if (log_check[0] & log_check[2]) 27008 ind_2 = 1; 27009 else if (log_check[1] & log_check[2]) 27010 ind_2 = 0; 27011 27012 if (ind_2 < 3) 27013 { 27014 changed = TRUE; 27015 sh6disconnect(pcurr,p_neighb[ind_2],&kstat); 27016 if (kstat < 0) goto error; 27017 /* afr: Changed line below from an empty if-statement. */ 27018 sh6nmbmain (p_neighb[ind_2], &kstat); 27019 if (kstat < 0) goto error; 27020 sh6idkpt (&pintdat, &p_neighb[ind_2], 0, &kstat); 27021 if (kstat < 0) goto error; 27022 } 27023 } 27024 } 27025 } 27026 } while (changed); 27027 } 27028 27029 27030 /* Reduction done. */ 27031 27032 (*jstat) = 0; 27033 goto out; 27034 27035 errinconsist: 27036 *jstat = -500; 27037 s6err ("sh6red", *jstat, 0); 27038 goto out; 27039 27040 error:(*jstat) = kstat; 27041 s6err ("sh6red", *jstat, 0); 27042 goto out; 27043 27044 out: 27045 return; 27046 } 27047 27048 27049 //=========================================================================== 27050 void sh6idcon (SISLIntdat ** pintdat, SISLIntpt ** pintpt1, 27051 SISLIntpt ** pintpt2, int *jstat) 27052 //=========================================================================== 27053 { 27054 int kstat; /* Local status variable. */ 27055 27056 /* First we have to be sure that pintdat contain the two points. */ 27057 27058 sh6idnpt (pintdat, pintpt1, 1, &kstat); 27059 if (kstat < 0) 27060 goto error; 27061 27062 sh6idnpt (pintdat, pintpt2, 1, &kstat); 27063 if (kstat < 0) 27064 goto error; 27065 27066 /* Connect */ 27067 sh6connect (*pintpt1, *pintpt2, &kstat); 27068 if (kstat < 0) 27069 goto error; 27070 27071 /* Set direction of connection. */ 27072 /* sh6setdir(*pintpt1, *pintpt2, &kstat); 27073 if (kstat < 0) 27074 goto error; */ 27075 27076 27077 *jstat = 0; 27078 goto out; 27079 27080 /* Error from lower function */ 27081 error: 27082 *jstat = kstat; 27083 s6err ("sh6idcon", *jstat, 0); 27084 out: 27085 ; 27086 } 27087 27088 27089 //=========================================================================== 27090 void sh6insertpt (SISLIntpt * pt1, SISLIntpt * pt2, SISLIntpt * ptnew, int *jstat) 27091 //=========================================================================== 27092 { 27093 int kstat; /* Local status variable. */ 27094 int index1=0,index2=0; 27095 int crv_dir1=0,crv_dir2=0; 27096 27097 *jstat = 0; 27098 27099 sh6getlist (pt1, pt2, &index1, &index2, &kstat); 27100 if (kstat < 0) 27101 goto error; /* Error. */ 27102 if (kstat == 1) 27103 goto err1; /* pt1 and pt2 are not linked. */ 27104 27105 /* Save info in curve_dir */ 27106 crv_dir1 = pt1->curve_dir[index1]; 27107 crv_dir2 = pt2->curve_dir[index2]; 27108 27109 27110 /* Check pt1,pt2,ptnew. */ 27111 27112 sh6connect (pt1, ptnew, &kstat); 27113 if (kstat < 0) 27114 goto error; /* Error. */ 27115 27116 /* Set values in curve_dir */ 27117 sh6getlist (pt1, ptnew, &index1, &index2, &kstat); 27118 pt1->curve_dir[index1] = crv_dir1; 27119 ptnew->curve_dir[index2] = crv_dir2; 27120 27121 sh6connect (pt2, ptnew, &kstat); 27122 if (kstat < 0) 27123 goto error; /* Error. */ 27124 27125 /* Set values in curve_dir */ 27126 sh6getlist (pt2, ptnew, &index1, &index2, &kstat); 27127 pt2->curve_dir[index1] = crv_dir2; 27128 ptnew->curve_dir[index2] = crv_dir1; 27129 27130 27131 sh6disconnect (pt1, pt2, &kstat); 27132 if (kstat < 0) 27133 goto error; /* Error. */ 27134 if (kstat == 1) 27135 goto err1; /* pt1 and pt2 are not linked. */ 27136 27137 27138 goto out; 27139 27140 27141 /* Error. pt1 and pt2 are not linked. */ 27142 27143 err1:*jstat = -1; 27144 s6err ("sh6insertpt", *jstat, 0); 27145 goto out; 27146 27147 /* Error in sub function. */ 27148 27149 error:*jstat = kstat; 27150 s6err ("sh6insertpt", *jstat, 0); 27151 goto out; 27152 27153 out: 27154 return; 27155 } 27156 27157 27158 //=========================================================================== 27159 int sh6nmbmain(SISLIntpt *pt,int *jstat) 27160 //=========================================================================== 27161 { 27162 int num; /* Number of lists. */ 27163 int ki; /* Loop variable. */ 27164 27165 num=0; 27166 27167 /* Count number of main lists pt lies in. */ 27168 27169 for(ki=0; ki<pt->no_of_curves; ki++) 27170 { 27171 if(pt->pnext[ki] == SISL_NULL) goto err1; 27172 if(sh6ismain(pt->pnext[ki])) num++; 27173 } 27174 27175 goto out; 27176 27177 27178 err1: 27179 /* Error in data structure. */ 27180 27181 *jstat = -1; 27182 s6err("sh6nmbmain",*jstat,0); 27183 goto out; 27184 27185 27186 out : 27187 return num; 27188 } 27189 27190 27191 //=========================================================================== 27192 void sh6connect (SISLIntpt * pt1, SISLIntpt * pt2, int *jstat) 27193 //=========================================================================== 27194 { 27195 int kstat; /* error flag. */ 27196 int index1, index2; /* dummy indices. */ 27197 int num; /* Number of main point pinters. */ 27198 27199 *jstat = 0; 27200 27201 if (pt1 == pt2) 27202 goto err4; 27203 27204 /* Check if pt1 and pt2 are already connected. */ 27205 27206 sh6getlist (pt1, pt2, &index1, &index2, &kstat); 27207 if (kstat < 0) 27208 goto err3; 27209 if (kstat < 1) /* Already connected. */ 27210 { 27211 *jstat = 1; 27212 goto out; 27213 } 27214 27215 /* Check that we can connect pt1. There are restrictions if it 27216 it a help point. */ 27217 27218 if (sh6ishelp (pt1)) /* pt1 is a help point */ 27219 { 27220 /* UJK, this is NO invariant */ 27221 /*if (pt1->no_of_curves > 2) 27222 goto err2; 27223 if (pt1->no_of_curves == 2) 27224 goto err1; */ 27225 27226 if (sh6ismain (pt2)) /* pt2 is a main point. */ 27227 { 27228 num = sh6nmbmain (pt1, &kstat); 27229 27230 /* UJK, If invar does not hold, MAKE it hold */ 27231 /* if (num > 1) 27232 goto err2; 27233 if (num == 1) 27234 goto err1; */ 27235 if (num >= 1) 27236 sh6tomain (pt1, &kstat); 27237 if (kstat < 0) 27238 goto err2; 27239 27240 /* pt1 cannot be connected to two main points. */ 27241 } 27242 } 27243 27244 /* Check that we can connect pt2. There are restrictions if it 27245 it a help point. */ 27246 27247 if (sh6ishelp (pt2)) /* pt2 is a help point */ 27248 { 27249 /* UJK, this is NO invariant */ 27250 /*if (pt2->no_of_curves > 2) 27251 goto err2; 27252 if (pt2->no_of_curves == 2) 27253 goto err1; */ 27254 27255 if (sh6ismain (pt1)) /* pt1 is a main point. */ 27256 { 27257 num = sh6nmbmain (pt2, &kstat); 27258 27259 /* UJK, If invar does not hold, MAKE it hold */ 27260 /*if (num > 1) 27261 goto err2; 27262 if (num == 1) 27263 goto err1; */ 27264 if (num >= 1) 27265 sh6tomain (pt2, &kstat); 27266 if (kstat < 0) 27267 goto err2; 27268 27269 /* pt2 cannot be connected to two main points. */ 27270 } 27271 } 27272 27273 /* Now make the connection. */ 27274 27275 27276 /* Point pt1 to pt2. */ 27277 27278 /* Check if we need to reallocate the pnext and curve_dir arrays. */ 27279 27280 if (pt1->no_of_curves > pt1->no_of_curves_alloc) 27281 goto err2; 27282 if (pt1->no_of_curves == pt1->no_of_curves_alloc) 27283 { 27284 pt1->no_of_curves_alloc += 4; 27285 pt1->pnext = increasearray (pt1->pnext, 27286 pt1->no_of_curves_alloc, SISLIntpt *); 27287 pt1->curve_dir = increasearray (pt1->curve_dir, 27288 pt1->no_of_curves_alloc, int); 27289 /* UJK, Must have size of pretop arrays increased */ 27290 pt1->left_obj_1 = increasearray (pt1->left_obj_1, 27291 pt1->no_of_curves_alloc, int); 27292 pt1->left_obj_2 = increasearray (pt1->left_obj_2, 27293 pt1->no_of_curves_alloc, int); 27294 pt1->right_obj_1 = increasearray (pt1->right_obj_1, 27295 pt1->no_of_curves_alloc, int); 27296 pt1->right_obj_2 = increasearray (pt1->right_obj_2, 27297 pt1->no_of_curves_alloc, int); 27298 } 27299 27300 /* Set new pointer to new position in array. */ 27301 /* Set new curve direction to 0 for now. */ 27302 27303 pt1->pnext[pt1->no_of_curves] = pt2; 27304 pt1->curve_dir[pt1->no_of_curves] = 0; 27305 27306 /* Increment no_of_curves. */ 27307 27308 pt1->no_of_curves++; 27309 27310 27311 /* Point pt2 to pt1. */ 27312 27313 /* Check if we need to reallocate the pnext and curve_dir arrays. */ 27314 27315 if (pt2->no_of_curves > pt2->no_of_curves_alloc) 27316 goto err2; 27317 if (pt2->no_of_curves == pt2->no_of_curves_alloc) 27318 { 27319 pt2->no_of_curves_alloc += 4; 27320 /* UJK, pt1->pnext chaged to pt2->pnext */ 27321 pt2->pnext = increasearray (pt2->pnext, 27322 pt2->no_of_curves_alloc, SISLIntpt *); 27323 pt2->curve_dir = increasearray (pt2->curve_dir, 27324 pt2->no_of_curves_alloc, int); 27325 /* UJK, Must have size of pretop arrays increased */ 27326 pt2->left_obj_1 = increasearray (pt2->left_obj_1, 27327 pt2->no_of_curves_alloc, int); 27328 pt2->left_obj_2 = increasearray (pt2->left_obj_2, 27329 pt2->no_of_curves_alloc, int); 27330 pt2->right_obj_1 = increasearray (pt2->right_obj_1, 27331 pt2->no_of_curves_alloc, int); 27332 pt2->right_obj_2 = increasearray (pt2->right_obj_2, 27333 pt2->no_of_curves_alloc, int); 27334 } 27335 27336 /* Set new pointer to new position in array. */ 27337 /* Set new curve direction to 0 for now. */ 27338 27339 pt2->pnext[pt2->no_of_curves] = pt1; 27340 pt2->curve_dir[pt2->no_of_curves] = 0; 27341 27342 /* Increment no_of_curves. */ 27343 27344 pt2->no_of_curves++; 27345 27346 27347 27348 goto out; 27349 27350 /* Illegal to connect. */ 27351 /*err1: 27352 27353 *jstat = -1; 27354 s6err ("sh6connect", *jstat, 0); 27355 goto out; */ 27356 27357 /* Error in data structure. */ 27358 err2: 27359 27360 *jstat = -2; 27361 s6err ("sh6connect", *jstat, 0); 27362 goto out; 27363 27364 /* Error in subfunction. */ 27365 err3: 27366 27367 *jstat = -3; 27368 s6err ("sh6connect", *jstat, 0); 27369 goto out; 27370 27371 err4: 27372 /* Selfconnecting not legal */ 27373 *jstat = -4; 27374 s6err ("sh6connect", *jstat, 0); 27375 goto out; 27376 27377 27378 out: 27379 return; 27380 } 27381 27382 27383 //=========================================================================== 27384 void sh6disconnect(SISLIntpt *pt1,SISLIntpt *pt2,int *jstat) 27385 //=========================================================================== 27386 { 27387 int kstat; /* Local status variable. */ 27388 int index1,index2; /* Indices for pt1 and pt2. */ 27389 27390 *jstat = 0; 27391 27392 27393 /* Check if pt1 and pt2 are connected. */ 27394 27395 sh6getlist(pt1,pt2,&index1,&index2,&kstat); 27396 if(kstat < 0) goto err1; 27397 if(kstat == 1) 27398 { 27399 *jstat = 1; 27400 goto out; 27401 } 27402 27403 27404 /* Disconnect. */ 27405 27406 pt1->no_of_curves--; 27407 pt1->pnext[index1] = pt1->pnext[pt1->no_of_curves]; 27408 pt1->curve_dir[index1] = pt1->curve_dir[pt1->no_of_curves]; 27409 27410 pt2->no_of_curves--; 27411 pt2->pnext[index2] = pt2->pnext[pt2->no_of_curves]; 27412 pt2->curve_dir[index2] = pt2->curve_dir[pt2->no_of_curves]; 27413 27414 27415 goto out; 27416 27417 27418 27419 /* No connection exists. */ 27420 27421 err1 : *jstat = -1; 27422 s6err("sh6disconnect",*jstat,0); 27423 goto out; 27424 27425 out: ; 27426 } 27427 27428 27429 //=========================================================================== 27430 void sh6idkpt (SISLIntdat ** pintdat, SISLIntpt ** pintpt, int join, int *jstat) 27431 //=========================================================================== 27432 { 27433 int ki; /* Counters. */ 27434 int knum; 27435 int kstat = 0; 27436 SISLIntpt *pnhbr_1 = SISL_NULL; /* First neighbour */ 27437 SISLIntpt *pnhbr_2 = SISL_NULL; /* Second neighbour */ 27438 SISLIntpt *help_pt = SISL_NULL; /* help point */ 27439 int crv_dir_1 = 0; 27440 int crv_dir_2 = 0; 27441 int index1 = 0; 27442 int index2 = 0; 27443 int dummy; 27444 /* ------------------------------------------------*/ 27445 27446 *jstat = 0; 27447 27448 if ((*pintpt) == SISL_NULL) 27449 { 27450 *jstat = 1; 27451 goto out; 27452 } 27453 27454 if (join) 27455 { 27456 /* ALA-- We first remove all help point if this point is a main point. */ 27457 if (sh6ismain(*pintpt)) 27458 for (ki = 0; ki < (*pintpt)->no_of_curves; ki++) 27459 { 27460 if (sh6ishelp(help_pt = sh6getnext(*pintpt, ki))) 27461 { 27462 sh6idkpt (pintdat, &help_pt, 1, &kstat); 27463 if (kstat < 0) 27464 goto error; 27465 } 27466 } 27467 27468 /* Remember the two neighbours */ 27469 sh6getnhbrs (*pintpt, &pnhbr_1, &pnhbr_2, &kstat); 27470 if (kstat < 0) 27471 goto error; 27472 27473 27474 if (pnhbr_1 && pnhbr_2) 27475 { 27476 /* Two neighbours, remember crv_dir */ 27477 sh6getlist (*pintpt, pnhbr_1, &dummy, &index1, &kstat); 27478 if (kstat < 0) 27479 goto error; /* Error. */ 27480 if (kstat == 1) 27481 goto err1; /* pt1 and pt2 are not linked. */ 27482 27483 sh6getlist (*pintpt, pnhbr_2, &dummy, &index2, &kstat); 27484 if (kstat < 0) 27485 goto error; /* Error. */ 27486 if (kstat == 1) 27487 goto err1; /* pt1 and pt2 are not linked. */ 27488 27489 crv_dir_1 = pnhbr_1->curve_dir[index1]; 27490 crv_dir_2 = pnhbr_2->curve_dir[index2]; 27491 } 27492 } 27493 27494 27495 for (; (*pintpt)->no_of_curves;) 27496 { 27497 /* Disconnect all */ 27498 sh6disconnect (*pintpt, (*pintpt)->pnext[0], &kstat); 27499 if (kstat < 0) 27500 goto error; 27501 } 27502 27503 /* Connect the two neighbours */ 27504 if (pnhbr_1 && pnhbr_2) 27505 { 27506 sh6connect (pnhbr_1, pnhbr_2, &kstat); 27507 if (kstat < 0) 27508 goto error; 27509 27510 /* UJK, MESZ 930617: Don't bother with curve_dir when 27511 the points already were connected. */ 27512 if (kstat != 1) 27513 { 27514 sh6getlist (pnhbr_1, pnhbr_2, &index1, &index2, &kstat); 27515 if (kstat < 0) 27516 goto error; /* Error. */ 27517 if (kstat == 1) 27518 goto err1; /* pt1 and pt2 are not linked. */ 27519 27520 pnhbr_1->curve_dir[index1] = crv_dir_1; 27521 pnhbr_2->curve_dir[index2] = crv_dir_2; 27522 } 27523 } 27524 27525 if ((*pintdat) == SISL_NULL) 27526 { 27527 freeIntpt (*pintpt); 27528 (*pintpt) = SISL_NULL; 27529 27530 *jstat = 1; 27531 goto out; 27532 } 27533 27534 27535 /* Find pintpt in pintdat. */ 27536 27537 for (knum = -1, ki = 0; ki < (*pintdat)->ipoint; ki++) 27538 { 27539 if ((*pintdat)->vpoint[ki] == (*pintpt)) 27540 { 27541 knum = ki; 27542 break; 27543 } 27544 } 27545 27546 27547 if (knum == -1) 27548 *jstat = 1; 27549 else 27550 { 27551 (*pintdat)->vpoint[knum] = (*pintdat)->vpoint[(*pintdat)->ipoint - 1]; 27552 ((*pintdat)->ipoint)--; 27553 (*pintdat)->vpoint[(*pintdat)->ipoint] = SISL_NULL; 27554 27555 27556 27557 if ((*pintdat)->ipoint == 0) 27558 { 27559 freeIntdat (*pintdat); 27560 (*pintdat) = SISL_NULL; 27561 } 27562 } 27563 27564 freeIntpt (*pintpt); 27565 (*pintpt) = SISL_NULL; 27566 goto out; 27567 27568 27569 err1: 27570 *jstat = -1; 27571 goto out; 27572 27573 error: 27574 *jstat = kstat; 27575 goto out; 27576 27577 out:; 27578 } 27579 27580 27581 //=========================================================================== 27582 void sh_div_crv (SISLCurve * pc, int which_end, double aepsge, 27583 SISLCurve ** rcnew, int *jstat) 27584 //=========================================================================== 27585 { 27586 int kpos = 0; /* Position of error. */ 27587 int ki,kj; /* Loop control */ 27588 int kn,kk,kdim; /* Attributes of inut curve */ /* Position of error. */ 27589 double a,b; /* Bezier interval */ 27590 double *et_new = SISL_NULL; /* New knot array */ 27591 double *ecoef_new = SISL_NULL; /* New coefficient array */ 27592 SISLCurve *qc = SISL_NULL; /* Pointer to new curve-object. */ 27593 27594 27595 /* Check that we have a curve. */ 27596 if (!pc) 27597 goto err150; 27598 27599 /* Minimum order allowed is 3. */ 27600 if (pc->ik < 3) 27601 goto err151; 27602 27603 /* The curve has to be of bezier type. */ 27604 if (pc->in != pc->ik) 27605 goto err152; 27606 27607 kn = pc->in; 27608 kk = pc->ik; 27609 a = pc->et[kk-1]; 27610 b = pc->et[kn]; 27611 kdim = pc->idim; 27612 27613 /* Test if the corresponding coeficient is zero. */ 27614 /* if (which_end == 0) 27615 { 27616 for (ki=0; ki < kdim; ki++) 27617 if (fabs(pc->ecoef[ki]) > aepsge) 27618 goto err153; 27619 } 27620 else 27621 { 27622 for (ki=(kn-1)*kdim; ki < kn*kdim; ki++) 27623 if (fabs(pc->ecoef[ki]) > aepsge) 27624 goto err153; 27625 } 27626 */ 27627 27628 /* create knot array. __________________________________________*/ 27629 if ((et_new= newarray(kn+kk-2,DOUBLE)) == SISL_NULL) goto err101; 27630 27631 for (ki=0; ki < kk-1; ki++) 27632 et_new[ki] = a; 27633 27634 for (; ki < kn+kk-2; ki++) 27635 et_new[ki] = b; 27636 27637 /* create coeficient array. _________________________________ */ 27638 if ((ecoef_new= newarray(kdim*(kn-1),DOUBLE)) == SISL_NULL) goto err101; 27639 27640 if (which_end) 27641 for (ki=0; ki < kn-1; ki++) 27642 for (kj=0; kj < kdim; kj++) 27643 ecoef_new[ki*kdim +kj] = pc->ecoef[ki*kdim +kj]*(kn-1)/(kn-1-ki); 27644 else 27645 for (ki=0; ki < kn-1; ki++) 27646 for (kj=0; kj < kdim; kj++) 27647 ecoef_new[ki*kdim +kj] = pc->ecoef[(ki+1)*kdim + kj]*(kn-1)/(ki+1); 27648 27649 27650 /* Create factor curve */ 27651 if ((qc = newCurve (kn-1, kk-1, et_new, ecoef_new, pc->ikind, kdim, 2)) 27652 == SISL_NULL) goto err101; 27653 27654 *rcnew = qc; 27655 *jstat = 0; 27656 goto out; 27657 27658 /* ERROR EXITS ___________________________________________ */ 27659 27660 /* Error. No input curve. */ 27661 err150: 27662 *jstat = -150; 27663 s6err ("sh_div_crv", *jstat, kpos); 27664 goto out; 27665 27666 27667 /* Error. order less than 3. */ 27668 err151: 27669 *jstat = -151; 27670 s6err ("sh_div_crv", *jstat, kpos); 27671 goto out; 27672 27673 /* Error. Not a bezier curve. */ 27674 err152: 27675 *jstat = -152; 27676 s6err ("sh_div_crv", *jstat, kpos); 27677 goto out; 27678 27679 27680 /* Error in allocation.*/ 27681 27682 err101: 27683 if (et_new) freearray(et_new); 27684 if (ecoef_new) freearray(ecoef_new); 27685 *jstat = -101; 27686 s6err ("sh_div_crv", *jstat, kpos); 27687 goto out; 27688 27689 out: 27690 ; 27691 } 27692 27693 27694 //=========================================================================== 27695 void sh_div_surf (SISLSurf * ps, int which_end_1, int which_end_2, 27696 double aepsge, SISLSurf ** rsnew, int *jstat) 27697 //=========================================================================== 27698 { 27699 int kstat; /* Local status variable. */ 27700 int kdim = ps->idim; /* Dimension of geometry space. */ 27701 int kkind = ps->ikind; /* Kind of surface. */ 27702 int kk1; /* Order in 1. par. dir. */ 27703 int kk2; /* Order in 2. par. dir. */ 27704 int kn1; /* Number of vertices in 1. par. dir. */ 27705 int kn2; /* Number of vertices in 2. par. dir. */ 27706 double *st1; /* Knot vector in 1. par. dir. */ 27707 double *st2; /* Knot vector in 2. par. dir. */ 27708 double *scoef1 = SISL_NULL; /* Coefficients of input curve to 27709 factorize in 1. par. dir. */ 27710 double *scoef2 = SISL_NULL; /* Coefficients of factorized surface. */ 27711 double *scoef; /* Coefficients of factorized surface. */ 27712 SISLCurve *qc1 = SISL_NULL; /* Input curve to sh_div_crv in 1. par. dir. */ 27713 SISLCurve *qc2 = SISL_NULL; /* Output curve from sh_div_crv in 1. par. dir. */ 27714 SISLCurve *qc3 = SISL_NULL; /* Output curve from sh_div_crv in 2. par. dir. */ 27715 /* __________________________________________________________________ */ 27716 27717 if (which_end_1 > -1) 27718 { 27719 /* Factorize 1. dir, 27720 first express the surface as a curve. */ 27721 27722 if ((scoef1 = newarray (kdim * ps->in1 * ps->in2, double)) == SISL_NULL) 27723 goto err101; 27724 27725 /* Change parameter directions of surface. */ 27726 27727 s6chpar (ps->ecoef, ps->in1, ps->in2, kdim, scoef1); 27728 27729 /* Create curve. */ 27730 27731 qc1 = newCurve (ps->in1, ps->ik1, ps->et1, scoef1, kkind, kdim * ps->in2, 0); 27732 if (qc1 == SISL_NULL) 27733 goto err101; 27734 27735 /* Factorize the curve. */ 27736 sh_div_crv (qc1, which_end_1, aepsge, &qc2, &kstat); 27737 if (kstat < 0) 27738 goto error; 27739 27740 /* Change parameter directions of the coefficient array of 27741 the resulting curve. */ 27742 27743 if ((scoef2 = newarray (qc2->in *ps->in2 * kdim, DOUBLE)) == SISL_NULL) 27744 goto err101; 27745 s6chpar (qc2->ecoef, ps->in2, qc2->in, kdim, scoef2); 27746 27747 /* Set local parameters of factorized surface. */ 27748 27749 kk1 = qc2->ik; 27750 kn1 = qc2->in; 27751 kk2 = ps->ik2; 27752 kn2 = ps->in2; 27753 st1 = qc2->et; 27754 st2 = ps->et2; 27755 27756 /* Free curve used as input to the sh_div_crv. */ 27757 27758 if (qc1 != SISL_NULL) 27759 freeCurve (qc1); 27760 qc1 = SISL_NULL; 27761 } 27762 else 27763 { 27764 /* Set local parameters of input surface. */ 27765 27766 kk1 = ps->ik1; 27767 kk2 = ps->ik2; 27768 kn1 = ps->in1; 27769 kn2 = ps->in2; 27770 st1 = ps->et1; 27771 st2 = ps->et2; 27772 scoef2 = ps->ecoef; 27773 } 27774 27775 if (which_end_2 > -1) 27776 { 27777 /* Factorize in second parameter direction of the 27778 surface. First express the surface as a curve. */ 27779 27780 if ((qc1 = newCurve (kn2, ps->ik2, st2, scoef2, kkind, kn1 * kdim, 0)) 27781 == SISL_NULL) 27782 goto err101; 27783 27784 27785 27786 27787 /* Factorize the curve. */ 27788 sh_div_crv(qc1, which_end_2, aepsge, &qc3, &kstat); 27789 if (kstat < 0) 27790 goto error; 27791 27792 /* Set local parameters of the surface. */ 27793 27794 kk2 = qc3->ik; 27795 kn2 = qc3->in; 27796 st2 = qc3->et; 27797 scoef = qc3->ecoef; 27798 } 27799 else 27800 scoef = scoef2; 27801 27802 /* Express result as a surface. */ 27803 27804 if ((*rsnew = newSurf (kn1, kn2, kk1, kk2, st1, st2, 27805 scoef, kkind, kdim, 1)) == SISL_NULL) 27806 goto err101; 27807 27808 /* Exit. */ 27809 27810 *jstat = 0; 27811 goto out; 27812 27813 /* Error in scratch allocation. */ 27814 27815 err101:*jstat = -101; 27816 goto out; 27817 27818 /* Error in lower level routine. */ 27819 27820 error:*jstat = kstat; 27821 goto out; 27822 27823 out: 27824 /* Free scratch occupied by local arrays and objects. */ 27825 27826 if (which_end_1 > -1 && scoef1 != SISL_NULL) 27827 freearray (scoef1); 27828 if (which_end_1 > -1&& scoef2 != SISL_NULL) 27829 freearray (scoef2); 27830 if (qc1 != SISL_NULL) 27831 freeCurve (qc1); 27832 if (qc2 != SISL_NULL) 27833 freeCurve (qc2); 27834 if (qc3 != SISL_NULL) 27835 freeCurve (qc3); 27836 27837 return; 27838 } 27839 27840 27841 //=========================================================================== 27842 void sh6comedg (SISLObject * po1, SISLObject * po2, SISLIntpt *pt1, SISLIntpt *pt2, int *jstat) 27843 //=========================================================================== 27844 { 27845 int kstat=0; 27846 double minpar[4]; 27847 double maxpar[4]; 27848 int nrpar, np1, np2; 27849 int common_edg, i, j; 27850 int is_inside = 1; 27851 int on_edge1 = 0; 27852 int on_edge2 = 0; 27853 int ind1, ind2; 27854 /* ---------------------------------------------------------------- */ 27855 27856 *jstat = 0; 27857 27858 if (pt1 != SISL_NULL && pt2 != SISL_NULL) 27859 { 27860 /* Making the parametric boarders */ 27861 27862 if (po1->iobj == SISLSURFACE) 27863 { 27864 nrpar = 2; 27865 np1 = 4; 27866 27867 minpar[0] = po1->s1->et1[po1->s1->ik1-1]; 27868 minpar[1] = po1->s1->et2[po1->s1->ik2-1]; 27869 maxpar[0] = po1->s1->et1[po1->s1->in1]; 27870 maxpar[1] = po1->s1->et2[po1->s1->in2]; 27871 } 27872 else if (po1->iobj == SISLCURVE) 27873 { 27874 nrpar = 1; 27875 np1 = 2; 27876 27877 minpar[0] = po1->c1->et[po1->c1->ik-1]; 27878 maxpar[0] = po1->c1->et[po1->c1->in]; 27879 } 27880 else /* SISLPOINT */ 27881 np1 = nrpar = 0; 27882 27883 if (po2->iobj == SISLSURFACE) 27884 { 27885 minpar[nrpar] = po2->s1->et1[po2->s1->ik1-1]; 27886 minpar[nrpar+1] = po2->s1->et2[po2->s1->ik2-1]; 27887 maxpar[nrpar] = po2->s1->et1[po2->s1->in1]; 27888 maxpar[nrpar+1] = po2->s1->et2[po2->s1->in2]; 27889 nrpar += 2; 27890 np2 = 4; 27891 } 27892 else if (po2->iobj == SISLCURVE) 27893 { 27894 minpar[nrpar] = po2->c1->et[po2->c1->ik-1]; 27895 maxpar[nrpar] = po2->c1->et[po2->c1->in]; 27896 nrpar++; 27897 np2 = 2; 27898 } 27899 else np2 = 0; /* SISLPOINT */ 27900 27901 /* Testing. */ 27902 27903 /* UJK, aug.92 */ 27904 /* for (i = 0; i < nrpar || !is_inside; i++) */ 27905 for (i = 0; i < nrpar && is_inside; i++) 27906 { 27907 if (pt1->epar[i] <= maxpar[i] + REL_PAR_RES && 27908 pt1->epar[i] >= minpar[i] - REL_PAR_RES) 27909 { 27910 /* pt1 is inside. */ 27911 27912 if (pt1->epar[i] >= maxpar[i] - REL_PAR_RES) 27913 on_edge1 += (1 << (2*i)); /* On edge/end */ 27914 if (pt1->epar[i] <= minpar[i] + REL_PAR_RES) 27915 on_edge1 += (1 << (2*i+1)); /* On edge/end */ 27916 27917 } 27918 else is_inside = 0; 27919 27920 if (pt2->epar[i] <= maxpar[i] + REL_PAR_RES && 27921 pt2->epar[i] >= minpar[i] - REL_PAR_RES) 27922 { 27923 /* pt2 is inside. */ 27924 27925 if (pt2->epar[i] >= maxpar[i] - REL_PAR_RES) 27926 on_edge2 += (1 << (2*i)); /* On edge/end */ 27927 if (pt2->epar[i] <= minpar[i] + REL_PAR_RES) 27928 on_edge2 += (1 << (2*i+1)); /* On edge/end */ 27929 27930 } 27931 else is_inside = 0; 27932 } 27933 27934 common_edg = on_edge1 & on_edge2; 27935 (*jstat) = 0; 27936 27937 if(is_inside && common_edg) 27938 { 27939 if (np1 > 0) 27940 { 27941 j = (15>>(4-np1)); 27942 if (common_edg & j) 27943 { 27944 sh6getlist(pt1,pt2,&ind1,&ind2,&kstat); 27945 if (kstat < 0) goto err106; 27946 if (kstat == 0) 27947 { 27948 if (common_edg & 3) i = 2; 27949 else i = 0; 27950 if (common_edg & (3<<2)) i+= 4; 27951 if (pt1->curve_dir[ind1] & i) (*jstat) = 1; 27952 } 27953 } 27954 } 27955 if (np2 > 0) 27956 { 27957 j = (15>>(4-np2)); 27958 j <<= np1; 27959 if (common_edg & j) 27960 { 27961 sh6getlist(pt1,pt2,&ind1,&ind2,&kstat); 27962 if (kstat < 0) goto err106; 27963 if (kstat == 0) 27964 { 27965 if (common_edg & (3<<np1)) i = 8; 27966 else i = 0; 27967 if (common_edg & (3<<(np1+2))) i+= 16; 27968 if (pt1->curve_dir[ind1] & i) (*jstat) += 2; 27969 } 27970 } 27971 } 27972 } 27973 else 27974 (*jstat) = 0; 27975 } 27976 else goto err108; 27977 27978 27979 /* Done. */ 27980 27981 goto out; 27982 27983 /* Error in input. Conflicting dimensions. */ 27984 27985 err106:*jstat = -106; 27986 s6err("sh6comedg",*jstat,0); 27987 goto out; 27988 27989 /* Error in input. No points */ 27990 27991 err108:*jstat = -108; 27992 s6err("sh6comedg",*jstat,0); 27993 goto out; 27994 27995 out: 27996 return; 27997 } 27998 27999 28000 //=========================================================================== 28001 void sh6isinside (SISLObject * po1, SISLObject * po2, SISLIntpt *intpt, int *jstat) 28002 //=========================================================================== 28003 { 28004 double minpar[4]; 28005 double maxpar[4]; 28006 int nrpar; 28007 int i; 28008 int is_inside = 1; 28009 int on_edge = 0; 28010 28011 28012 if (intpt != SISL_NULL) 28013 { 28014 /* Making the parametric boarders */ 28015 28016 if (po1->iobj == SISLSURFACE) 28017 { 28018 nrpar = 2; 28019 28020 minpar[0] = po1->s1->et1[po1->s1->ik1-1]; 28021 minpar[1] = po1->s1->et2[po1->s1->ik2-1]; 28022 maxpar[0] = po1->s1->et1[po1->s1->in1]; 28023 maxpar[1] = po1->s1->et2[po1->s1->in2]; 28024 } 28025 else if (po1->iobj == SISLCURVE) 28026 { 28027 nrpar = 1; 28028 28029 minpar[0] = po1->c1->et[po1->c1->ik-1]; 28030 maxpar[0] = po1->c1->et[po1->c1->in]; 28031 } 28032 else /* SISLPOINT */ 28033 nrpar = 0; 28034 28035 if (po2->iobj == SISLSURFACE) 28036 { 28037 minpar[nrpar] = po2->s1->et1[po2->s1->ik1-1]; 28038 minpar[nrpar+1] = po2->s1->et2[po2->s1->ik2-1]; 28039 maxpar[nrpar] = po2->s1->et1[po2->s1->in1]; 28040 maxpar[nrpar+1] = po2->s1->et2[po2->s1->in2]; 28041 nrpar += 2; 28042 } 28043 else if (po2->iobj == SISLCURVE) 28044 { 28045 minpar[nrpar] = po2->c1->et[po2->c1->ik-1]; 28046 maxpar[nrpar] = po2->c1->et[po2->c1->in]; 28047 nrpar++; 28048 } 28049 /*else SISLPOINT */ 28050 28051 if (nrpar != intpt->ipar) goto err106; 28052 28053 /* Testing. */ 28054 28055 for (i = 0; (i < nrpar) && is_inside; i++) 28056 { 28057 if ((intpt->epar[i] <= maxpar[i] + REL_PAR_RES || 28058 DEQUAL(intpt->epar[i], maxpar[i])) && 28059 (intpt->epar[i] >= minpar[i] - REL_PAR_RES || 28060 DEQUAL(intpt->epar[i], minpar[i]))) 28061 { 28062 /* Int point is inside. */ 28063 28064 if (intpt->epar[i] >= maxpar[i] - REL_PAR_RES) 28065 on_edge += (1 << (2*i)); /* On edge/end */ 28066 if (intpt->epar[i] <= minpar[i] + REL_PAR_RES) 28067 on_edge += (1 << (2*i+1)); /* On edge/end */ 28068 28069 } 28070 else is_inside = 0; 28071 } 28072 28073 if (is_inside) 28074 { 28075 (*jstat) = 1; 28076 if(on_edge) 28077 { 28078 (*jstat) += 1; 28079 if(on_edge > 1) 28080 { 28081 if (po1->iobj == SISLSURFACE) 28082 { 28083 if ((on_edge & 1 || on_edge & 2) && 28084 (on_edge & 4 || on_edge & 8)) 28085 (*jstat) += 1; 28086 } 28087 28088 if (po2->iobj == SISLSURFACE ) 28089 { 28090 int ui = 2*(nrpar - 2); 28091 if ((on_edge & (1 << (ui)) || on_edge & (1 << (ui+1))) && 28092 (on_edge & (1 << (ui+2)) || on_edge & (1 << (ui+3)))) 28093 (*jstat) += 1; 28094 } 28095 } 28096 } 28097 28098 /* Test if the intersection point lies at an edge in both 28099 objects and is not registered as a corner point. */ 28100 28101 if (*jstat == 2 && (on_edge & 15) && (on_edge & 240)) 28102 *jstat = 5; 28103 } 28104 else 28105 (*jstat) = 0; 28106 } 28107 else goto err108; 28108 28109 28110 /* Done. */ 28111 28112 goto out; 28113 28114 /* Error in input. Conflicting dimensions. */ 28115 28116 err106:*jstat = -106; 28117 goto out; 28118 28119 /* Error in input. No points */ 28120 28121 err108:*jstat = -108; 28122 goto out; 28123 28124 out: 28125 return; 28126 } 28127 28128 28129 //=========================================================================== 28130 void freeTrimpar(SISLTrimpar *trimpar) 28131 //=========================================================================== 28132 { 28133 28134 28135 /* Free the instance pointed at by trimpar. */ 28136 28137 freearray(trimpar); 28138 28139 return; 28140 } 28141 28142 //=========================================================================== 28143 void freeIntpt(SISLIntpt *ppt) 28144 //=========================================================================== 28145 { 28146 /* Free the arrays contained in the instance. */ 28147 28148 if (ppt->ipar) 28149 freearray(ppt -> epar); 28150 if (ppt->pnext) freearray(ppt->pnext); 28151 if (ppt->curve_dir) freearray(ppt->curve_dir); 28152 if (ppt->left_obj_1) freearray(ppt->left_obj_1); 28153 if (ppt->left_obj_2) freearray(ppt->left_obj_2); 28154 if (ppt->right_obj_1) freearray(ppt->right_obj_1); 28155 if (ppt->right_obj_2) freearray(ppt->right_obj_2); 28156 if (ppt->geo_data_1) freearray(ppt->geo_data_1); 28157 if (ppt->geo_data_2) freearray(ppt->geo_data_2); 28158 28159 if(ppt->trim[0] != SISL_NULL) freeTrimpar(ppt->trim[0]); 28160 if(ppt->trim[1] != SISL_NULL) freeTrimpar(ppt->trim[1]); 28161 28162 /* Free the instance pointed at by ppt. */ 28163 28164 freearray(ppt); 28165 } 28166 28167 28168 //=========================================================================== 28169 void s6deCasteljau(double C[], double a, double b, double t, int k, double D[], int* jstat) 28170 //=========================================================================== 28171 { 28172 int r,j,kk=k*k,kr; 28173 double alpha; 28174 double Al[16]; 28175 double* A = SISL_NULL; 28176 28177 28178 *jstat = 1; 28179 if (a > b || DEQUAL(a,b) ) goto err109; 28180 28181 if (k > 4 ) 28182 { 28183 A = newarray(kk,double); 28184 if (A == SISL_NULL) goto err101; 28185 } 28186 else 28187 A = Al; 28188 28189 for (j=0; j<k; j++) 28190 A[j] = C[j]; 28191 28192 alpha = (b-t)/(b-a); 28193 for (r = 1; r < k; r++) 28194 for (j = r; j < k; j++) 28195 A[k*r+j] = alpha*A[k*(r-1)+j-1] + (1-alpha)*A[k*(r-1)+j]; 28196 28197 for (kk--,kr=r=0; r<k; r++,kr+=k) 28198 { 28199 D[r] = A[kr+r]; 28200 D[k+r] = A[kk-kr]; 28201 } 28202 28203 goto out; 28204 28205 err109: *jstat = -109; 28206 goto out; 28207 28208 err101: *jstat = -101; 28209 goto out; 28210 28211 out: 28212 if (A != SISL_NULL && A != Al) 28213 freearray(A); 28214 return ; 28215 } 28216 28217 28218 //=========================================================================== 28219 void s6sratder(double eder[],int idim,int ider1,int ider2,double gder[],int *jstat) 28220 //=========================================================================== 28221 { 28222 int kpos=0; /* Position of error. */ 28223 double w0; /* The denominator. */ 28224 int ki; /* Count through dimensions. */ 28225 int idu; /* Count through derivatives in u. */ 28226 int idv; /* Count through derivatives in v. */ 28227 int *binom=SISL_NULL; /* Array for binomial coefficients. */ 28228 int *binomu=SISL_NULL; /* Pointer to binomial coefficients in u. */ 28229 int *binomv=SISL_NULL; /* Pointer to binomial coefficients in v. */ 28230 double *sum1=SISL_NULL; /* Leibnitz expansion in u */ 28231 double *sum2=SISL_NULL; /* Leibnitz expansion in u and v. */ 28232 double sumdum1[4]; /* Fixed space for sum1. */ 28233 double sumdum2[4]; /* Fixed space for sum2. */ 28234 int idimp1; /* idim + 1. */ 28235 int iw; /* Pointer to a weight. */ 28236 int iwbase; /* Starting value of iw on each row. */ 28237 int igder; /* Pointer to already calculated derivs. */ 28238 int igbase; /* Starting value of igder on each row. */ 28239 int i,iu,iv,j,k; /* Counters. */ 28240 int ider1p1; /* ider1 + 1. */ 28241 int ider2p1; /* ider2 + 1. */ 28242 int igrow; /* (ider1+1) * idim. */ 28243 int iwrow; /* (ider1+1) * idimp1. */ 28244 int iwfix; /* Index of initial weight in sum. */ 28245 int bidum[10]; /* Array for storing binomial coeffs. */ 28246 int idermax; /* maximum of ider1 and ider2. */ 28247 double temp; /* Temporary multiple. */ 28248 28249 if (ider1<0 || ider2<0) goto err178; 28250 if (idim<1) goto err102; 28251 28252 *jstat = 0; 28253 28254 /* Find denominator. */ 28255 28256 w0 = eder[idim]; 28257 if (DEQUAL(w0,DZERO)) w0 = (double)1.0; 28258 28259 /* If we're only asked for position, we'll do it 28260 now and exit for the sake of speed. */ 28261 28262 if(ider1 == 0 && ider2 == 0) 28263 { 28264 for(ki=0; ki<idim; ki++) 28265 { 28266 gder[ki] = eder[ki] / w0; 28267 } 28268 28269 goto out; 28270 } 28271 28272 /* Set up some constants. */ 28273 28274 idimp1 = idim + 1; 28275 ider1p1 = ider1 + 1; 28276 ider2p1 = ider2 + 1; 28277 igrow = ider1p1 * idim; 28278 iwrow = igrow + ider1p1; /* = iderp1 * idimp1 */ 28279 28280 28281 /* Set up binomial coefficients. 28282 Use new array only when ider1 > 3 or ider2 > 3. */ 28283 28284 idermax = max(ider1,ider2); 28285 28286 if (idermax > 3) 28287 { 28288 binom = newarray(((idermax+1)*(idermax+2)) >> 1, INT); 28289 if(binom == SISL_NULL) goto err179; 28290 } 28291 else 28292 { 28293 binom = bidum; 28294 } 28295 28296 for(j=0,k=0; j<=idermax; j++,k+=j) 28297 { 28298 /* Calculate the new row of binomial coefficients. */ 28299 28300 binom[k] = 1; 28301 28302 for(i=k+1; i<k+j; i++) 28303 { 28304 binom[i] = binom[i-j-1] + binom[i-j]; 28305 } 28306 28307 binom[k+j] = 1; 28308 } 28309 28310 28311 /* Set up space for sum1 and sum2 if necessary. 28312 Use new arrays only when idim > 4. */ 28313 28314 if (idim > 4) 28315 { 28316 sum1 = newarray(idim, DOUBLE); 28317 if(sum1 == SISL_NULL) goto err179; 28318 sum2 = newarray(idim, DOUBLE); 28319 if(sum2 == SISL_NULL) goto err179; 28320 } 28321 else 28322 { 28323 sum1=sumdum1; 28324 sum2=sumdum2; 28325 } 28326 28327 28328 /* Loop through derivatives in u and v. */ 28329 28330 for(idv=0,binomv=binom,j=0,k=0; idv<=ider2; idv++,binomv+=idv) 28331 { 28332 28333 for(idu=0,binomu=binom; idu<=ider1; idu++,k++,binomu+=idu) 28334 { 28335 28336 28337 if(idu == 0 && idv == 0) 28338 { 28339 /* Position is a special case. */ 28340 28341 for(ki=0; ki<idim; ki++,j++,k++) 28342 { 28343 gder[j] = eder[k] / w0; 28344 } 28345 28346 } 28347 else 28348 { 28349 28350 /* Calculate each coefficient of the (idu,idv)'th 28351 derivative of the rational surface (in gder). 28352 28353 This requires calculating the Liebnitz sum from 28354 the subarray of gder (0,..,idu, 0,...,idv) and 28355 the subarray of eder (0,..,idu, 0,...,idv). */ 28356 28357 iwfix = k + idim; 28358 28359 /* Calculate the Leibnitz sum. */ 28360 28361 for(ki=0; ki<idim; ki++) 28362 { 28363 sum2[ki] = (double)0.0; 28364 } 28365 28366 for(iv=0,igbase=0,iwbase=iwfix; 28367 iv<=idv; 28368 iv++,igbase+=igrow,iwbase-=iwrow) 28369 { 28370 28371 for(ki=0; ki<idim; ki++) 28372 { 28373 sum1[ki] = (double)0.0; 28374 } 28375 28376 for(iu=0,igder=igbase,iw=iwbase; 28377 iu<=idu; 28378 iu++,iw-=idimp1) 28379 { 28380 /* Add the next Leibnitz term unless we 28381 have reached the last one (the unknown). */ 28382 28383 if(iu<idu || iv<idv) 28384 { 28385 /* If iu=0 or iu=idu, the u binomial 28386 coefficient is 1 so don't multiply. */ 28387 28388 if(iu>0 && iu<idu) 28389 { 28390 temp = (double)binomu[iu] * eder[iw]; 28391 28392 for(ki=0; ki<idim; ki++,igder++) 28393 { 28394 sum1[ki] += temp * gder[igder]; 28395 } 28396 } 28397 else 28398 { 28399 for(ki=0; ki<idim; ki++,igder++) 28400 { 28401 sum1[ki] += eder[iw] * gder[igder]; 28402 } 28403 } 28404 28405 } 28406 } 28407 28408 /* If iv=0 or iv=idv, the v binomial 28409 coefficient is 1 so don't multiply. */ 28410 28411 if(iv>0 && iv<idv) 28412 { 28413 for(ki=0; ki<idim; ki++) 28414 { 28415 sum2[ki] += (double)binomv[iv] * sum1[ki]; 28416 } 28417 } 28418 else 28419 { 28420 for(ki=0; ki<idim; ki++) 28421 { 28422 sum2[ki] += sum1[ki]; 28423 } 28424 } 28425 28426 } 28427 28428 for(ki=0; ki<idim; ki++,j++,k++) 28429 { 28430 gder[j] = (eder[k] - sum2[ki]) / w0; 28431 } 28432 28433 } 28434 28435 } 28436 28437 } 28438 28439 28440 /* Free arrays. */ 28441 28442 if (idermax > 3) 28443 { 28444 freearray(binom); 28445 } 28446 28447 if (idim > 4) 28448 { 28449 freearray(sum1); 28450 freearray(sum2); 28451 } 28452 28453 28454 28455 /* Done. */ 28456 28457 28458 goto out; 28459 28460 28461 /* idim less than 1. */ 28462 err102: *jstat = -102; 28463 s6err("s6ratder",*jstat,kpos); 28464 goto out; 28465 28466 /* Derivative negative */ 28467 err178: *jstat = -178; 28468 s6err("s6ratder",*jstat,kpos); 28469 goto out; 28470 28471 28472 /* Not enough memory */ 28473 err179: *jstat = -179; 28474 s6err("s6ratder",*jstat,kpos); 28475 goto out; 28476 28477 28478 out: 28479 return; 28480 } 28481 28482 28483 28484 //=========================================================================== 28485 void s1424(SISLSurf *ps1,int ider1,int ider2,double epar[], 28486 int *ileft1,int *ileft2,double eder[],int *jstat) 28487 //=========================================================================== 28488 { 28489 int kstat=0; /* Local status variable. */ 28490 int kpos=0; /* The position of error. */ 28491 int kn1,kn2; /* The number of B-splines accociated with the knot 28492 vectors st1 and st2. */ 28493 int kk1,kk2; /* The polynomial order of the surface in the two 28494 directions. */ 28495 int kdim; /* The dimension of the space in which the surface 28496 lies. Equivalently, the number of components 28497 of each B-spline coefficient. */ 28498 int kder1,kder2; /* Local versions of ider1 and ider2. Since 28499 derivatives of order higher than kk1-1 and kk2-1, 28500 respectively, are all zero, we set 28501 kder1=min(kk1-1,ider1) and kder2=(kk2-1,ider2). */ 28502 int kleft2,kleft1; /* Local versions of ileft1 and ileft2 which are 28503 used in order to avoid the pointers. */ 28504 int ki,kj,kih,kjh; /* Control variables in for loops and for stepping 28505 through arrays. */ 28506 int kh,kl,kl1,kl2; /* Control variables in for loops and for stepping 28507 through arrays. */ 28508 double *st1,*st2; /* The knot vectors of the surface. These have 28509 length [kn1+kk1] and [kn2+kk2], 28510 respectively. */ 28511 double *scoef; /* The B-spline coefficients of the surface. 28512 This is an array of dimension [kn2*kn1*kdim]. */ 28513 double tt; /* Dummy variable used for holding an array element 28514 in a for loop. */ 28515 double *ebder=SISL_NULL; /* Pointer to an array of dimension 28516 [max(kk1*(ider1+1),kk2*(ider2+1))] which will 28517 contain the values and ider first derivatives of 28518 the kk1 (kk2) nonzero B-splines at epar[0] (epar[1]). 28519 These are stored in the following order: 28520 First the value, 1. derivative etc. of the 28521 first nonzero B-spline, then the same for the 28522 second nonzero B-spline and so on. */ 28523 28524 double *ew=SISL_NULL; /* Pointer to an array of dimension [kk1*(ider1+1)*kdim] 28525 which will be used to store the result of the first 28526 matrix multiplication in (2) above. This array is 28527 initialized to all zeros. */ 28528 double *sder=SISL_NULL; /* Pointer to array used for storage of points, if 28529 non rational sder points to eder, if rational sder 28530 has to be allocated to make room for the homogenous 28531 coordinate */ 28532 28533 double sdum1[49]; /* Arraye used for ebder */ 28534 double sdum2[147]; /* Array used for ew */ 28535 int knumb1; /* Necessary size of ebder */ 28536 int knumb2; /* Necessary size of ew */ 28537 28538 kleft1 = *ileft1; 28539 kleft2 = *ileft2; 28540 28541 /* Copy surface to local parameters. */ 28542 28543 kn1 = ps1 -> in1; 28544 kn2 = ps1 -> in2; 28545 kk1 = ps1 -> ik1; 28546 kk2 = ps1 -> ik2; 28547 st1 = ps1 -> et1; 28548 st2 = ps1 -> et2; 28549 kdim = ps1 -> idim; 28550 if (ps1->ikind == 2 || ps1->ikind == 4) 28551 { 28552 scoef = ps1 -> rcoef; 28553 kdim +=1; 28554 if((sder = newarray(kdim*(ider1+1)*(ider2+1),DOUBLE)) == SISL_NULL) 28555 goto err101; 28556 } 28557 else 28558 { 28559 scoef = ps1 -> ecoef; 28560 sder = eder; 28561 } 28562 28563 /* Check the input. */ 28564 28565 if (kdim < 1) goto err102; 28566 if (kk1 < 1) goto err115; 28567 if (kn1 < kk1 || kn2 < kk2) goto err116; 28568 if (ider1 < 0 || ider2 < 0) goto err178; 28569 if (st1[kk1-1] == st1[kk1] || st1[kn1-1] == st1[kn1]) goto err117; 28570 if (st2[kk2-1] == st2[kk2] || st2[kn2-1] == st2[kn2]) goto err117; 28571 if (ps1->ikind == 1 || ps1->ikind == 3) 28572 { 28573 kder1 = min(kk1-1,ider1); 28574 kder2 = min(kk2-1,ider2); 28575 } 28576 else 28577 { 28578 kder1 = ider1; 28579 kder2 = ider2; 28580 } 28581 28582 /* Allocate space for B-spline values and derivatives and one work array. */ 28583 28584 knumb1 = max(kk1*(kder1+1),kk2*(kder2+1)); 28585 28586 /* ONly allocate ebder if sdum1 too small */ 28587 28588 if (knumb1>49) 28589 { 28590 if((ebder = newarray(knumb1,double)) == SISL_NULL) goto err101; 28591 } 28592 else 28593 { 28594 ebder = &sdum1[0]; 28595 for (ki=0;ki<knumb1;ki++) 28596 ebder[ki] = DZERO; 28597 } 28598 28599 if (ebder == SISL_NULL) goto err101; 28600 28601 /* Only allocate ew if sdum2 too small */ 28602 28603 knumb2 = (kk1*(kder2+1)*kdim); 28604 if (knumb2>147) 28605 { 28606 if((ew = new0array(knumb2,double)) == SISL_NULL) goto err101; 28607 } 28608 else 28609 { 28610 ew = &sdum2[0]; 28611 for (ki=0;ki<knumb2;ki++) 28612 sdum2[ki] = DZERO; 28613 } 28614 28615 if (ew == SISL_NULL) goto err101; 28616 28617 /* Set all the elements of sder to 0. */ 28618 28619 for (ki=0; ki<(ider2+1)*(ider1+1)*kdim; ki++) sder[ki] = DZERO; 28620 28621 /* Compute the values and derivatives of the nonzero B-splines in the 28622 second parameter direction. */ 28623 28624 s1220(st2,kk2,kn2,&kleft2,epar[1],kder2,ebder,&kstat); 28625 28626 if (kstat < 0) goto error; 28627 28628 /* Update ileft1 (ileft2 was updated above, in s1220). */ 28629 28630 s1219(st1,kk1,kn1,&kleft1,epar[0],&kstat); 28631 28632 if (kstat < 0) goto error; 28633 28634 /* Compute the first matrix product in (2) above. */ 28635 28636 /* ki steps through the appropriate kk2 rows of B-spline coefficients 28637 while kih steps through the B-spline value and derivatives for the 28638 B-spline given by ki. */ 28639 28640 kih = 0; 28641 for (ki=kleft2-kk2+1; ki<=kleft2; ki++) 28642 { 28643 28644 /* kj counts through the kder2+1 derivatives to be computed. 28645 kjh steps through ew once for each ki to accumulate the contribution 28646 from the different B-splines. 28647 kl1 points to the first component of the first B-spline coefficient 28648 in row no. ki of the B-spline coefficient matrix that multiplies 28649 a nonzero B-spline in the first parameter direction. 28650 */ 28651 28652 kjh = 0; kl1 = ki*kdim*kn1 + kdim*(kleft1-kk1+1); 28653 for (kj=0; kj<=kder2; kj++) 28654 { 28655 28656 /* The value of the B-spline derivative is stored in tt while 28657 kl2 steps through the kdim components of all the B-spline 28658 coefficients that multiplies nonzero B-splines along st1. 28659 */ 28660 28661 tt = ebder[kih++]; kl2 = kl1; 28662 for (kl=0; kl<kdim*kk1; kl++,kjh++,kl2++) 28663 { 28664 ew[kjh] += scoef[kl2]*tt; 28665 } 28666 } 28667 } 28668 28669 /* Compute the values and derivatives of the nonzero B-splines in the 28670 first parameter direction. */ 28671 28672 s1220(st1,kk1,kn1,&kleft1,epar[0],kder1,ebder,&kstat); 28673 28674 if (kstat < 0) goto error; 28675 28676 /* Compute the remaining matrix product. */ 28677 28678 /* kh steps through the kder2+1 derivatives in the first parameter direction 28679 (the rows of ew if we image it as a kk1x(ider1+1) matrix with each element 28680 a kdim dimensional vector) while kl1 steps through the elements of ew 28681 (again considering each element to have kdim components). 28682 */ 28683 28684 kl1 = 0; 28685 for (kh=0; kh<=kder2; kh++) 28686 { 28687 28688 /* ki steps through the kk1 columns of ew (corresponding to the columns 28689 of scoef that multiply nonzero B-splines along st1), while kih 28690 steps through the B-spline values and derivatives for the nonzero 28691 B-splines along st1 (stored in ebder). 28692 */ 28693 28694 kih = 0; 28695 for (ki=0; ki<kk1; ki++) 28696 { 28697 28698 /* kj counts through the kder1+1 derivatives in the first 28699 parameter direction (corresponding to the columns of sder). 28700 kjh points to the row of sder corresponding to derivatives of 28701 order kh in the second parameter direction (if sder is 28702 considered a matrix with elements consisting of vectors with 28703 kdim components. 28704 */ 28705 28706 kjh = kh*(kder1+1)*kdim; 28707 for (kj=0; kj<=kder1; kj++) 28708 { 28709 /* Pick out the current element of ebder. 28710 kl2 steps through the kdim components of the (kh,ki) 28711 element of ew. 28712 */ 28713 28714 tt = ebder[kih++]; 28715 kl2 = kl1; 28716 for (kl=0; kl<kdim; kl++,kjh++,kl2++) 28717 { 28718 sder[kjh] += ew[kl2]*tt; 28719 } 28720 } 28721 kl1 += kdim; 28722 } 28723 } 28724 28725 if (kder1 < ider1 || kder2 < ider2) 28726 28727 /* The derivatives are not positioned in the right way in sder, 28728 shift values into the right position 28729 */ 28730 28731 for (kj=ider2 ; 0<=kj ; kj--) 28732 { 28733 for (ki=ider1 ; 0<=ki ; ki--) 28734 { 28735 if ( ki <= kder1 && kj <= kder2) 28736 memcopy(sder+kdim*(ki+kj*(ider1+1)),sder+kdim*(ki+kj*(kder1+1)), 28737 kdim,DOUBLE); 28738 else 28739 for (kl=0;kl<kdim;kl++) 28740 *(sder+kdim*(ki+kj*(ider1+1))+kl) = DZERO; 28741 } 28742 } 28743 28744 /* Free memory. */ 28745 28746 /* If rational surface calculate the derivatives based on derivatives in 28747 homogenous coordinates */ 28748 28749 if (ps1->ikind == 2 || ps1->ikind == 4) 28750 { 28751 s6sratder(sder,ps1->idim,ider1,ider2,eder,&kstat); 28752 if (kstat<0) goto error; 28753 if(sder != SISL_NULL) freearray(sder); 28754 } 28755 28756 /* Only free ew and ebder if the were allocated by newarray */ 28757 28758 if (knumb1 > 49 && ebder != SISL_NULL) freearray(ebder); 28759 if (knumb2 > 147 && ew != SISL_NULL) freearray(ew); 28760 28761 /* Successful computations. */ 28762 28763 *jstat = 0; 28764 goto out; 28765 28766 /* Not enough memory. */ 28767 28768 err101: 28769 *jstat = -101; 28770 s6err("s1424",*jstat,kpos); 28771 goto out; 28772 28773 /* kdim less than 1. */ 28774 28775 err102: 28776 *jstat = -102; 28777 s6err("s1424",*jstat,kpos); 28778 goto out; 28779 28780 /* Polynomial order less than 1. */ 28781 28782 err115: 28783 *jstat = -115; 28784 s6err("s1424",*jstat,kpos); 28785 goto out; 28786 28787 /* Fewer B-splines than the order. */ 28788 28789 err116: 28790 *jstat = -116; 28791 s6err("s1424",*jstat,kpos); 28792 goto out; 28793 28794 /* Error in knot vector. 28795 (The first or last interval of one of the knot vectors is empty.) */ 28796 28797 err117: 28798 *jstat = -117; 28799 s6err("s1424",*jstat,kpos); 28800 goto out; 28801 28802 /* Illegal derivative requested. */ 28803 28804 err178: 28805 *jstat = -178; 28806 s6err("s1424",*jstat,kpos); 28807 goto out; 28808 28809 /* Error in lower level routine. */ 28810 28811 error: 28812 *jstat = kstat; 28813 s6err("s1424",*jstat,kpos); 28814 goto out; 28815 28816 out: 28817 *ileft1 = kleft1; 28818 *ileft2 = kleft2; 28819 return; 28820 } 28821 28822 28823 28824 //=========================================================================== 28825 void s6hermite_bezier(SISLSurf* s,double a[],double b[],int idim, double c[],int* jstat) 28826 //=========================================================================== 28827 { 28828 int i,kstat,left1=0,left2=0; 28829 double dblocal[9]; 28830 double *derive=SISL_NULL; 28831 28832 28833 if (DEQUAL(a[0],b[0]) && DEQUAL(a[1],b[1])) goto error; 28834 if (s->idim != idim) goto error; 28835 28836 if ( idim > 3) 28837 { 28838 derive = newarray(3*idim,double); 28839 if (derive == SISL_NULL) goto err101; 28840 } 28841 else 28842 derive = dblocal; 28843 28844 /* evaluate s and its derivative at a */ 28845 28846 s1424(s,1,1,a,&left1,&left2,derive,&kstat); 28847 if (kstat < 0) goto error; 28848 for (i=0; i < idim; i++) 28849 { 28850 c[i] = derive[i]; 28851 c[idim+i] = c[i] + (derive[idim+i]*(b[0]-a[0]) 28852 + derive[2*idim+i]*(b[1]-a[1]))/3.0; 28853 } 28854 28855 /* evaluate s and its derivative at b */ 28856 28857 s1424(s,1,1,b,&left1,&left2,derive,&kstat); 28858 if (kstat < 0) goto error; 28859 for (i=0; i < idim; i++) 28860 { 28861 c[3*idim+i] = derive[i]; 28862 c[2*idim+i] = c[3*idim+i] - (derive[idim+i]*(b[0]-a[0]) 28863 + derive[2*idim+i]*(b[1]-a[1]))/3.0; 28864 } 28865 28866 *jstat = 0; 28867 goto out; 28868 28869 /* Error in space allocation. */ 28870 28871 err101 : 28872 *jstat = -101; 28873 goto out; 28874 28875 28876 /* Error in lower level routine. */ 28877 28878 error : 28879 *jstat = kstat; 28880 goto out; 28881 28882 28883 out : 28884 28885 if (derive != SISL_NULL && derive != dblocal) 28886 freearray(derive); 28887 28888 return; 28889 28890 } 28891 28892 //=========================================================================== 28893 void s6identify(SISLSurf* s,double a[], double b[], double level_val, 28894 double eps1,double eps2,int* jstat) 28895 //=========================================================================== 28896 { 28897 double c[4],cref[8]; 28898 int i,kstat; 28899 28900 if ( s == SISL_NULL || 28901 (a[0] < s->et1[0] || a[0] > s->et1[s->in1]) || 28902 (a[1] < s->et2[0] || a[1] > s->et2[s->in2]) || 28903 (b[0] < s->et1[0] || b[0] > s->et1[s->in1]) || 28904 (b[1] < s->et2[0] || b[1] > s->et2[s->in2]) ) 28905 goto err109; 28906 28907 if (DEQUAL(a[0],b[0]) && DEQUAL(a[1],b[1])) 28908 { 28909 kstat = 1; 28910 goto out; 28911 } 28912 if ( sqrt((a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1])) > eps1 ) 28913 kstat = 0; 28914 else 28915 { 28916 s6hermite_bezier(s,a,b,1,c,&kstat); 28917 if (kstat < 0) goto error; 28918 28919 s6deCasteljau(c,0.0,1.0,0.5,4,cref,&kstat); 28920 if (kstat < 0) goto error; 28921 28922 kstat = 1; 28923 for (i=0; i<8; i++) 28924 if (fabs(cref[i]-level_val) > eps2) 28925 kstat = 0; 28926 } 28927 28928 goto out; 28929 28930 err109: kstat = -109; 28931 s6err("s6identify",kstat,0); 28932 goto out; 28933 28934 28935 error: 28936 s6err("s6identify",kstat,0); 28937 goto out; 28938 28939 out: 28940 *jstat = kstat; 28941 return ; 28942 } 28943 28944 28945 //=========================================================================== 28946 SISLIntdat *newIntdat (void) 28947 //=========================================================================== 28948 { 28949 SISLIntdat *pnew = SISL_NULL; /* Local pointer to the instance. */ 28950 28951 /* Allocate space for instance. */ 28952 28953 if ((pnew = newarray (1, SISLIntdat)) != SISL_NULL) 28954 { 28955 /* Initiate the variables of the instance. */ 28956 pnew->ipmax = 20; 28957 pnew->ilmax = 10; 28958 pnew->ipoint = 0; 28959 pnew->ilist = 0; 28960 28961 /* Allocate space for array of pointers to Intlist. */ 28962 28963 if ((pnew->vlist = new0array (pnew->ilmax, SISLIntlist *)) != SISL_NULL) 28964 { 28965 /* Allocate space for array of pointers to SISLIntpt */ 28966 if ((pnew->vpoint = new0array (pnew->ipmax, SISLIntpt *)) 28967 != SISL_NULL) ; 28968 28969 /* Task done. */ 28970 28971 else 28972 { 28973 /* Error in space allocation of pnew->vpoint.*/ 28974 freearray (pnew->vlist); 28975 freearray (pnew); 28976 } 28977 } 28978 else 28979 /* Error in space allocation of pnew->vlist. */ 28980 freearray (pnew); 28981 } 28982 return pnew; 28983 } 28984 28985 28986 //=========================================================================== 28987 void sh_1d_div_sh9idnpt(SISLSurf* surf, SISLPoint* point, SISLIntdat **pintdat, 28988 SISLIntpt **pintpt, int itest, double aepsge, int *jstat) 28989 //=========================================================================== 28990 { 28991 register int ki; /* Counters. */ 28992 double eps_ball_par; 28993 int kstat; 28994 28995 /* We have to be sure that we have an intdat structure. */ 28996 28997 if ((*pintdat) == SISL_NULL) 28998 { 28999 if (((*pintdat) = newIntdat()) == SISL_NULL) goto err101; 29000 } 29001 29002 29003 /* Then we have to be sure that we do not have the intersection point 29004 before or an equal point. */ 29005 29006 for (ki=0; ki<(*pintdat)->ipoint; ki++) 29007 if ((*pintdat)->vpoint[ki] == (*pintpt)) 29008 { 29009 *jstat = 1; 29010 goto out; 29011 } 29012 else if (itest) 29013 { 29014 eps_ball_par = surf->et1[surf->in1]- surf->et1[surf->ik1]; 29015 eps_ball_par = max(eps_ball_par, 29016 surf->et2[surf->in2]- surf->et2[surf->ik2])+1; 29017 eps_ball_par *= 1e-6; 29018 29019 s6identify(surf,(*pintpt)->epar, 29020 (*pintdat)->vpoint[ki]->epar, 29021 point->ecoef[0],eps_ball_par,aepsge,&kstat); 29022 if (kstat < 0 ) goto error; 29023 if (kstat == 1 ) 29024 { 29025 freeIntpt(*pintpt); 29026 (*pintpt) = (*pintdat)->vpoint[ki]; 29027 *jstat = 2; 29028 goto out; 29029 } 29030 } 29031 29032 29033 /* Then we have to be sure that the array vpoint is great enough. */ 29034 29035 if (ki == (*pintdat)->ipmax) 29036 { 29037 (*pintdat)->ipmax += 20; 29038 29039 if (((*pintdat)->vpoint = increasearray((*pintdat)->vpoint, 29040 (*pintdat)->ipmax,SISLIntpt *)) == SISL_NULL) 29041 goto err101; 29042 } 29043 29044 29045 /* Now we can insert the new point. */ 29046 29047 (*pintdat)->vpoint[ki] = (*pintpt); 29048 (*pintdat)->ipoint++; 29049 *jstat = 0; 29050 goto out; 29051 29052 29053 /* Error in space allocation. */ 29054 29055 err101: *jstat = -101; 29056 s6err("sh_1d_div_sh9idnpt",*jstat,0); 29057 goto out; 29058 error: *jstat = kstat; 29059 s6err("sh_1d_div_sh9idnpt",*jstat,0); 29060 goto out; 29061 29062 out: ; 29063 } 29064 29065 29066 29067 //=========================================================================== 29068 void sh_1d_div (SISLObject *po1, SISLObject *po2, double aepsge, 29069 SISLIntdat **pintdat, SISLEdge * vedge[], int *jstat) 29070 //=========================================================================== 29071 { 29072 29073 int kant; /* Number of parameter directions */ 29074 int cv_dir_1, cv_dir_2; /* Locals for curve_dir */ 29075 int ind1, ind2; /* Locals indexes */ 29076 int kpos = 0; /* Position of error. */ 29077 int kstat = 0; /* Local error status. */ 29078 int knum; /* Number of intersection pts on edge */ 29079 int knum2; /* Number of intersection pts in corners */ 29080 int which_end_1=-1; /* Branch paraeter fro zero edge. */ 29081 int which_end_2=-1; /* Branch paraeter fro zero edge. */ 29082 int kn, kj, ki; /* Loop control */ 29083 int edge_1=0, edge_2=0; /* No of pts in pt_arr_1[2] */ 29084 int alloc_1=0, alloc_2=0; /* Size of pt_arr_1[2] */ 29085 SISLIntpt *pcurr = SISL_NULL; /* Array of poiners to int points. */ 29086 SISLIntpt **uintpt = SISL_NULL; /* Array of poiners to int points. */ 29087 SISLIntpt **up = SISL_NULL; /* Array of poiners to edge int points. */ 29088 SISLIntpt **pt_arr_1 = SISL_NULL; /* Array of poiners to ZERO edge. */ 29089 SISLIntpt **pt_arr_2 = SISL_NULL; /* Array of poiners to ZERO edge. */ 29090 SISLIntpt **up2 = SISL_NULL; /* Array of poiners to corner int points. */ 29091 SISLIntdat *qintdat = SISL_NULL; /* Data structure of sub inters problem */ 29092 SISLObject *qo1 = SISL_NULL; /* Pointer to surface in 29093 object/point intersection. */ 29094 double *nullp = SISL_NULL; 29095 /* ____________________________________________________________________ */ 29096 29097 *jstat = 0; 29098 29099 /* Check input */ 29100 if (po1->iobj != SISLSURFACE) goto err150; 29101 if (po1->s1->idim != 1) goto err150; 29102 29103 /* Bezier case ? */ 29104 if (po1->s1->ik1 != po1->s1->in1 || 29105 po1->s1->ik2 != po1->s1->in2) goto out; 29106 29107 if (po1->s1->ik1 < 3 || 29108 po1->s1->ik2 < 3 ) goto out; 29109 29110 sh6edgpoint (vedge, &up, &knum, &kstat); 29111 if (kstat < 0) 29112 goto error; 29113 if (knum < 2) goto out; 29114 29115 /* Find corner points */ 29116 /* Allocate an array for intersection points. */ 29117 if ((up2= newarray (knum, SISLIntpt *)) == SISL_NULL) 29118 goto err101; 29119 29120 for (knum2=ki=0;ki<knum;ki++) 29121 { 29122 sh6isinside (po1, po2, up[ki], &kstat); 29123 if (kstat < 0 ) goto error; 29124 29125 if (kstat == 3) 29126 { 29127 up2[knum2] = up[ki]; 29128 knum2++; 29129 } 29130 } 29131 29132 if (knum2 < 2) goto out; 29133 29134 /* Find connections */ 29135 for (ki=0;ki<knum2-1;ki++) 29136 for (kj=1;kj<knum2;kj++) 29137 { 29138 sh6comedg (po1, po2, up2[ki], up2[kj], &kstat); 29139 if (kstat < 0) goto error; 29140 29141 if (kstat == 1) 29142 { 29143 /* One edge is zero, find which */ 29144 if (DEQUAL(up2[ki]->epar[0], up2[kj]->epar[0])) 29145 { 29146 29147 /* Store the two corner points (sorted). */ 29148 if (alloc_1 == 0) 29149 { 29150 alloc_1 = 10; 29151 if((pt_arr_1 = newarray(alloc_1,SISLIntpt *)) 29152 == SISL_NULL) goto err101; 29153 } 29154 edge_1 = 2; 29155 if (up2[ki]->epar[1] < up2[kj]->epar[1]) 29156 { 29157 pt_arr_1[0] = up2[ki]; 29158 pt_arr_1[1] = up2[kj]; 29159 } 29160 else 29161 { 29162 pt_arr_1[1] = up2[ki]; 29163 pt_arr_1[0] = up2[kj]; 29164 } 29165 29166 if (DEQUAL(up2[ki]->epar[0],po1->s1->et1[0])) 29167 which_end_1 = 0; 29168 else 29169 which_end_1 = 1; 29170 } 29171 else 29172 { 29173 29174 /* Store the two corner points (sorted). */ 29175 if (alloc_2 == 0) 29176 { 29177 alloc_2 = 10; 29178 if((pt_arr_2 = newarray(alloc_2,SISLIntpt *)) 29179 == SISL_NULL) goto err101; 29180 } 29181 edge_2 = 2; 29182 if (up2[ki]->epar[0] < up2[kj]->epar[0]) 29183 { 29184 pt_arr_2[0] = up2[ki]; 29185 pt_arr_2[1] = up2[kj]; 29186 } 29187 else 29188 { 29189 pt_arr_2[1] = up2[ki]; 29190 pt_arr_2[0] = up2[kj]; 29191 } 29192 29193 if (DEQUAL(up2[ki]->epar[1],po1->s1->et2[0])) 29194 which_end_2 = 0; 29195 else 29196 which_end_2 = 1; 29197 } 29198 29199 } 29200 } 29201 29202 if (which_end_1 >=0 || which_end_2 >=0) 29203 { 29204 29205 /* 29206 * Create new object and create surface to object. 29207 * ------------------------------------------------ 29208 */ 29209 29210 if (!(qo1 = newObject (SISLSURFACE))) 29211 goto err101; 29212 qo1->s1 = SISL_NULL; 29213 qo1->o1 = qo1; 29214 29215 /* Filter coefficients less than aepsge. */ 29216 for (ki=0; ki< po1->s1->in1*po1->s1->in2;ki++) 29217 if ( fabs(po1->s1->ecoef[ki]-po2->p1->ecoef[0]) < aepsge) 29218 po1->s1->ecoef[ki] = po2->p1->ecoef[0]; 29219 29220 sh_div_surf(po1->s1,which_end_1, which_end_2, aepsge, &qo1->s1, &kstat); 29221 if (kstat < 0) goto error; 29222 29223 sh1761 (qo1, po2, aepsge, &qintdat, &kstat); 29224 if (kstat < 0) 29225 goto error; 29226 29227 /* UJK, JUNE 93: start____________ */ 29228 if (qintdat) 29229 { 29230 29231 /* Kill all help.pts. */ 29232 for (ki = 0; ki < qintdat->ipoint; ki++) 29233 { 29234 pcurr = qintdat->vpoint[ki]; 29235 if(sh6ishelp(pcurr)) 29236 { 29237 sh6idkpt (&qintdat, &pcurr, 0, &kstat); 29238 if (kstat < 0) goto error; 29239 ki--; 29240 } 29241 } 29242 } 29243 /* UJK, JUNE 93: end____________ */ 29244 29245 if (qintdat) 29246 { 29247 /* Intersection found, transfere it to pintdat. */ 29248 29249 /* Number of parameter direction. */ 29250 kant = qintdat->vpoint[0]->ipar; 29251 29252 /* Allocate an array for intersection points. */ 29253 if ((uintpt = newarray (qintdat->ipoint, SISLIntpt *)) == SISL_NULL) 29254 goto err101; 29255 29256 /* Copy all intersection points. */ 29257 for (ki = 0; ki < qintdat->ipoint; ki++) 29258 { 29259 29260 uintpt[ki] = hp_newIntpt (kant, 29261 qintdat->vpoint[ki]->epar, 29262 qintdat->vpoint[ki]->adist, 29263 qintdat->vpoint[ki]->iinter, 29264 qintdat->vpoint[ki]->left_obj_1[0], 29265 qintdat->vpoint[ki]->right_obj_1[0], 29266 qintdat->vpoint[ki]->left_obj_2[0], 29267 qintdat->vpoint[ki]->right_obj_2[0], 29268 0, 0, 29269 nullp, nullp); 29270 29271 if (uintpt[ki] == SISL_NULL) 29272 goto err101; 29273 } 29274 29275 /* Insert all new intersection points in rintdat. */ 29276 29277 for (ki = 0; ki < qintdat->ipoint; ki++) 29278 { 29279 sh_1d_div_sh9idnpt (po1->o1->s1,po2->p1,pintdat, &uintpt[ki], 1,aepsge, 29280 &kstat); 29281 if (kstat < 0) 29282 goto error; 29283 } 29284 29285 29286 /* Insert points on edges divided out/(splitting strategy. */ 29287 for (ki = 0; ki < qintdat->ipoint; ki++) 29288 { 29289 if (which_end_1 >=0 && 29290 DEQUAL(uintpt[ki]->epar[0], pt_arr_1[0]->epar[0]) && 29291 DEQUAL(uintpt[ki]->epar[0], pt_arr_1[1]->epar[0])) 29292 { 29293 for (kj=0; kj < edge_1 - 1; kj++) 29294 if (uintpt[ki]->epar[1] > pt_arr_1[kj]->epar[1] && 29295 uintpt[ki]->epar[1] < pt_arr_1[kj+1]->epar[1]) 29296 { 29297 sh6insertpt(pt_arr_1[kj],pt_arr_1[kj+1],uintpt[ki],&kstat); 29298 if (kstat < 0) goto error; 29299 if (edge_1 >= alloc_1) 29300 { 29301 alloc_1 += 10; 29302 if ((pt_arr_1 = 29303 increasearray(pt_arr_1,alloc_1,SISLIntpt *)) 29304 == SISL_NULL) goto err101; 29305 } 29306 29307 for (kn = edge_1; kn > kj+1; kn--) 29308 pt_arr_1[kn] = pt_arr_1[kn-1]; 29309 pt_arr_1[kj+1] = uintpt[ki]; 29310 edge_1++; 29311 29312 break; 29313 } 29314 } 29315 else if (which_end_2 >=0 && 29316 DEQUAL(uintpt[ki]->epar[1], pt_arr_2[0]->epar[1]) && 29317 DEQUAL(uintpt[ki]->epar[1], pt_arr_2[1]->epar[1])) 29318 { 29319 for (kj=0; kj < edge_2 - 1; kj++) 29320 if (uintpt[ki]->epar[0] > pt_arr_2[kj]->epar[0] && 29321 uintpt[ki]->epar[0] < pt_arr_2[kj+1]->epar[0]) 29322 { 29323 sh6insertpt(pt_arr_2[kj],pt_arr_2[kj+1],uintpt[ki],&kstat); 29324 if (kstat < 0) goto error; 29325 if (edge_2 >= alloc_2) 29326 { 29327 alloc_2 += 10; 29328 if ((pt_arr_2 = 29329 increasearray(pt_arr_2,alloc_2,SISLIntpt *)) 29330 == SISL_NULL) goto err101; 29331 } 29332 29333 for (kn = edge_2; kn > kj+1; kn--) 29334 pt_arr_2[kn] = pt_arr_2[kn-1]; 29335 pt_arr_2[kj+1] = uintpt[ki]; 29336 edge_2++; 29337 29338 break; 29339 } 29340 } 29341 29342 } 29343 29344 29345 /* Transform the connections. */ 29346 for (ki = 0; ki < qintdat->ipoint; ki++) 29347 { 29348 for (kj = ki + 1; kj < qintdat->ipoint; kj++) 29349 { 29350 sh6getlist (qintdat->vpoint[ki], qintdat->vpoint[kj], 29351 &ind1, &ind2, &kstat); 29352 if (kstat < 0) 29353 goto error; 29354 if (kstat == 0 && uintpt[kj] != uintpt[ki]) 29355 { 29356 cv_dir_1 = qintdat->vpoint[ki]->curve_dir[ind1]; 29357 cv_dir_2 = qintdat->vpoint[kj]->curve_dir[ind2]; 29358 29359 sh6idcon (pintdat, &uintpt[ki], &uintpt[kj], &kstat); 29360 if (kstat < 0) 29361 goto error; 29362 29363 sh6getlist (uintpt[ki], uintpt[kj], 29364 &ind1, &ind2, &kstat); 29365 if (kstat != 0) goto error; 29366 uintpt[ki]->curve_dir[ind1] |= cv_dir_1; 29367 uintpt[kj]->curve_dir[ind2] |= cv_dir_2; 29368 29369 } 29370 } 29371 29372 if (sh6ismain (qintdat->vpoint[ki]) && 29373 sh6nmbmain (qintdat->vpoint[ki], &kstat)) 29374 { 29375 sh6tomain (uintpt[ki], &kstat); 29376 if (kstat < 0) 29377 goto error; 29378 } 29379 } 29380 29381 /* Remains splitting of zero curves inside edges ! */ 29382 29383 } 29384 29385 *jstat = 1; 29386 } 29387 29388 29389 29390 goto out; 29391 /* ______________ ERROR EXITS ______________________________ */ 29392 /* Lower level problem. */ 29393 error: 29394 *jstat = kstat; 29395 s6err("sh_1d_div",*jstat,kpos); 29396 goto out; 29397 29398 /* Space problem. */ 29399 err101: 29400 *jstat = -101; 29401 s6err("sh_1d_div",*jstat,kpos); 29402 goto out; 29403 29404 /* Input wrong. */ 29405 err150: 29406 *jstat = -150; 29407 s6err("sh_1d_div",*jstat,kpos); 29408 goto out; 29409 29410 29411 out: 29412 if (uintpt) freearray(uintpt); 29413 if (up) freearray(up); 29414 if (up2) freearray(up2); 29415 if (pt_arr_1) freearray(pt_arr_1); 29416 if (pt_arr_2) freearray(pt_arr_2); 29417 if (qo1) 29418 freeObject (qo1); 29419 if (qintdat) 29420 freeIntdat (qintdat); 29421 } 29422 29423 29424 //=========================================================================== 29425 void s1797(SISLSurf *ps1,SISLCurve *pc1,double aepsge,double aang,int *jstat) 29426 //=========================================================================== 29427 { 29428 int kpos = 0; /* Position of the error. */ 29429 int kstat; /* Local status variable. */ 29430 int ki; /* Counter. */ 29431 int kn; /* Number of vertices of curve. */ 29432 int kn1; /* Number of vertices of surface in 1. par. direction.*/ 29433 int kn2; /* Number of vertices of surface in 2. par. direction.*/ 29434 int kdim; /* Dimension of the space in which the objects lie. */ 29435 int kdim4; /* Help variable to contain 4*kdim. */ 29436 int kver,khor; /* The index to the vertice in the upper left corner 29437 to the patch to treat. */ 29438 int k1,k2,k3,k4; /* Control variables in loop. */ 29439 double *t=SISL_NULL; /* Allocating t[5][kdim]. Five tangents around the 29440 patch, the first and the last is the same. */ 29441 double *tn; /* Allocating tn[4][kdim]. Four normals in the corner 29442 of the patch. */ 29443 double *scen1; /* The orginal basis vector to the projection plan. */ 29444 double *scen2; /* The computed basis vector to the projection plan.*/ 29445 double tlen; /* The length of a vector. */ 29446 double tang; /* An angle between two vectors. */ 29447 double tang1=DZERO;/* An angle between two vectors. */ 29448 double tang2=DZERO;/* An angle between two vectors. */ 29449 double t1,t2;/* Help variables. */ 29450 double slen[5]; /* Distances between coefficients. */ 29451 double scorn[4]; /* Angle between derivatives in corner of patch. */ 29452 29453 29454 29455 /* Initialate dimentions. */ 29456 29457 kdim = ps1 -> idim; 29458 kdim4 = 4*kdim; 29459 29460 29461 /* Allocate local used matrices, t[5][kdim] and tn[4][kdim]. */ 29462 29463 if ((t = newarray(10*kdim,double)) == SISL_NULL) goto err101; 29464 29465 tn = t + 5*kdim; 29466 29467 scen1 = ps1->pdir->ecoef; 29468 scen2 = tn + 4*kdim; 29469 tlen = s6scpr(scen1,pc1->pdir->ecoef,kdim); 29470 for (k1=0; k1 < kdim; k1++) 29471 scen2[k1] = pc1->pdir->ecoef[k1] - tlen*scen1[k1]; 29472 tlen = s6length(scen2,kdim,&kstat); 29473 for (k1=0; k1 < kdim; k1++) 29474 scen2[k1] /= tlen; 29475 29476 kn1 = ps1 -> in1; 29477 kn2 = ps1 -> in2; 29478 29479 /* Here we are treating each patch in the control polygon separately.*/ 29480 29481 for (kver=0; kver < (kn2-1); kver++) 29482 for (khor=0; khor < (kn1-1); khor++) 29483 { 29484 slen[0] = slen[1] = slen[2] = slen[3] = DZERO; 29485 scorn[0] = scorn[1] = scorn[2] = scorn[3] = DZERO; 29486 29487 /* Here we make the tangents in each corner of the patch, 29488 and in direction with the clock. The first and the last 29489 vector contains both the first tangent. */ 29490 29491 k2 = (kver*kn1+khor)*kdim; 29492 29493 for (k1=0; k1 < kdim; k1++,k2++) 29494 { 29495 t[kdim+k1] = ps1->pdir->esmooth[k2+kdim] - ps1->pdir->esmooth[k2]; 29496 t[2*kdim+k1] = ps1->pdir->esmooth[k2+(kn1+1)*kdim]-ps1->pdir->esmooth[k2+kdim]; 29497 t[3*kdim+k1] = ps1->pdir->esmooth[k2+kn1*kdim]-ps1->pdir->esmooth[k2+(kn1+1)*kdim]; 29498 t[kdim4+k1] = t[k1] = ps1->pdir->esmooth[k2]-ps1->pdir->esmooth[k2+kn1*kdim]; 29499 29500 slen[0] += t[k1]*t[k1]; 29501 slen[1] += t[k1+kdim]*t[k1+kdim]; 29502 slen[2] += t[k1+2*kdim]*t[k1+2*kdim]; 29503 slen[3] += t[k1+3*kdim]*t[k1+3*kdim]; 29504 } 29505 slen[4] = slen[0] = sqrt(slen[0]); 29506 slen[1] = sqrt(slen[1]); 29507 slen[2] = sqrt(slen[2]); 29508 slen[3] = sqrt(slen[3]); 29509 29510 scorn[0] = s6ang(t,t+kdim,kdim); 29511 scorn[1] = s6ang(t+kdim,t+2*kdim,kdim); 29512 scorn[2] = s6ang(t+2*kdim,t+3*kdim,kdim); 29513 scorn[3] = s6ang(t+3*kdim,t,kdim); 29514 29515 29516 /* Here we makes the normales in each corner of the patch. 29517 We are using a cross product between two tangents. 29518 The normals is also normalized by deviding with its 29519 own length. */ 29520 29521 29522 for (k1=0, ki=0; k1<kdim4; k1+=kdim, ki++) 29523 { 29524 29525 for (tlen=DZERO,k2=0,k3=1,k4=2; k2 < kdim; k2++,k3++,k4++) 29526 { 29527 29528 if(k3 == kdim) k3 = 0; 29529 if(k4 == kdim) k4 = 0; 29530 tn[k1+k2] = t[k1+k3]*t[k1+kdim+k4]-t[k1+k4]*t[k1+kdim+k3]; 29531 29532 tlen += tn[k1+k2]*tn[k1+k2]; 29533 } 29534 29535 tlen = sqrt(tlen); 29536 if (slen[ki]>aepsge && slen[ki+1]>aepsge && 29537 scorn[ki] > ANGULAR_TOLERANCE) 29538 for (k2=0; k2 < kdim; k2++) tn[k1+k2] /= tlen; 29539 else 29540 for (k2=0; k2 < kdim; k2++) tn[k1+k2] = scen1[k2]; 29541 29542 } 29543 29544 for (k1=0; k1<kdim4; k1+=kdim) 29545 { 29546 t2 = scen2[0]*tn[k1]; 29547 for (k2=1,k3=k1+1;k2<kdim;k2++,k3++) 29548 t2 += scen2[k2]*tn[k3]; 29549 29550 if (aang > PIHALF) 29551 { 29552 if (t2 <= DZERO) continue; 29553 } 29554 else if (t2 >= DZERO) continue; 29555 29556 t1 = scen1[0]*tn[k1]; 29557 for (k2=1,k3=k1+1;k2<kdim;k2++,k3++) 29558 t1 += scen1[k2]*tn[k3]; 29559 29560 tang = t1/sqrt(t1*t1 + t2*t2); 29561 29562 if (tang >= DZERO) tang = min((double)1,tang); 29563 else tang = max((double)-1,tang); 29564 29565 tang = acos(tang); 29566 29567 tang1 = max(tang1,tang); 29568 } 29569 } 29570 29571 29572 /* The first basis vector. */ 29573 29574 scen1 = pc1 ->pdir-> ecoef; 29575 29576 /* We must orthonormalize the second basis vector. */ 29577 29578 scen2 = t + kdim; 29579 tlen = s6scpr(scen1,ps1->pdir->ecoef,kdim); 29580 for (k1=0; k1 < kdim; k1++) 29581 scen2[k1] = ps1->pdir->ecoef[k1] - tlen*scen1[k1]; 29582 tlen = s6length(scen2,kdim,&kstat); 29583 for (k1=0; k1 < kdim; k1++) 29584 scen2[k1] /= tlen; 29585 29586 /* Here we are treating each part in the control polygon separately.*/ 29587 29588 for (kn=pc1->in,k2=0,khor=0; khor < kn-1; khor++) 29589 { 29590 29591 /* Here we make an aproximative tangents to the curve 29592 using the control polygon. The tangents is also normalized 29593 by deviding with its own length. */ 29594 29595 for (tlen=DZERO,k1=0; k1 < kdim; k1++,k2++) 29596 { 29597 t[k1] = pc1->pdir->esmooth[k2+kdim] - pc1->pdir->esmooth[k2]; 29598 tlen += t[k1]*t[k1]; 29599 } 29600 29601 tlen = sqrt(tlen); 29602 29603 if (tlen > aepsge) 29604 for (k1=0; k1 < kdim; k1++) t[k1] /= tlen; 29605 else 29606 for (k1=0; k1 < kdim; k1++) t[k1] = scen1[k1]; 29607 29608 t2 = scen2[0]*t[0]; 29609 for (k1=1; k1<kdim; k1++) 29610 t2 += scen2[k1]*t[k1]; 29611 29612 if (aang > PIHALF) 29613 { 29614 if (t2 <= DZERO) continue; 29615 } 29616 else if (t2 >= DZERO) continue; 29617 29618 t1 = scen1[0]*t[0]; 29619 for (k1=1; k1<kdim; k1++) 29620 t1 += scen1[k1]*t[k1]; 29621 29622 tang = t1/sqrt(t1*t1 + t2*t2); 29623 29624 if (tang >= DZERO) tang = min((double)1,tang); 29625 else tang = max((double)-1,tang); 29626 29627 tang = acos(tang); 29628 29629 tang2 = max(tang2,tang); 29630 } 29631 29632 /* Performing a simple case check. */ 29633 29634 if (aang > PIHALF) aang = PI - aang; 29635 29636 if (tang1 + tang2 <= PIHALF - aang) 29637 *jstat = 1; /* A simpel case.*/ 29638 else 29639 *jstat = 0; 29640 29641 goto out; 29642 29643 29644 /* Error in space allacation. */ 29645 29646 err101: *jstat = -101; 29647 s6err("s1795",*jstat,kpos); 29648 goto out; 29649 29650 /* Free local used memory. */ 29651 29652 out: if (t != SISL_NULL) freearray(t); 29653 } 29654 29655 29656 //=========================================================================== 29657 void s1795(SISLSurf *ps1,SISLSurf *ps2,double aepsge,double aang,int *jstat) 29658 //=========================================================================== 29659 { 29660 int kpos = 0; /* Position of the error. */ 29661 int kstat; /* Local status variable. */ 29662 int ki; /* Counter. */ 29663 int kn1; /* Number of vertices of surface in 1. par. direction.*/ 29664 int kn2; /* Number of vertices of surface in 2. par. direction.*/ 29665 int kdim; /* Dimension of the space in which the objects lie. */ 29666 int kdim4; /* Help variable to contain 4*kdim. */ 29667 int kver,khor; /* The index to the vertice in the upper left corner 29668 to the patch to treat. */ 29669 int k1,k2,k3,k4; /* Control variables in loop. */ 29670 double *t=SISL_NULL; /* Allocating t[5][kdim]. Five tangents around the 29671 patch, the first and the last is the same. */ 29672 double *tn; /* Allocating tn[4][kdim]. Four normals in the corner 29673 of the patch. */ 29674 double *scen1; /* The orginal basis vector to the projection plan. */ 29675 double *scen2; /* The computed basis vector to the projection plan.*/ 29676 double tlen; /* The length of a vector. */ 29677 double tang; /* An angle between two vectors. */ 29678 double tang1=DZERO;/* An angle between two vectors. */ 29679 double tang2=DZERO;/* An angle between two vectors. */ 29680 double t1,t2; /* Help variables. */ 29681 double slen[5]; /* Distances between coefficients. */ 29682 double scorn[4]; /* Angle between derivatives in corner of patch. */ 29683 29684 29685 /* Initialate dimentions. */ 29686 29687 kdim = ps1 -> idim; 29688 kdim4 = 4*kdim; 29689 29690 29691 /* Allocate local used matrices, t[5][kdim] and tn[4][kdim]. */ 29692 29693 if ((t = newarray(10*kdim,double)) == SISL_NULL) goto err101; 29694 29695 tn = t + 5*kdim; 29696 29697 29698 if (aang > PIHALF) 29699 aang = PI - aang; 29700 29701 scen1 = ps1->pdir->ecoef; 29702 scen2 = tn + 4*kdim; 29703 tlen = s6scpr(scen1,ps2->pdir->ecoef,kdim); 29704 for (k1=0; k1 < kdim; k1++) 29705 scen2[k1] = ps2->pdir->ecoef[k1] - tlen*scen1[k1]; 29706 tlen = s6length(scen2,kdim,&kstat); 29707 for (k1=0; k1 < kdim; k1++) 29708 scen2[k1] /= tlen; 29709 29710 kn1 = ps1 -> in1; 29711 kn2 = ps1 -> in2; 29712 29713 /* Here we are treating each patch in the control polygon separately.*/ 29714 29715 for (kver=0; kver < (kn2-1); kver++) 29716 for (khor=0; khor < (kn1-1); khor++) 29717 { 29718 slen[0] = slen[1] = slen[2] = slen[3] = DZERO; 29719 scorn[0] = scorn[1] = scorn[2] = scorn[3] = DZERO; 29720 29721 /* Here we make the tangents in each corner of the patch, 29722 and in direction with the clock. The first and the last 29723 vector contains both the first tangent. */ 29724 29725 k2 = (kver*kn1+khor)*kdim; 29726 29727 for (k1=0; k1 < kdim; k1++,k2++) 29728 { 29729 t[kdim+k1] = ps1->pdir->esmooth[k2+kdim] - ps1->pdir->esmooth[k2]; 29730 t[2*kdim+k1] = ps1->pdir->esmooth[k2+(kn1+1)*kdim]-ps1->pdir->esmooth[k2+kdim]; 29731 t[3*kdim+k1] = ps1->pdir->esmooth[k2+kn1*kdim]-ps1->pdir->esmooth[k2+(kn1+1)*kdim]; 29732 t[kdim4+k1] = t[k1] = ps1->pdir->esmooth[k2]-ps1->pdir->esmooth[k2+kn1*kdim]; 29733 29734 slen[0] += t[k1]*t[k1]; 29735 slen[1] += t[k1+kdim]*t[k1+kdim]; 29736 slen[2] += t[k1+2*kdim]*t[k1+2*kdim]; 29737 slen[3] += t[k1+3*kdim]*t[k1+3*kdim]; 29738 } 29739 slen[4] = slen[0] = sqrt(slen[0]); 29740 slen[1] = sqrt(slen[1]); 29741 slen[2] = sqrt(slen[2]); 29742 slen[3] = sqrt(slen[3]); 29743 29744 scorn[0] = s6ang(t,t+kdim,kdim); 29745 scorn[1] = s6ang(t+kdim,t+2*kdim,kdim); 29746 scorn[2] = s6ang(t+2*kdim,t+3*kdim,kdim); 29747 scorn[3] = s6ang(t+3*kdim,t,kdim); 29748 29749 29750 /* Here we makes the normales in each corner of the patch. 29751 We are using a cross product between two tangents. 29752 The normals is also normalized by deviding with its 29753 own length. */ 29754 29755 29756 for (k1=0, ki=0; k1<kdim4; k1+=kdim, ki++) 29757 { 29758 29759 for (tlen=DZERO,k2=0,k3=1,k4=2; k2 < kdim; k2++,k3++,k4++) 29760 { 29761 29762 if(k3 == kdim) k3 = 0; 29763 if(k4 == kdim) k4 = 0; 29764 tn[k1+k2] = t[k1+k3]*t[k1+kdim+k4]-t[k1+k4]*t[k1+kdim+k3]; 29765 29766 tlen += tn[k1+k2]*tn[k1+k2]; 29767 } 29768 29769 tlen = sqrt(tlen); 29770 if (slen[ki]>aepsge && slen[ki+1]>aepsge && 29771 scorn[ki] > ANGULAR_TOLERANCE) 29772 for (k2=0; k2 < kdim; k2++) tn[k1+k2] /= tlen; 29773 else 29774 for (k2=0; k2 < kdim; k2++) tn[k1+k2] = scen1[k2]; 29775 29776 } 29777 29778 for (k1=0; k1<kdim4; k1+=kdim) 29779 { 29780 t2 = scen2[0]*tn[k1]; 29781 for (k2=1,k3=k1+1;k2<kdim;k2++,k3++) 29782 t2 += scen2[k2]*tn[k3]; 29783 29784 if (t2 <= DZERO) continue; 29785 29786 t1 = scen1[0]*tn[k1]; 29787 for (k2=1,k3=k1+1;k2<kdim;k2++,k3++) 29788 t1 += scen1[k2]*tn[k3]; 29789 29790 tang = t1/sqrt(t1*t1 + t2*t2); 29791 29792 if (tang >= DZERO) tang = min((double)1,tang); 29793 else tang = max((double)-1,tang); 29794 29795 tang = acos(tang); 29796 29797 tang1 = max(tang1,tang); 29798 } 29799 } 29800 29801 scen1 = ps2 ->pdir-> ecoef; 29802 tlen = s6scpr(scen1,ps1->pdir->ecoef,kdim); 29803 for (k1=0; k1 < kdim; k1++) 29804 scen2[k1] = ps1->pdir->ecoef[k1] - tlen*scen1[k1]; 29805 tlen = s6length(scen2,kdim,&kstat); 29806 for (k1=0; k1 < kdim; k1++) 29807 scen2[k1] /= tlen; 29808 29809 kn1 = ps2 -> in1; 29810 kn2 = ps2 -> in2; 29811 29812 /* Here we are treating each patch in the control polygon separately.*/ 29813 29814 for (kver=0; kver < (kn2-1); kver++) 29815 for (khor=0; khor < (kn1-1); khor++) 29816 { 29817 slen[0] = slen[1] = slen[2] = slen[3] = DZERO; 29818 scorn[0] = scorn[1] = scorn[2] = scorn[3] = DZERO; 29819 29820 /* Here we make the tangents in each corner of the patch, 29821 and in direction with the clock. The first and the last 29822 vector contains both the first tangent. */ 29823 29824 k2 = (kver*kn1+khor)*kdim; 29825 29826 for (k1=0; k1 < kdim; k1++,k2++) 29827 { 29828 t[kdim+k1] = ps2->pdir->esmooth[k2+kdim] - ps2->pdir->esmooth[k2]; 29829 t[2*kdim+k1] = ps2->pdir->esmooth[k2+(kn1+1)*kdim]-ps2->pdir->esmooth[k2+kdim]; 29830 t[3*kdim+k1] = ps2->pdir->esmooth[k2+kn1*kdim]-ps2->pdir->esmooth[k2+(kn1+1)*kdim]; 29831 t[kdim4+k1] = t[k1] = ps2->pdir->esmooth[k2]-ps2->pdir->esmooth[k2+kn1*kdim]; 29832 29833 slen[0] += t[k1]*t[k1]; 29834 slen[1] += t[k1+kdim]*t[k1+kdim]; 29835 slen[2] += t[k1+2*kdim]*t[k1+2*kdim]; 29836 slen[3] += t[k1+3*kdim]*t[k1+3*kdim]; 29837 } 29838 slen[4] = slen[0] = sqrt(slen[0]); 29839 slen[1] = sqrt(slen[1]); 29840 slen[2] = sqrt(slen[2]); 29841 slen[3] = sqrt(slen[3]); 29842 29843 scorn[0] = s6ang(t,t+kdim,kdim); 29844 scorn[1] = s6ang(t+kdim,t+2*kdim,kdim); 29845 scorn[2] = s6ang(t+2*kdim,t+3*kdim,kdim); 29846 scorn[3] = s6ang(t+3*kdim,t,kdim); 29847 29848 29849 /* Here we makes the normales in each corner of the patch. 29850 We are using a cross product between two tangents. 29851 The normals is also normalized by deviding with its 29852 own length. */ 29853 29854 29855 for (k1=0, ki=0; k1<kdim4; k1+=kdim, ki++) 29856 { 29857 29858 for (tlen=DZERO,k2=0,k3=1,k4=2; k2 < kdim; k2++,k3++,k4++) 29859 { 29860 29861 if(k3 == kdim) k3 = 0; 29862 if(k4 == kdim) k4 = 0; 29863 tn[k1+k2] = t[k1+k3]*t[k1+kdim+k4]-t[k1+k4]*t[k1+kdim+k3]; 29864 29865 tlen += tn[k1+k2]*tn[k1+k2]; 29866 } 29867 29868 tlen = sqrt(tlen); 29869 if (slen[ki]>aepsge && slen[ki+1]>aepsge && 29870 scorn[ki] > ANGULAR_TOLERANCE) 29871 for (k2=0; k2 < kdim; k2++) tn[k1+k2] /= tlen; 29872 else 29873 for (k2=0; k2 < kdim; k2++) tn[k1+k2] = scen1[k2]; 29874 29875 } 29876 29877 29878 for (k1=0; k1<kdim4; k1+=kdim) 29879 { 29880 t2 = scen2[0]*tn[k1]; 29881 for (k2=1,k3=k1+1;k2<kdim;k2++,k3++) 29882 t2 += scen2[k2]*tn[k3]; 29883 29884 if (t2 <= DZERO) continue; 29885 29886 t1 = scen1[0]*tn[k1]; 29887 for (k2=1,k3=k1+1;k2<kdim;k2++,k3++) 29888 t1 += scen1[k2]*tn[k3]; 29889 29890 tang = t1/sqrt(t1*t1+t2*t2); 29891 29892 if (tang >= DZERO) tang = min((double)1,tang); 29893 else tang = max((double)-1,tang); 29894 29895 tang = acos(tang); 29896 29897 tang2 = max(tang2,tang); 29898 } 29899 } 29900 29901 29902 /* Performing a simple case check. */ 29903 29904 if (tang1 + tang2 <= aang) 29905 *jstat = 1; /* A simpel case.*/ 29906 else 29907 *jstat = 0; 29908 29909 goto out; 29910 29911 29912 /* Error in space allacation. */ 29913 29914 err101: *jstat = -101; 29915 s6err("s1795",*jstat,kpos); 29916 goto out; 29917 29918 29919 29920 /* Free local used memory. */ 29921 29922 out: if (t != SISL_NULL) freearray(t); 29923 } 29924 29925 29926 //=========================================================================== 29927 void s1796(SISLCurve *pc1,SISLCurve *pc2,double aepsge,double aang,int *jstat) 29928 //=========================================================================== 29929 { 29930 int kstat = 0; /* Local status variable. */ 29931 int kpos = 0; /* Position of the error. */ 29932 int turned = 0; /* Use as mark if dir of curve2 is turned. */ 29933 int kn; /* Number of vertices of curve. */ 29934 int kdim; /* Dimension of the space in which the objects lie. */ 29935 int kin; /* The index to the vertice to treat. */ 29936 int k1,k2; /* Control variables in loop. */ 29937 double *t=SISL_NULL; /* Tangent at each coeficient. */ 29938 double tlen; /* The length of a vector. */ 29939 double *scen1; /* The orginal basis vector to the projection plan. */ 29940 double *scen2; /* The computed basis vector to the projection plan.*/ 29941 double tang; /* An angle between two vectors. */ 29942 double tang1=DZERO;/* An angle between two vectors. */ 29943 double tang2=DZERO;/* An angle between two vectors. */ 29944 double t1,t2; /* Help variables. */ 29945 29946 29947 /* Initialate space dimentions. */ 29948 29949 kdim = pc1 -> idim; 29950 29951 29952 /* Allocate local used array. */ 29953 29954 if ((t = newarray(2*kdim,double)) == SISL_NULL) goto err101; 29955 29956 /* We have to turn the direction into the smallest angel. */ 29957 29958 if (aang > PIHALF) 29959 { 29960 aang = PI - aang; 29961 turned = 1; 29962 } 29963 29964 /* The first basis vector. */ 29965 29966 scen1 = pc1->pdir->ecoef; 29967 29968 /* We must orthonormalize the second basis vector. */ 29969 29970 scen2 = t + kdim; 29971 tlen = s6scpr(scen1,pc2->pdir->ecoef,kdim); 29972 for (k1=0; k1 < kdim; k1++) 29973 scen2[k1] = pc2->pdir->ecoef[k1] - tlen*scen1[k1]; 29974 tlen = s6length(scen2,kdim,&kstat); 29975 for (k1=0; k1 < kdim; k1++) 29976 scen2[k1] /= tlen; 29977 29978 if (turned) 29979 for (k1=0; k1 < kdim; k1++) scen2[k1] = -scen2[k1]; 29980 29981 29982 /* Here we are treating each patch in the control polygon separately.*/ 29983 29984 for (kn=pc1->in,k2=0,kin=0; kin < kn-1; kin++) 29985 { 29986 29987 /* Here we make an aproximative tangents to the curve 29988 using the control polygon. The tangents are also normalized 29989 by deviding with its own length. */ 29990 29991 for (tlen=DZERO,k1=0; k1 < kdim; k1++,k2++) 29992 { 29993 t[k1] = pc1->pdir->esmooth[k2+kdim] - pc1->pdir->esmooth[k2]; 29994 tlen += t[k1]*t[k1]; 29995 } 29996 29997 tlen = sqrt(tlen); 29998 29999 if (tlen > aepsge) 30000 for (k1=0; k1 < kdim; k1++) t[k1] /= tlen; 30001 else 30002 for (k1=0; k1 < kdim; k1++) t[k1] = scen1[k1]; 30003 30004 t2 = scen2[0]*t[0]; 30005 for (k1=1; k1<kdim; k1++) 30006 t2 += scen2[k1]*t[k1]; 30007 30008 if (t2 <= DZERO) continue; 30009 30010 t1 = scen1[0]*t[0]; 30011 for (k1=1; k1<kdim; k1++) 30012 t1 += scen1[k1]*t[k1]; 30013 30014 tang = t1/sqrt(t1*t1 + t2*t2); 30015 30016 if (tang >= DZERO) tang = min((double)1,tang); 30017 else tang = max((double)-1,tang); 30018 30019 tang = acos(tang); 30020 30021 tang1 = max(tang1,tang); 30022 } 30023 30024 /* The first basis vector. */ 30025 30026 scen1 = pc2->pdir->ecoef; 30027 30028 /* We must orthonormalize the second basis vector. */ 30029 30030 scen2 = t + kdim; 30031 tlen = s6scpr(scen1,pc1->pdir->ecoef,kdim); 30032 for (k1=0; k1 < kdim; k1++) 30033 scen2[k1] = pc1->pdir->ecoef[k1] - tlen*scen1[k1]; 30034 tlen = s6length(scen2,kdim,&kstat); 30035 for (k1=0; k1 < kdim; k1++) 30036 scen2[k1] /= tlen; 30037 30038 if (turned) 30039 for (k1=0; k1 < kdim; k1++) scen2[k1] = -scen2[k1]; 30040 30041 /* Here we are treating each patch in the control polygon separately.*/ 30042 30043 for (kn =pc2->in,k2=0,kin=0; kin < kn-1; kin++) 30044 { 30045 30046 /* Here we make an aproximative tangents to the curve 30047 using the control polygon. The tangents are also normalized 30048 by deviding with its own length. */ 30049 30050 for (tlen=DZERO,k1=0; k1 < kdim; k1++,k2++) 30051 { 30052 t[k1] = pc2->pdir->esmooth[k2+kdim] - pc2->pdir->esmooth[k2]; 30053 tlen += t[k1]*t[k1]; 30054 } 30055 30056 tlen = sqrt(tlen); 30057 30058 if (tlen > aepsge) 30059 for (k1=0; k1 < kdim; k1++) t[k1] /= tlen; 30060 else 30061 for (k1=0; k1 < kdim; k1++) t[k1] = scen1[k1]; 30062 30063 30064 t2 = scen2[0]*t[0]; 30065 for (k1=1; k1<kdim;k1++) 30066 t2 += scen2[k1]*t[k1]; 30067 30068 if (t2 <= DZERO) continue; 30069 30070 t1 = scen1[0]*t[0]; 30071 for (k1=1; k1<kdim; k1++) 30072 t1 += scen1[k1]*t[k1]; 30073 30074 tang = t1/sqrt(t1*t1 + t2*t2); 30075 30076 if (tang >= DZERO) tang = min((double)1,tang); 30077 else tang = max((double)-1,tang); 30078 30079 tang = acos(tang); 30080 30081 tang2 = max(tang2,tang); 30082 } 30083 30084 30085 30086 /* Performing a simple case check. */ 30087 30088 if (tang1 + tang2 <= aang) 30089 *jstat = 1; /* A simpel case.*/ 30090 else 30091 *jstat = 0; 30092 30093 goto out; 30094 30095 30096 /* Error in space allocation. */ 30097 30098 err101: *jstat = -101; 30099 s6err("s1796",*jstat,kpos); 30100 goto out; 30101 30102 30103 /* Free local used memory. */ 30104 30105 out: if (t != SISL_NULL) freearray(t); 30106 30107 } 30108 30109 30110 //=========================================================================== 30111 double s6dplane(double eq1[],double eq2[],double eq3[],double epoint[], 30112 int idim,int *jstat) 30113 //=========================================================================== 30114 { 30115 int kstat = 0; /* Local status varaible. */ 30116 double tdist; /* Distance between point and line. */ 30117 double snorm[3]; /* Normal vector to the plane. */ 30118 double sdiff1[3]; /* Difference vector between points in the plane. */ 30119 double sdiff2[3]; /* Difference vector between points in the plane. */ 30120 double sdiff3[3]; /* Difference vector. */ 30121 30122 /* Test dimension. */ 30123 30124 if (idim != 3) goto err104; 30125 30126 /* Compute difference vectors. */ 30127 30128 s6diff(eq2,eq1,idim,sdiff1); 30129 s6diff(eq3,eq1,idim,sdiff2); 30130 s6diff(epoint,eq1,idim,sdiff3); 30131 30132 /* Compute normalized plane normal. */ 30133 30134 s6crss(sdiff1,sdiff2,snorm); 30135 (void)s6norm(snorm,idim,snorm,&kstat); 30136 30137 /* Compute distance to closest point in plane. */ 30138 30139 if (kstat) 30140 tdist = fabs(s6scpr(sdiff3,snorm,idim)); 30141 else 30142 tdist = s6dist(eq1,epoint,idim); /* Normal of zero length. */ 30143 30144 /* Set status. */ 30145 30146 *jstat = 0; 30147 goto out; 30148 30149 /* Error in input, dimension not equal to 3. */ 30150 30151 err104 : *jstat = -104; 30152 goto out; 30153 30154 out : 30155 return tdist; 30156 } 30157 30158 30159 //=========================================================================== 30160 double s6dline(double estart[],double eend[],double epoint[], 30161 int idim,int *jstat) 30162 //=========================================================================== 30163 { 30164 int kstat = 0; /* Local status varaible. */ 30165 int ki; /* Counter. */ 30166 double tpar; /* Parameter of closest point. */ 30167 double tdist; /* Distance between point and line. */ 30168 double t1; /* Scalar product. */ 30169 double *sline = SISL_NULL; /* Line vector. */ 30170 double *sdiff = SISL_NULL; /* Difference vector. */ 30171 30172 /* Allocate scratch for local vectors. */ 30173 30174 if ((sline = newarray(idim,DOUBLE)) == SISL_NULL) goto err101; 30175 if ((sdiff = newarray(idim,DOUBLE)) == SISL_NULL) goto err101; 30176 30177 /* Compute help vectors. */ 30178 30179 s6diff(eend,estart,idim,sline); 30180 s6diff(epoint,estart,idim,sdiff); 30181 30182 /* Compute parameter of closest point. */ 30183 30184 t1 = s6scpr(sline,sline,idim); 30185 if (t1 <= REL_COMP_RES) 30186 { 30187 /* Compute distance between point and first endpoint of line. */ 30188 30189 tdist = s6dist(estart,epoint,idim); 30190 30191 /* Set a warning. */ 30192 30193 *jstat = 2; 30194 goto out; 30195 } 30196 30197 tpar = s6scpr(sline,sdiff,idim)/t1; 30198 30199 /* Compute vector between input point and closest point on 30200 line. */ 30201 30202 for (ki=0; ki<idim; ki++) 30203 sdiff[ki] = estart[ki] + tpar*sline[ki] - epoint[ki]; 30204 30205 /* Compute length of vector. */ 30206 30207 tdist = s6length(sdiff,idim,&kstat); 30208 30209 /* Set status. */ 30210 30211 *jstat = (tpar < 0 || tpar > 1) ? 1 : 0; 30212 goto out; 30213 30214 /* Error in scratch allocation. */ 30215 30216 err101 : *jstat = -101; 30217 goto out; 30218 30219 out : 30220 /* Free space occupied by local arrays. */ 30221 30222 if (sline != SISL_NULL) freearray(sline); 30223 if (sdiff != SISL_NULL) freearray(sdiff); 30224 30225 return tdist; 30226 } 30227 30228 30229 //=========================================================================== 30230 void s1990_s9smooth(double ecoef1[],int in1,int in2,int idim, 30231 double aepsge,double ecoef2[],int *jstat) 30232 //=========================================================================== 30233 { 30234 int kstat = 0; /* Local status variable. */ 30235 int kn = MIN(in1/2,in2/2)+1; /* Maximum numbers of 30236 coefficients to smooth. */ 30237 int ki,kj,kh,kl; /* Counters. */ 30238 int kc; /* Index of current corner. */ 30239 int k1; /* Sign of change in 1. par dir */ 30240 int k2; /* Sign of change in 2. par dir */ 30241 int lcorn[4]; /* Indexes of corners. */ 30242 int lsgn1[4]; /* Sign of changes in 1. par dir */ 30243 int lsgn2[4]; /* Sign of changes in 2. par dir */ 30244 double tdist; /* Distance to closest point in plane. */ 30245 30246 /* Set contents of arrays. */ 30247 30248 lcorn[0] = 0; 30249 lcorn[1] = (in1-1)*idim; 30250 lcorn[2] = (in1*in2-1)*idim; 30251 lcorn[3] = in1*(in2-1)*idim; 30252 30253 lsgn1[0] = 1; 30254 lsgn1[1] = -1; 30255 lsgn1[2] = -1; 30256 lsgn1[3] = 1; 30257 30258 lsgn2[0] = 1; 30259 lsgn2[1] = 1; 30260 lsgn2[2] = -1; 30261 lsgn2[3] = -1; 30262 30263 /* Copy coefficients to output array. */ 30264 30265 memcopy(ecoef2,ecoef1,in1*in2*idim,DOUBLE); 30266 30267 /* For each corner, try to smooth the coefficients in the 30268 neighbourhood of the corner. */ 30269 30270 for (ki=0; ki<4; ki++) 30271 { 30272 kc = lcorn[ki]; /* Index of current corner. */ 30273 k1 = lsgn1[ki]; /* Sign change in 1. par dir. */ 30274 k2 = lsgn2[ki]; /* Sign change in 2. par dir. */ 30275 30276 /* Try to smooth coefficients on center line. */ 30277 30278 for (kj=2; kj<kn; kj++) 30279 { 30280 if (s6dist(ecoef2+kc,ecoef2+kc+(k2*kj*in1+k1*kj)*idim, 30281 idim) < aepsge) continue; 30282 30283 for (kh=1; kh<kj; kh++) 30284 { 30285 tdist = s6dline(ecoef2+kc,ecoef2+kc+(k2*kj*in1+k1*kj)*idim, 30286 ecoef2+kc+(k2*kh*in1+k1*kh)*idim,idim,&kstat); 30287 if (kstat < 0) goto error; 30288 if (kstat || tdist >= aepsge) break; 30289 } 30290 if (kh < kj) break; 30291 } 30292 30293 /* Perform smoothing. */ 30294 30295 kj--; 30296 for (kh=1; kh<kj; kh++) 30297 memcopy(ecoef2+kc+(k2*kh*in1+k1*kh)*idim,ecoef2+kc, 30298 idim,DOUBLE); 30299 30300 /* Try to smooth coefficients on lower triangle. */ 30301 30302 for (kj=2; kj<kn; kj++) 30303 { 30304 for (kh=1; kh<kj; kh++) 30305 { 30306 for (kl=0; kl<kh; kl++) 30307 { 30308 tdist = s6dplane(ecoef2+kc,ecoef2+kc+k1*kj*idim, 30309 ecoef2+kc+(k2*kj*in1+k1*kj)*idim, 30310 ecoef2+kc+(k2*kl*in1+k1*kh)*idim, 30311 idim,&kstat); 30312 if (tdist >= aepsge) break; 30313 } 30314 if (tdist >= aepsge) break; 30315 } 30316 if (kh < kj) break; 30317 } 30318 30319 /* Perform smoothing. */ 30320 30321 kj--; 30322 for (kh=1; kh<kj; kh++) 30323 for (kl=0; kl<kh; kl++) 30324 memcopy(ecoef2+kc+(k2*kl*in1+k1*kh)*idim,ecoef2+kc, 30325 idim,DOUBLE); 30326 30327 /* Try to smooth coefficients on upper triangle. */ 30328 30329 for (kj=2; kj<kn; kj++) 30330 { 30331 for (kh=0; kh<kj; kh++) 30332 { 30333 for (kl=kh+1; kl<kj; kl++) 30334 { 30335 tdist = s6dplane(ecoef2+kc,ecoef2+kc+k2*kj*in1*idim, 30336 ecoef2+kc+(k2*kj*in1+k1*kj)*idim, 30337 ecoef2+kc+(k2*kl*in1+k1*kh)*idim, 30338 idim,&kstat); 30339 if (tdist >= aepsge) break; 30340 } 30341 if (tdist >= aepsge) break; 30342 } 30343 if (kh < kj) break; 30344 } 30345 30346 /* Perform smoothing. */ 30347 30348 kj--; 30349 for (kh=0; kh<kj; kh++) 30350 for (kl=kh+1; kl<kj; kl++) 30351 memcopy(ecoef2+kc+(k2*kl*in1+k1*kh)*idim,ecoef2+kc, 30352 idim,DOUBLE); 30353 } 30354 30355 /* Smoothing performed. */ 30356 *jstat = 0; 30357 goto out; 30358 30359 /* Error in lower level routine. */ 30360 30361 error : *jstat = kstat; 30362 goto out; 30363 30364 out : 30365 30366 return; 30367 } 30368 30369 30370 //=========================================================================== 30371 void s1990_s9edg(double et[],double etan[],double esen[],double aepsge, 30372 double *cang,int idim,int *jstat) 30373 //=========================================================================== 30374 { 30375 int ki; 30376 double tlen; 30377 double tang; 30378 double t1,t2; 30379 30380 30381 /* Normalizing the tangent. */ 30382 30383 for (tlen = DZERO,ki=0; ki < idim; ki++) 30384 { 30385 etan[ki] = et[ki]; 30386 tlen += etan[ki]*etan[ki]; 30387 } 30388 tlen = sqrt(tlen); 30389 30390 if (tlen > aepsge) 30391 for (ki=0; ki < idim; ki++) etan[ki] /= tlen; 30392 else 30393 { 30394 *jstat = 0; 30395 goto out; 30396 } 30397 30398 30399 /* Computing the angle beetween the senter of the cone 30400 and the tangent. */ 30401 30402 for (tang=DZERO,ki=0;ki<idim;ki++) 30403 tang += esen[ki]*etan[ki]; 30404 30405 if (tang >= DZERO) tang = min((double)1.0,tang); 30406 else tang = max((double)-1.0,tang); 30407 30408 tang = acos(tang); 30409 30410 30411 if (tang + *cang >= PI) 30412 { 30413 /* The angle is to great, give a meesage 30414 to subdivied and exit this function. */ 30415 30416 *jstat = 1; 30417 goto out; 30418 } 30419 else if (tang > *cang) 30420 { 30421 /* The tangent is not inside the cone, and we 30422 have to compute a new cone. */ 30423 30424 /* Computing the center coordinates.*/ 30425 30426 t1 = (tang - *cang)/((double)2*tang); 30427 t2 = (double)1 - t1; 30428 30429 for (tlen=DZERO,ki=0; ki<idim; ki++) 30430 { 30431 esen[ki] = esen[ki]*t2 + etan[ki]*t1; 30432 tlen += esen[ki]*esen[ki]; 30433 } 30434 tlen = sqrt(tlen); 30435 30436 if (tlen > DZERO) 30437 for (ki=0; ki < idim; ki++) esen[ki] /= tlen; 30438 else 30439 { 30440 /* Vi have to be aware of colapsed polygon. */ 30441 30442 *jstat = 1; 30443 goto out; 30444 } 30445 30446 /* Computing the angle of the cone. */ 30447 30448 *cang = (tang + *cang)/(double)2; 30449 } 30450 30451 30452 if (*cang >= SIMPLECASE) 30453 { 30454 /* The angle is to large, give a meesage 30455 to subdivied and exit this function. */ 30456 30457 *jstat = 1; 30458 goto out; 30459 } 30460 30461 30462 *jstat = 0; 30463 30464 out: ; 30465 } 30466 30467 30468 30469 //=========================================================================== 30470 void s1990(SISLSurf *ps,double aepsge,int *jstat) 30471 //=========================================================================== 30472 { 30473 int kpos = 0; /* Position of the error. */ 30474 int kstat = 0; /* Local status variable. */ 30475 int kfirst = 1; /* Flag to mark if the first patch is treating. */ 30476 int kcount; /* Counts number of vanishing normals. */ 30477 int kn1; /* Number of vertices of surface in 1. par. direction.*/ 30478 int kn2; /* Number of vertices of surface in 2. par. direction.*/ 30479 int kdim; /* Dimension of the space in which the objects lie. */ 30480 int kdim4; /* Help variable to contain 4*kdim. */ 30481 int kver,khor; /* The index to the vertice in the upper left corner 30482 to the patch to treat. */ 30483 int k1,k2,k3,k4; /* Control variables in loop. */ 30484 int ki; /* Control variable in loop. */ 30485 int lcone[4]; /* Flag telling if the cone has been generated. */ 30486 double *t=SISL_NULL; /* Allocating t[5][kdim]. Five tangents around the 30487 patch, the first and the last is the same. */ 30488 double *tn; /* Allocating tn[4][kdim]. Four normals in the corner 30489 of the patch. */ 30490 double *tsen; /* Allocating tsen[4][kdim] for senter in edge cones. */ 30491 double *ttan; /* Allocating ttan[kdim] for tangent on edges. */ 30492 double tmax,tmin; /* Maximum and minimum coordinates to the narmals in 30493 the first patch. */ 30494 double tlen; /* The length of a vector. */ 30495 double tnlen; /* The length of a normal vector. */ 30496 double tang; /* An angle between two vectors. */ 30497 double t1,t2; /* Help variables. */ 30498 double sang[4]; /* Angel to the cones to edges. */ 30499 double svec1[3]; /* Vectors used to determin degeneration. */ 30500 double svec2[3]; /* Vectors used to determin degeneration. */ 30501 double *scoef; /* Pointer to smoothed coefficient vector. */ 30502 double slen[5]; /* Distances between coefficients. */ 30503 double scorn[4]; /* Angle between derivatives in corner of patch. */ 30504 30505 /* Initiate output status */ 30506 30507 *jstat = 0; 30508 30509 /* Test if the surfaces already have been treated. */ 30510 30511 if (ps->pdir != SISL_NULL) goto out; 30512 30513 /* Initialate dimentions. */ 30514 30515 kdim = ps -> idim; 30516 kn1 = ps -> in1; 30517 kn2 = ps -> in2; 30518 kdim4 = 4*kdim; 30519 30520 lcone[0] = 1; 30521 lcone[1] = 1; 30522 lcone[2] = 1; 30523 lcone[3] = 1; 30524 30525 /*Make a new direction cone. */ 30526 30527 if ((ps->pdir = newdir(kdim)) == SISL_NULL) goto err101; 30528 30529 ps->pdir->aang = DZERO; 30530 for (k1=0;k1<kdim;k1++) ps->pdir->ecoef[k1] = DZERO; 30531 30532 /* Allocate scratch for smoothed coefficients. */ 30533 30534 if ((ps->pdir->esmooth = newarray(kn1*kn2*kdim,DOUBLE)) == SISL_NULL) goto err101; 30535 scoef = ps->pdir->esmooth; 30536 30537 /* Compute coefficients of smoothed curve. */ 30538 30539 /* s1990_s9smooth(ps->ecoef,kn1,kn2,kdim,aepsge,scoef,&kstat); 30540 if (kstat < 0) goto error; */ 30541 30542 memcopy(scoef,ps->ecoef,kn1*kn2*kdim,DOUBLE); 30543 30544 /* Allocate local used matrices, t[5][kdim] and tn[4][kdim]. */ 30545 30546 if ((t = newarray(14*kdim,double)) == SISL_NULL) goto err101; 30547 tn = t + 5*kdim; 30548 tsen = tn + 4*kdim; 30549 ttan = tsen + 4*kdim; 30550 30551 /* Here we are treating each patch in the control polygon separately.*/ 30552 30553 for (kver=0; kver < (kn2-1); kver++) 30554 for (khor=0; khor < (kn1-1); khor++) 30555 { 30556 slen[0] = slen[1] = slen[2] = slen[3] = DZERO; 30557 scorn[0] = scorn[1] = scorn[2] = scorn[3] = DZERO; 30558 30559 /* Here we make the tangents in each corner of the patch, 30560 and in direction with the clock. The first and the last 30561 vector contains both the first tangent. */ 30562 30563 k2 = (kver*kn1+khor)*kdim; 30564 30565 for (k1=0; k1 < kdim; k1++,k2++) 30566 { 30567 t[kdim+k1] = scoef[k2+kdim] - scoef[k2]; 30568 t[2*kdim+k1] = scoef[k2+(kn1+1)*kdim]-scoef[k2+kdim]; 30569 t[3*kdim+k1] = scoef[k2+kn1*kdim]-scoef[k2+(kn1+1)*kdim]; 30570 t[kdim4+k1] = t[k1] = scoef[k2]-scoef[k2+kn1*kdim]; 30571 30572 slen[0] += t[k1]*t[k1]; 30573 slen[1] += t[k1+kdim]*t[k1+kdim]; 30574 slen[2] += t[k1+2*kdim]*t[k1+2*kdim]; 30575 slen[3] += t[k1+3*kdim]*t[k1+3*kdim]; 30576 } 30577 slen[4] = slen[0] = sqrt(slen[0]); 30578 slen[1] = sqrt(slen[1]); 30579 slen[2] = sqrt(slen[2]); 30580 slen[3] = sqrt(slen[3]); 30581 30582 scorn[0] = s6ang(t,t+kdim,kdim); 30583 scorn[1] = s6ang(t+kdim,t+2*kdim,kdim); 30584 scorn[2] = s6ang(t+2*kdim,t+3*kdim,kdim); 30585 scorn[3] = s6ang(t+3*kdim,t,kdim); 30586 30587 /* If problems on edges is found we jump to the surface. */ 30588 30589 if (ps->pdir->igtpi > 0) goto next; 30590 30591 /* Computing cones of edges in ends of parameter two. */ 30592 30593 if (kver == 0) 30594 { 30595 if (lcone[0]) 30596 { 30597 /* First time to generate cone. */ 30598 30599 memcopy(tsen,t+kdim,kdim,DOUBLE); 30600 tlen = slen[1]; 30601 30602 if (tlen > aepsge) 30603 { 30604 for (k1=0; k1 < kdim; k1++) tsen[k1] /= tlen; 30605 lcone[0] = 0; 30606 sang[0] = (double)0; 30607 } 30608 } 30609 else 30610 { 30611 /* Modify existing cone. */ 30612 s1990_s9edg(t+(kdim),ttan,tsen,aepsge,sang,kdim,&kstat); 30613 30614 if (kstat) ps->pdir->igtpi = 10; 30615 } 30616 } 30617 if (kver == kn2-2) 30618 { 30619 if (lcone[1]) 30620 { 30621 /* First time to generate cone. */ 30622 30623 memcopy(tsen+kdim,t+3*kdim,kdim,DOUBLE); 30624 tlen = slen[3]; 30625 30626 if (tlen > aepsge) 30627 { 30628 for (k1=0; k1 < kdim; k1++) tsen[kdim+k1] /= tlen; 30629 lcone[1] = 0; 30630 sang[1] = (double)0; 30631 } 30632 } 30633 else 30634 { 30635 s1990_s9edg(t+(3*kdim),ttan,tsen+kdim,aepsge,sang+1,kdim,&kstat); 30636 if (kstat) ps->pdir->igtpi = 10; 30637 } 30638 } 30639 30640 /* Computing cones of edges in ends of parameter one. */ 30641 30642 if (khor == 0) 30643 { 30644 if (lcone[2]) 30645 /* First time to generate cone. */ 30646 { 30647 memcopy(tsen+2*kdim,t,kdim,DOUBLE); 30648 tlen = slen[0]; 30649 30650 if (tlen > aepsge) 30651 { 30652 for (k1=0; k1 < kdim; k1++) tsen[2*kdim+k1] /= tlen; 30653 lcone[2] = 0; 30654 sang[2] = (double)0; 30655 } 30656 } 30657 else 30658 { 30659 s1990_s9edg(t,ttan,tsen+(2*kdim),aepsge,sang+2,kdim,&kstat); 30660 if (kstat) ps->pdir->igtpi = 10; 30661 } 30662 } 30663 if (khor == kn1-2) 30664 { 30665 if (lcone[3]) 30666 { 30667 memcopy(tsen+3*kdim,t+2*kdim,kdim,DOUBLE); 30668 tlen = slen[2]; 30669 30670 if (tlen > aepsge) 30671 { 30672 for (k1=0; k1 < kdim; k1++) tsen[3*kdim+k1] /= tlen; 30673 lcone[3] = 0; 30674 sang[3] = (double)0; 30675 } 30676 } 30677 else 30678 { 30679 s1990_s9edg(t+(2*kdim),ttan,tsen+(3*kdim),aepsge,sang+3,kdim,&kstat); 30680 if (kstat) ps->pdir->igtpi = 10; 30681 } 30682 } 30683 30684 next: 30685 30686 /* Here we makes the normales in each corner of the patch. 30687 We are using a cross product between two tangents. 30688 The normals is also normalized by deviding with its 30689 own length. */ 30690 30691 for (kcount=0, ki=0, k1=0; k1 < kdim4; k1+=kdim, ki++) 30692 { 30693 for (tlen=DZERO,k2=0,k3=1,k4=2; k2 < kdim; k2++,k3++,k4++) 30694 { 30695 if(k3 == kdim) k3 = 0; 30696 if(k4 == kdim) k4 = 0; 30697 tn[k1+k2] = t[k1+k3]*t[k1+kdim+k4]-t[k1+k4]*t[k1+kdim+k3]; 30698 30699 tlen += tn[k1+k2]*tn[k1+k2]; 30700 } 30701 tlen = sqrt(tlen); 30702 /* KYS 070494 : multiplied ANGULAR_TOLERANCE by 1.0e-2 */ 30703 if (slen[ki]>aepsge && slen[ki+1]>aepsge && 30704 scorn[ki] > 1.0e-2*ANGULAR_TOLERANCE) 30705 for (k2=0; k2 < kdim; k2++) tn[k1+k2] /= tlen; 30706 else 30707 { 30708 for (k2=0; k2 < kdim; k2++) tn[k1+k2] = ps->pdir->ecoef[k2]; 30709 kcount++; 30710 } 30711 } 30712 30713 if (kcount == 4) continue; /* Degenerate control polygon patch */ 30714 30715 /* We are treating the first patch. */ 30716 30717 if (kfirst) 30718 { 30719 /* Computing the center coordinates of the cone.*/ 30720 30721 for (tlen=DZERO,k1=0; k1 < kdim; k1++) 30722 { 30723 tmin = (double)1.0; 30724 tmax = - tmin; 30725 for (k2=0; k2 < kdim4; k2+=kdim) 30726 { 30727 tmax = max(tn[k2+k1],tmax); 30728 tmin = min(tn[k2+k1],tmin); 30729 } 30730 ps->pdir->ecoef[k1]=(tmax+tmin)/(double)2; 30731 30732 tlen += ps->pdir->ecoef[k1]*ps->pdir->ecoef[k1]; 30733 } 30734 tlen = sqrt(tlen); 30735 if (tlen > DZERO) 30736 for (k1=0; k1 < kdim; k1++) ps->pdir->ecoef[k1] /= tlen; 30737 else 30738 /* KYS 070494 : 'continue' replaced by the following block {} */ 30739 /* There are nonzero normals pointing in 30740 opposite directions, i.e. not simple case */ 30741 { 30742 if (khor <= kver) 30743 ps->pdir->igtpi = 1; 30744 else 30745 ps->pdir->igtpi = 2; 30746 ps->pdir->aang = PI; 30747 goto out; 30748 } 30749 30750 /* Computing the angle of the cone. */ 30751 30752 for (ps->pdir->aang=DZERO,k1=0; k1<kdim4; k1+=kdim) 30753 { 30754 for (tnlen=DZERO,tlen=DZERO,k2=0;k2<kdim;k2++) 30755 { 30756 tlen += ps->pdir->ecoef[k2]*tn[k1+k2]; 30757 tnlen += tn[k1+k2]*tn[k1+k2]; 30758 } 30759 30760 if (tlen >= DZERO) tlen = min((double)1.0,tlen); 30761 else tlen = max((double)-1.0,tlen); 30762 30763 tlen = acos(tlen); 30764 if (sqrt(tnlen) < aepsge) tlen = DZERO; 30765 30766 ps->pdir->aang = max(ps->pdir->aang,tlen); 30767 } 30768 30769 kfirst = 0; /* The first patch have been treated.*/ 30770 } 30771 else 30772 for (k1=0; k1<kdim4; k1+=kdim) 30773 { 30774 /* Computing the angle beetween the senter of the cone 30775 and the normal. */ 30776 30777 for (tnlen=DZERO,tang=DZERO,k2=0;k2<kdim;k2++) 30778 { 30779 tang += ps->pdir->ecoef[k2]*tn[k1+k2]; 30780 tnlen += tn[k1+k2]*tn[k1+k2]; 30781 } 30782 30783 if (tang >= DZERO) tang = MIN((double)1.0,tang); 30784 else tang = MAX((double)-1.0,tang); 30785 30786 tang = acos(tang); 30787 if (sqrt(tnlen) < aepsge) tang = DZERO; 30788 30789 if (tang + ps->pdir->aang >= PI) 30790 { 30791 /* The angle is to great, give a meesage 30792 how to subdivied and exit this function. */ 30793 30794 if (khor <= kver) 30795 ps->pdir->igtpi = 1; 30796 else 30797 ps->pdir->igtpi = 2; 30798 goto out; 30799 } 30800 else if (tang > ps->pdir->aang) 30801 { 30802 /* The normal is not inside the cone, than we 30803 have to compute a new cone. */ 30804 30805 /* Computing the center coordinates.*/ 30806 30807 double sin_tang = sin(tang); /*@ hke */ 30808 double delta = (tang - ps->pdir->aang)/2.0; /*@ hke */ 30809 30810 t1 = sin(delta)/sin_tang; /*@ hke */ 30811 t2 = sin(tang - delta)/sin_tang; /*@ hke */ 30812 30813 /* 30814 t1 = (tang - ps->pdir->aang)/((double)2*tang); 30815 t2 = (double)1 - t1; 30816 */ 30817 30818 for (tlen=DZERO,k2=0; k2<kdim; k2++) 30819 { 30820 ps->pdir->ecoef[k2] = 30821 ps->pdir->ecoef[k2]*t2 + tn[k1+k2]*t1; 30822 tlen += ps->pdir->ecoef[k2]*ps->pdir->ecoef[k2]; 30823 } 30824 tlen = sqrt(tlen); 30825 30826 for (k2=0; k2 < kdim; k2++) ps->pdir->ecoef[k2] /= tlen; 30827 30828 /* Computing the angle of the cone. */ 30829 30830 ps->pdir->aang = (tang + ps->pdir->aang)/(double)2; 30831 } 30832 } 30833 30834 if (ps->pdir->aang >= SIMPLECASE) 30835 { 30836 /* The angle is to great, give a meesage 30837 how to subdivied and exit this function. */ 30838 30839 if (khor <= kver) 30840 ps->pdir->igtpi = 10; 30841 else 30842 ps->pdir->igtpi = 20; 30843 } 30844 } 30845 30846 /* A final check if we have made a cone. */ 30847 /* UJK, SI, 91-10, when 2D, return values from edge case */ 30848 if (kfirst && kdim != 2) 30849 { 30850 /* No cone has been generated. We must examin if the surface is 30851 degenerated to a point or line. */ 30852 for (k1 = 1; k1 < kn1*kn2; k1++) 30853 if (s6dist(scoef,scoef + (k1*kdim),kdim) >aepsge) break; 30854 30855 if (k1 == kn1*kn2) 30856 { 30857 /* Degenerated to a point. */ 30858 ps->pdir->igtpi = 0; 30859 ps->pdir->aang = DZERO; 30860 ps->pdir->ecoef[0] = (double) 1.0; 30861 for (k1 = 1; k1 < kdim; k1++) ps->pdir->ecoef[k1] = DZERO; 30862 } 30863 else 30864 { 30865 s6diff(scoef,scoef + (k1*kdim),kdim,svec1); 30866 30867 for (k2 = k1 + 1; k2 < kn1*kn2; k2++) 30868 if (s6dist(scoef,scoef + (k2*kdim),kdim) >aepsge) 30869 { 30870 s6diff(scoef,scoef + (k2*kdim),kdim,svec2); 30871 if (s6ang(svec1,svec2,kdim) > 1.0e-2*ANGULAR_TOLERANCE) break; 30872 } 30873 30874 if (k2 == kn1*kn2) 30875 { 30876 /* Degenerated to a line. */ 30877 ps->pdir->igtpi = 0; 30878 ps->pdir->aang = DZERO; 30879 ps->pdir->ecoef[0] = (double) 1.0; 30880 for (k1 = 1; k1 < kdim; k1++) ps->pdir->ecoef[k1] = DZERO; 30881 } 30882 else 30883 { 30884 /* Three points describing a plane found, continue subdividing. */ 30885 if (ps->et1[kn1] - ps->et1[ps->ik1-1] >= 30886 ps->et2[kn2] - ps->et2[ps->ik2-1]) 30887 ps->pdir->igtpi = 1; 30888 else 30889 ps->pdir->igtpi = 2; 30890 } 30891 } 30892 } 30893 30894 /* success */ 30895 30896 goto out; 30897 30898 /* Error in space allacation. */ 30899 30900 err101: 30901 *jstat = -101; 30902 s6err("s1990",*jstat,kpos); 30903 goto out; 30904 30905 /* Error in lower level routine. */ 30906 30907 /* error : 30908 *jstat = kstat; 30909 goto out; 30910 */ 30911 30912 /* Free local used memory. */ 30913 30914 out: 30915 if (t != SISL_NULL) freearray(t); 30916 } 30917 30918 30919 30920 30921 //=========================================================================== 30922 void sh1994(SISLSurf *s1,double aepsge,int *jstat) 30923 //=========================================================================== 30924 { 30925 register int ki,kj,kh; 30926 int kk1, kk2, kn1, kn2; 30927 int kbez; 30928 30929 double tmaxt, tmaxs; 30930 double tmint, tmins; 30931 double tdiff; 30932 double *scoef=SISL_NULL; 30933 30934 /* Init to simple case. */ 30935 *jstat = 1; 30936 30937 tmaxt = tmaxs = - HUGE; 30938 tmint = tmins = HUGE; 30939 30940 /* Get surface attributes. */ 30941 kk1 = s1->ik1; 30942 kk2 = s1->ik2; 30943 kn1 = s1->in1; 30944 kn2 = s1->in2; 30945 kbez = (kk1 == kn1) && (kk2 == kn2); 30946 30947 30948 /* If the surface is linear in some direction it is simpel case. */ 30949 if ((kk1 == 2 && kn1 == 2) || (kk2 == 2 && kn2 == 2)) goto out; 30950 30951 30952 /* Run through vertices in first parameter direction to find 30953 intervall of first derivative. */ 30954 30955 /* UJK, 91-10 */ 30956 /* for (kj=0, scoef=s1->ecoef; kj<kn2; kj++,scoef++) */ 30957 for (kj=0, scoef=s1->ecoef; kj<kn2; kj++,scoef=s1->ecoef+kn1*kj) 30958 for (tdiff=DZERO, ki=1; ki<kn1; ki+=kh, scoef+=kh) 30959 { 30960 for (kh=1; ki+kh<=kn1; kh++) 30961 { 30962 if (tdiff*(*(scoef+kh) - *(scoef+kh-1)) < DZERO) 30963 { 30964 scoef += (kh-1); 30965 ki += (kh-1); 30966 kh = 1; 30967 } 30968 tdiff = *(scoef + kh) - *scoef; 30969 if (fabs(tdiff) >= aepsge) break; 30970 } 30971 if (ki+kh > kn1) break; 30972 30973 tmint = min(tmint,tdiff); 30974 tmaxt = max(tmaxt,tdiff); 30975 } 30976 30977 /* Run through vertices in second parameter direction to find 30978 intervall of first derivative. */ 30979 30980 for (ki=0; ki<kn1; ki++) 30981 for (tdiff=DZERO, kj=1, scoef=s1->ecoef+ki; kj<kn2; kj+=kh, scoef+=kh*kn1) 30982 { 30983 for (kh=1; kj+kh<=kn2; kh++) 30984 { 30985 if (tdiff*(*(scoef+kh*kn1) - *(scoef+(kh-1)*kn1)) < DZERO) 30986 { 30987 scoef += (kh-1)*kn1; 30988 kj += (kh-1); 30989 kh = 1; 30990 } 30991 tdiff = *(scoef + kh*kn1) - *scoef; 30992 if (fabs(tdiff) >= aepsge) break; 30993 } 30994 if (kj+kh > kn2) break; 30995 30996 tmins = min(tmins,tdiff); 30997 tmaxs = max(tmaxs,tdiff); 30998 } 30999 31000 /* UJK, 91-10, maybe parameters not set */ 31001 if (tmint > tmaxt || tmins > tmaxs) 31002 { 31003 *jstat = 1; 31004 goto out; 31005 } 31006 31007 /* The first derivatives decide directions of possible intersection curves. */ 31008 if (kbez && (tmint*tmaxt >=DZERO || tmins*tmaxs >=DZERO)) 31009 *jstat = 1; 31010 else if (tmint*tmaxt > DZERO || tmins*tmaxs > DZERO) 31011 *jstat = 1; 31012 else if (tmint == tmaxt || tmins == tmaxs) 31013 *jstat = 1; 31014 else 31015 /* Not a simple case. */ 31016 *jstat = 0; 31017 31018 goto out; 31019 out: ; 31020 } 31021 31022 31023 //=========================================================================== 31024 SISLdir * newdir (int idim) 31025 //=========================================================================== 31026 { 31027 SISLdir *qnew; /* Local pointer to new direction structure.*/ 31028 31029 /* Allocate space for direction structure. */ 31030 31031 if ((qnew = newarray (1, SISLdir)) != SISL_NULL) 31032 { 31033 /* Initialise new direction structure. */ 31034 31035 qnew->igtpi = 0; 31036 qnew->esmooth = SISL_NULL; 31037 if ((qnew->ecoef = newarray (idim, double)) == SISL_NULL) 31038 freearray (qnew); 31039 } 31040 return (qnew); 31041 } 31042 31043 //=========================================================================== 31044 void s1991(SISLCurve *pc,double aepsge,int *jstat) 31045 //=========================================================================== 31046 { 31047 int kpos = 0; /* Position of the error. */ 31048 int kfirst = 1; /* Flag to mark if the first tangent is treating. */ 31049 int kn; /* Number of vertices of curve. */ 31050 int kdim; /* Dimension of the space in which the objects lie.*/ 31051 int kin; /* The index to the vertice to treat. */ 31052 int k1,k2; /* Control variables in loop. */ 31053 double *t=SISL_NULL; /* Tangent at each coeficient. */ 31054 double tlen; /* The length of a vector. */ 31055 double tang; /* An angle between two vectors. */ 31056 double t1,t2; /* Help variables. */ 31057 double *scoef; /* Pointer to coefficients. */ 31058 31059 31060 31061 /* Test if the surfaces already have been treated. */ 31062 31063 if (pc->pdir != SISL_NULL) goto out; 31064 31065 31066 /* Initialate dimentions. */ 31067 31068 kdim = pc -> idim; 31069 kn = pc -> in; 31070 31071 31072 /* Make a new direction cone. */ 31073 31074 if ((pc->pdir = newdir(kdim))==SISL_NULL) goto err101; 31075 31076 /* UJK, Set default values in pdir. */ 31077 pc->pdir->aang = DZERO; 31078 pc->pdir->igtpi = 0; 31079 pc->pdir->ecoef[0] = (double) 1.0; 31080 31081 for (k2 = 1;k2<kdim;k2++) 31082 pc->pdir->ecoef[k2] = DZERO; 31083 31084 31085 /* Allocate local used array. */ 31086 31087 if ((t = newarray(kdim,double)) == SISL_NULL) goto err101; 31088 31089 /* Allocate scratch for smoothed coefficients. */ 31090 31091 if ((pc->pdir->esmooth = newarray(kn*kdim,DOUBLE)) == SISL_NULL) goto err101; 31092 scoef = pc->pdir->esmooth; 31093 31094 /* Compute coefficients of smoothed curve. */ 31095 31096 /* s1991_s9smooth(pc->ecoef,kn,kdim,aepsge,scoef,&kstat); 31097 if (kstat < 0) goto error; */ 31098 /* (VSK 02-1994: no point in smoothing) */ 31099 memcopy(scoef, pc->ecoef, kn*kdim, DOUBLE); 31100 31101 /* Here we are treating each patch in the control polygon separately.*/ 31102 31103 for (k2=0,kin=0; kin < kn-1; kin++) 31104 { 31105 31106 /* Here we make an aproximative tangents to the curve 31107 using the control polygon. The tangents is also normalized 31108 by deviding with its own length. */ 31109 31110 for (tlen=DZERO,k1=0; k1 < kdim; k1++,k2++) 31111 { 31112 t[k1] = scoef[k2+kdim] - scoef[k2]; 31113 tlen += t[k1]*t[k1]; 31114 } 31115 31116 tlen = sqrt(tlen); 31117 31118 if (tlen > aepsge) 31119 for (k1=0; k1 < kdim; k1++) t[k1] /= tlen; 31120 else 31121 { 31122 /* UJK, whats wrong with colapsed polygons when computing directions? */ 31123 continue; 31124 31125 /* Vi have to be aware of colapsed polygon. */ 31126 /* pc->pdir->igtpi = 1; 31127 goto out; */ 31128 31129 } 31130 31131 31132 /* We are treating the first tangent. */ 31133 31134 if (kfirst) 31135 { 31136 31137 /* Computing the center coordinates of the cone.*/ 31138 31139 for (k1=0; k1 < kdim; k1++) 31140 pc->pdir->ecoef[k1]= t[k1]; 31141 31142 /* Computing the angle of the cone. */ 31143 31144 pc->pdir->aang = DZERO; 31145 31146 kfirst = 0; /* The first tangent have been treated.*/ 31147 } 31148 else 31149 { 31150 31151 /* Computing the angle beetween the senter of the cone 31152 and the tangent. */ 31153 31154 for (tang=DZERO,k1=0;k1<kdim;k1++) 31155 tang += pc->pdir->ecoef[k1]*t[k1]; 31156 31157 if (tang >= DZERO) tang = min((double)1.0,tang); 31158 else tang = max((double)-1.0,tang); 31159 31160 tang = acos(tang); 31161 31162 if (tang + pc->pdir->aang >= PI) 31163 { 31164 /* The angle is to great, give a meesage 31165 to subdivied and exit this function. */ 31166 31167 pc->pdir->igtpi = 1; 31168 goto out; 31169 } 31170 else if (tang > pc->pdir->aang) 31171 { 31172 /* The tangent is not inside the cone, and we 31173 have to compute a new cone. */ 31174 31175 /* Computing the center coordinates.*/ 31176 31177 t1 = (tang - pc->pdir->aang)/((double)2*tang); 31178 t2 = (double)1 - t1; 31179 31180 for (tlen=DZERO,k1=0; k1<kdim; k1++) 31181 { 31182 pc->pdir->ecoef[k1] = 31183 pc->pdir->ecoef[k1]*t2 + t[k1]*t1; 31184 tlen += pc->pdir->ecoef[k1]* 31185 pc->pdir->ecoef[k1]; 31186 } 31187 tlen = sqrt(tlen); 31188 31189 if (tlen > DZERO) 31190 for (k1=0; k1 < kdim; k1++) 31191 pc->pdir->ecoef[k1] /= tlen; 31192 else 31193 { 31194 /* Vi have to be aware of colapsed polyg.*/ 31195 31196 pc->pdir->igtpi = 1; 31197 goto out; 31198 } 31199 31200 31201 /* Computing the angle of the cone. */ 31202 31203 pc->pdir->aang = (tang + pc->pdir->aang)/ 31204 (double)2; 31205 } 31206 } 31207 } 31208 31209 31210 31211 if (pc->pdir->aang >= SIMPLECASE) 31212 { 31213 /* The angle is to great, give a message 31214 to subdivied and exit this function. */ 31215 31216 pc->pdir->igtpi = 3; 31217 goto out; 31218 } 31219 31220 31221 *jstat = 0; 31222 goto out; 31223 31224 31225 /* Error in space allacation. */ 31226 31227 err101: *jstat = -101; 31228 s6err("s1991",*jstat,kpos); 31229 goto out; 31230 31231 out: if (t != SISL_NULL) freearray(t); 31232 31233 } 31234 31235 31236 //=========================================================================== 31237 void sh1993(SISLCurve *c1,double aepsge,int *jstat) 31238 //=========================================================================== 31239 { 31240 register int ki,kj; 31241 31242 int kk,kn; 31243 int kbez; 31244 double tmax; 31245 double tmin; 31246 double tdiff; 31247 double *scoef=SISL_NULL; 31248 /* ----------------------------------------------------------- */ 31249 31250 /* Init to simple case. */ 31251 *jstat = 1; 31252 31253 tmax = - HUGE; 31254 tmin = HUGE; 31255 31256 /* Get curve attributes. */ 31257 kk = c1->ik; 31258 kn = c1->in; 31259 kbez = (kk == kn); 31260 31261 /* Run through vertices to find 31262 intervall of first derivative. */ 31263 31264 for (tdiff=DZERO, ki=1, scoef=c1->ecoef; ki<kn; ki+=kj, scoef+=kj) 31265 { 31266 for (kj=1; ki+kj<=kn; kj++) 31267 { 31268 if (tdiff*(*(scoef+kj) - *(scoef+kj-1)) < DZERO) 31269 { 31270 scoef += (kj-1); 31271 ki += (kj-1); 31272 kj = 1; 31273 } 31274 tdiff = *(scoef + kj) - *scoef; 31275 if (fabs(tdiff) >= aepsge) break; 31276 } 31277 if (ki+kj > kn) break; 31278 31279 tmin = min(tmin,tdiff); 31280 tmax = max(tmax,tdiff); 31281 } 31282 31283 31284 /* Simple case when no genuin zero's of first derivative. */ 31285 if (kbez && (tmin*tmax >=DZERO)) 31286 *jstat = 1; 31287 else if (tmin*tmax > DZERO) 31288 *jstat = 1; 31289 else if (tmin == tmax) 31290 *jstat = 1; 31291 else 31292 /* Not a simple case. */ 31293 *jstat = 0; 31294 31295 } 31296 31297 31298 //=========================================================================== 31299 void s1741(SISLObject *po1,SISLObject *po2,double aepsge,int *jstat) 31300 //=========================================================================== 31301 { 31302 int kstat = 0; /* Local status variable. */ 31303 int kpos = 0; /* Position of the error. */ 31304 int k1; /* Control variable in loop. */ 31305 double tang; /* Angel between two vectors. */ 31306 double small_tang;/* Smallest angle between two vectors. */ 31307 31308 if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT) 31309 { 31310 SISLObject *qo1,*qo2; 31311 31312 if(po1->iobj == SISLPOINT) 31313 { 31314 qo1 = po1; 31315 qo2 = po2; 31316 } 31317 else 31318 { 31319 qo1 = po2; 31320 qo2 = po1; 31321 } 31322 31323 if (qo2->iobj == SISLCURVE) 31324 { 31325 /* Test if the curve lies in the same space as the point. */ 31326 31327 if (qo1->p1->idim != qo2->c1->idim) goto err106; 31328 31329 if (qo2->c1->idim == 1) 31330 { 31331 sh1993(qo2->c1,aepsge,&kstat); 31332 31333 *jstat = kstat; 31334 goto out; 31335 } 31336 31337 /* Computing the direction cone of the curve. If the curve 31338 have cones greater then pi we just return not a simple case. */ 31339 31340 s1991(qo2->c1,aepsge,&kstat); 31341 if (kstat < 0) goto error; 31342 else if (qo2->c1->pdir->igtpi != 0) goto out2;/* Not a simple case.*/ 31343 31344 31345 /* Performing a simple case check. */ 31346 31347 if (qo2->c1->pdir->aang<PIHALF) 31348 { 31349 /* A simpel case. The iteration is able to 31350 find intersection.*/ 31351 31352 *jstat = 1; 31353 goto out; 31354 } 31355 } 31356 else if (qo2->iobj == SISLSURFACE) 31357 { 31358 /* Test if the surface lies in the same space as the point. */ 31359 31360 if (qo1->p1->idim != qo2->s1->idim) goto err106; 31361 31362 31363 if (qo2->s1->idim == 1) 31364 { 31365 sh1994(qo2->s1,aepsge,&kstat); 31366 31367 *jstat = kstat; 31368 goto out; 31369 } 31370 else 31371 { 31372 /* Computing the direction cone of the surface. If the surface 31373 have cones greater then pi we just return not a simple case.*/ 31374 31375 s1990(qo2->s1,aepsge,&kstat); 31376 if (kstat < 0) goto error; 31377 else if (qo2->s1->pdir->igtpi != 0) goto out2; /*No simple case*/ 31378 31379 31380 /* Performing a simple case check. */ 31381 31382 if (qo2->s1->pdir->aang<PIHALF) 31383 { 31384 /* A simpel case. The iteration is able to 31385 find intersection.*/ 31386 31387 31388 *jstat = 1; 31389 goto out; 31390 } 31391 } 31392 } 31393 } 31394 else if (po1->iobj == SISLCURVE && po2->iobj == SISLCURVE) 31395 { 31396 /* Test if the curves lies in the same space. */ 31397 31398 if (po2->c1->idim != po1->c1->idim) goto err106; 31399 31400 31401 31402 /* Computing the direction cone of the two curves. If one of them 31403 have cones greater then pi we just return not a simple case. */ 31404 31405 s1991(po1->c1,aepsge,&kstat); 31406 if (kstat < 0) goto error; 31407 31408 s1991(po2->c1,aepsge,&kstat); 31409 if (kstat < 0) goto error; 31410 31411 if (po1->c1->pdir->igtpi != 0) goto out2; /* Not a simple case.*/ 31412 if (po2->c1->pdir->igtpi != 0) goto out2; /* Not a simple case.*/ 31413 31414 31415 /* Computing the angle beetween the senters of the two cones. */ 31416 31417 for (tang=DZERO,k1=0;k1<po1->c1->idim;k1++) 31418 tang += po1->c1->pdir->ecoef[k1]*po2->c1->pdir->ecoef[k1]; 31419 31420 if (tang >= DZERO) tang = min((double)1.0,tang); 31421 else tang = max((double)-1.0,tang); 31422 31423 tang = acos(tang); 31424 31425 if (tang > PIHALF) 31426 small_tang = PI - tang; 31427 else 31428 small_tang = tang; 31429 31430 /* Performing a simple case check. */ 31431 31432 if ((tang+po1->c1->pdir->aang+po2->c1->pdir->aang)<PI && 31433 (po1->c1->pdir->aang+po2->c1->pdir->aang)<tang) 31434 { 31435 /* A simpel case. The two cones and their mirrors 31436 are not intersecting.*/ 31437 31438 *jstat = 1; 31439 goto out; 31440 } 31441 else if (po1->c1->idim == 2) 31442 { 31443 *jstat = 0; 31444 goto out; 31445 } 31446 else if (tang < PI - ANGULAR_TOLERANCE && 31447 tang > ANGULAR_TOLERANCE && 31448 po1->c1->pdir->aang <= (double)1.3*small_tang && 31449 po2->c1->pdir->aang <= (double)1.3*small_tang) 31450 /*po1->c1->pdir->aang <= (double)1.3*tang && 31451 po2->c1->pdir->aang <= (double)1.3*tang)*/ 31452 { 31453 s1796(po1->c1,po2->c1,aepsge,tang,&kstat); 31454 if (kstat<0) goto error; 31455 else *jstat = kstat; 31456 goto out; 31457 } 31458 } 31459 else if (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE) 31460 { 31461 31462 /* Test if the surfaces lies in the same space. */ 31463 31464 if (po2->s1->idim != po1->s1->idim) goto err106; 31465 31466 31467 31468 /* Computing the direction cone of the two surfaces. If one of them 31469 have cones greater then pi we just return not a simple case. */ 31470 31471 s1990(po1->s1,aepsge,&kstat); 31472 if (kstat < 0) goto error; 31473 31474 s1990(po2->s1,aepsge,&kstat); 31475 if (kstat < 0) goto error; 31476 31477 if (po1->s1->pdir->igtpi != 0) goto out2; /* Not a simple case. */ 31478 31479 if (po2->s1->pdir->igtpi != 0) goto out2; /* Not a simple case. */ 31480 31481 /* Computing the angle beetween the senters of the two cones. */ 31482 31483 for (tang=DZERO,k1=0;k1<po1->s1->idim;k1++) 31484 tang += po1->s1->pdir->ecoef[k1]*po2->s1->pdir->ecoef[k1]; 31485 31486 if (tang >= DZERO) tang = min((double)1.0,tang); 31487 else tang = max((double)-1.0,tang); 31488 31489 tang = acos(tang); 31490 31491 31492 /* Performing a simple case check. */ 31493 31494 if ((tang+po1->s1->pdir->aang+po2->s1->pdir->aang)<PI && 31495 (po1->s1->pdir->aang+po2->s1->pdir->aang)<tang) 31496 { 31497 /* A simpel case. The two cones and their mirrors 31498 are not intersecting.*/ 31499 31500 po1->psimple = po2; 31501 *jstat = 1; 31502 goto out; 31503 } 31504 else if (tang < PI - ANGULAR_TOLERANCE && 31505 tang > ANGULAR_TOLERANCE && 31506 po1->s1->pdir->aang <= (double)1.3*tang && 31507 po2->s1->pdir->aang <= (double)1.3*tang) 31508 { 31509 s1795(po1->s1,po2->s1,aepsge,tang,&kstat); 31510 if (kstat < 0) goto error; 31511 if (kstat == 1) po1->psimple = po2; 31512 *jstat = kstat; 31513 goto out; 31514 } 31515 } 31516 else if (po1->iobj == SISLCURVE || po2->iobj == SISLCURVE) 31517 { 31518 SISLObject *qo1,*qo2; 31519 31520 if(po1->iobj == SISLCURVE) 31521 { 31522 qo1 = po1; 31523 qo2 = po2; 31524 } 31525 else 31526 { 31527 qo1 = po2; 31528 qo2 = po1; 31529 } 31530 31531 31532 /* Test if the surface and curve lies in the same space. */ 31533 31534 if (qo2->s1->idim != qo1->c1->idim) goto err106; 31535 31536 31537 31538 /* Computing the direction cone of the curve and the surface. If one of 31539 them have cones greater then pi we just return not a simple case. */ 31540 31541 31542 s1990(qo2->s1,aepsge,&kstat); 31543 if (kstat < 0) goto error; 31544 31545 s1991(qo1->c1,aepsge,&kstat); 31546 if (kstat < 0) goto error; 31547 31548 if (qo1->c1->pdir->igtpi != 0) goto out2; /* Not a simple case. */ 31549 if (qo2->s1->pdir->igtpi != 0) goto out2; /* Not a simple case. */ 31550 31551 31552 31553 /* Computing the angle beetween the senters of the two cones. */ 31554 31555 for (tang=DZERO,k1=0;k1<qo2->s1->idim;k1++) 31556 tang += qo2->s1->pdir->ecoef[k1]*qo1->c1->pdir->ecoef[k1]; 31557 31558 if (tang >= DZERO) tang = min((double)1.0,tang); 31559 else tang = max((double)-1.0,tang); 31560 31561 tang = acos(tang); 31562 31563 31564 /* Performing a simple case check. */ 31565 31566 if (((tang + qo1->c1->pdir->aang) < (PIHALF - qo2->s1->pdir->aang)) || 31567 ((tang - PIHALF - qo1->c1->pdir->aang) > qo2->s1->pdir->aang)) 31568 { 31569 /* A simpel case. The curve cone or the mirror cone 31570 are tottally inside the inverted surface cone. */ 31571 31572 *jstat = 1; 31573 goto out; 31574 } 31575 else if (tang < PI - ANGULAR_TOLERANCE && 31576 tang > ANGULAR_TOLERANCE && 31577 min(tang,fabs(PI-tang)) < 31578 (double)0.8*(PIHALF - qo2->s1->pdir->aang) && 31579 qo1->c1->pdir->aang < (double)0.8*(PIHALF-qo2->s1->pdir->aang)) 31580 { 31581 s1797(qo2->s1,qo1->c1,aepsge,tang,&kstat); 31582 if (kstat<0) goto error; 31583 else *jstat = kstat; 31584 goto out; 31585 } 31586 } 31587 31588 31589 /* Not a simple case. */ 31590 31591 out2: *jstat = 0; 31592 goto out; 31593 31594 /* Error. Dimensions conflicting. */ 31595 31596 err106: *jstat = -106; 31597 s6err("s1741",*jstat,kpos); 31598 goto out; 31599 31600 /* Error in lower level routine. */ 31601 31602 error : *jstat = kstat; 31603 s6err("s1741",*jstat,kpos); 31604 goto out; 31605 31606 out: ; 31607 } 31608 31609 31610 //=========================================================================== 31611 void sh6edgpoint (SISLEdge * vedge[], SISLIntpt *** wintpt, int *jnum,int *jstat) 31612 //=========================================================================== 31613 { 31614 int lant[2]; 31615 31616 if (vedge[0] == SISL_NULL) 31617 lant[0] = 0; 31618 else 31619 lant[0] = vedge[0]->ipoint; 31620 31621 if (vedge[1] == SISL_NULL) 31622 lant[1] = 0; 31623 else 31624 lant[1] = vedge[1]->ipoint; 31625 31626 if (lant[0] + lant[1] > 0) 31627 { 31628 int kn1; /* Number of int. pt. found. */ 31629 int kn, ki, kj; /* Counters. */ 31630 SISLPtedge *qpt; 31631 SISLIntpt *qintpt; /* Intersection point. */ 31632 SISLIntpt *qmain; /* Main point in chain of help points. */ 31633 31634 /* Allocate array of pointers to the points. */ 31635 31636 if (((*wintpt) = newarray (lant[0] + lant[1], 31637 SISLIntpt *)) == SISL_NULL) 31638 goto err101; 31639 31640 31641 /* Update the array. */ 31642 31643 for (kn1 = 0, kn = 0; kn < 2; kn++) 31644 if (lant[kn] > 0) 31645 for (kj = 0; kj < vedge[kn]->iedge; kj++) 31646 for (qpt = vedge[kn]->prpt[kj]; qpt != SISL_NULL; qpt = qpt->pnext) 31647 { 31648 for (ki = 0; ki < kn1; ki++) 31649 { 31650 if (qpt->ppt == (*wintpt)[ki]) 31651 break; 31652 } 31653 if (ki == kn1) 31654 (*wintpt)[kn1++] = qpt->ppt; 31655 } 31656 31657 /* Traverse the array and remove help points if the corresponding 31658 main point also lies in the array. */ 31659 31660 for (ki = 0; ki < kn1; ki++) 31661 { 31662 qintpt = (*wintpt)[ki]; 31663 if (sh6ishelp (qintpt)) 31664 { 31665 /* A help point is found. Fetch the corresponding main point. */ 31666 31667 qmain = sh6getmain (qintpt); 31668 31669 /* Check if the main point lies in the array. */ 31670 31671 if (qmain) 31672 { 31673 for (kj = 0; kj < kn1; kj++) 31674 if (qmain == (*wintpt)[kj]) 31675 break; 31676 if (kj < kn1) 31677 (*wintpt)[ki] = SISL_NULL; 31678 } 31679 } 31680 } 31681 31682 /* Make sure that the array of int.pt. is dense. */ 31683 31684 for (ki = 0, kj = kn1; ki < kj; ki++) 31685 if ((*wintpt)[ki] == SISL_NULL) 31686 (*wintpt)[ki] = (*wintpt)[--kj]; 31687 31688 *jnum = kn1 = kj; 31689 } 31690 else 31691 *jnum = 0; 31692 31693 *jstat = 0; 31694 goto out; 31695 31696 /* Error in memory allocation. */ 31697 31698 err101:*jstat = -101; 31699 s6err ("sh6edgpoint", *jstat, 0); 31700 goto out; 31701 31702 31703 out:; 31704 } 31705 31706 //=========================================================================== 31707 void sh1762 (SISLObject * po1, SISLObject * po2, double aepsge, 31708 SISLIntdat ** pintdat, SISLEdge * vedge[], int *jstat) 31709 //=========================================================================== 31710 { 31711 int kpos = 0; /* Position of error. */ 31712 int kstat = 0; /* Local error status. */ 31713 int kdiv1 = 0; /* Parameter direction of subdivsion. */ 31714 int kdiv2 = 0; /* Parameter direction of subdivsion. */ 31715 int ki, ki1, ki2; /* Counters. */ 31716 int at_bottom=TRUE; /* Flag, true on bottom level of recur*/ 31717 int knewpt=0; /* No of points made in prtop part */ 31718 int kexpand = 2; /* Expand box in the inner of object. */ 31719 int kxintercept = (*jstat == 202); /* Extra interception */ 31720 /* int knum; */ /* Number of intersection points at edges. */ 31721 SISLObject *uob1[4]; /* Pointers to subdivided object. */ 31722 SISLObject *uob2[4]; /* Pointer to object to subdivide. */ 31723 31724 int debug_flag=0; 31725 31726 /* FOR DEBUGGING define debug_flag as an extern variable, i.e.: 31727 * 31728 * extern int debug_flag; 31729 */ 31730 31731 if (debug_flag) 31732 { 31733 if ((po1->iobj == SISLSURFACE && po1->s1->idim == 1) || 31734 (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE)) 31735 { 31736 /* if (po1->s1->et1[0] >= 3.3 && 31737 po1->s1->et1[po1->s1->in1] <= 3.6 && 31738 po1->s1->et2[0] >= 0.7 && 31739 po1->s1->et2[po1->s1->in2] <= 0.9) 31740 { 31741 */ 31742 int knum; 31743 int ipar = 2; 31744 int kj, ki; 31745 SISLIntpt **up = SISL_NULL; /* Array of poiners to intersection point.*/ 31746 31747 sh6edgpoint (vedge, &up, &knum, &kstat); 31748 if (kstat < 0) 31749 goto error; 31750 if (debug_flag == 1) 31751 { 31752 printf("\n___________________________________________________"); 31753 31754 printf("\n par val(1) :%#10.10g %#10.10g %#10.10g %#10.10g ", 31755 po1->s1->et1[0], 31756 po1->s1->et1[po1->s1->in1], 31757 po1->s1->et2[0], 31758 po1->s1->et2[po1->s1->in2]); 31759 if (po2->iobj == SISLSURFACE) 31760 { 31761 ipar = 4; 31762 printf("\n par val(2) :%#10.10g %#10.10g %#10.10g %#10.10g ", 31763 po2->s1->et1[0], 31764 po2->s1->et1[po2->s1->in1], 31765 po2->s1->et2[0], 31766 po2->s1->et2[po2->s1->in2]); 31767 } 31768 printf("\n No of pts: %d",knum); 31769 for (ki = 0; ki < knum; ki++) 31770 { 31771 printf("\n point %d :",ki); 31772 for (kj = 0; kj < ipar; kj++) 31773 printf(" %#10.10g", up[ki]->epar[kj]); 31774 } 31775 } 31776 else /* if (debug_flag == 2) */ 31777 { 31778 printf("fg: black \n"); 31779 printf("lin: \n%#10.10g %#10.10g \n", 31780 po1->s1->et1[0], 31781 po1->s1->et2[0]); 31782 31783 printf("%#10.10g %#10.10g \n", 31784 po1->s1->et1[0], 31785 po1->s1->et2[po1->s1->in2]); 31786 31787 printf("%#10.10g %#10.10g \n", 31788 po1->s1->et1[po1->s1->in1], 31789 po1->s1->et2[po1->s1->in2]); 31790 31791 printf("%#10.10g %#10.10g \n", 31792 po1->s1->et1[po1->s1->in1], 31793 po1->s1->et2[0]); 31794 31795 printf("%#10.10g %#10.10g \n", 31796 po1->s1->et1[0], 31797 po1->s1->et2[0]); 31798 31799 } 31800 31801 if (up) freearray(up); 31802 31803 /* } */ 31804 } 31805 } 31806 31807 sh1762_xc++; 31808 sh1762_xmax = MAX (sh1762_xmax, sh1762_xc); 31809 /* printf("Max : %d \n",xc); */ 31810 31811 31812 for (ki = 0; ki < 4; ki++) 31813 uob1[ki] = uob2[ki] = SISL_NULL; 31814 31815 /* Initiate to no intersection. */ 31816 31817 *jstat = 0; 31818 31819 /* Test if intersection is possible (perform box-test). */ 31820 31821 /* box_nmb++; 31822 time_before = clock(); */ 31823 31824 sh1790 (po1, po2, kexpand, aepsge, &kstat); 31825 31826 /* time_used = clock() - time_before; 31827 box_time += time_used; */ 31828 if (kstat < 0) 31829 goto error; 31830 31831 /* printf("Box test. Status = %d \n",kstat); */ 31832 31833 /* We may have tree different values on kstat. 31834 kstat = 1 : The two boxes overlapp. 31835 kstat = 2 : The two "bezier" boxes is just touching. 31836 kstat = 3 : The two boxes is both inside a microbox of aepsge. 31837 kstat = 4 : One of the objects is degenerated to one 3D point. 31838 kstat = 5 : Danger of shadow area in point object intersection, 31839 dimension > 1. */ 31840 31841 if (kstat == 5) 31842 { 31843 /* VSK, 92-10. 31844 Either make sure that there is no overlap, or find the intersection. 31845 The situation that there is an intersection point in point-object 31846 intersection when dim > 1 where the usual box test fails to 31847 recognize the possibility may arise near the endpoints/edges of 31848 the other object. */ 31849 31850 sh1762_s9ptiter(po1, po2, aepsge, pintdat, vedge, &kstat); 31851 if (kstat < 0) goto error; 31852 31853 /* kstat = 0 : No overlap. 31854 kstat = 1 : The boxes overlap, and the intersection is found. */ 31855 31856 if (kstat == 1) *jstat = 1; 31857 } 31858 31859 else if (kstat == 4) 31860 31861 goto out; 31862 31863 else if (kstat == 3) 31864 { 31865 /* Microbox found.*/ 31866 31867 sh1762_s9mic (po1, po2, pintdat, &vedge, &kstat); 31868 if (kstat < 0) 31869 goto error; 31870 else 31871 *jstat = kstat; /* Possible uppdating intersection found. */ 31872 } 31873 else if (kstat == 1) 31874 { 31875 /* Simple Case test (more than one intersection possible?) */ 31876 31877 /* UJK, div until bezier, due to problems in silhouettes */ 31878 /* Must be opened again for silhouettes NO/YES?/NO!/... 31879 ??????????????????????????????????? 31880 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 31881 31882 31883 if ((po1->iobj == SISLSURFACE && po1->s1->idim == 1 && 31884 (po1->s1->ik1 != po1->s1->in1 || po1->s1->ik2 != po1->s1->in2)) || 31885 (po2->iobj == SISLSURFACE && po2->s1->idim == 1 && 31886 (po2->s1->ik1 != po2->s1->in1 || po2->s1->ik2 != po2->s1->in2))) 31887 kstat = 0; 31888 else 31889 { */ 31890 31891 s1741 (po1, po2, aepsge, &kstat); 31892 if (kstat < 0) 31893 goto error; 31894 else if (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE && 31895 vedge[0]->ipoint + vedge[1]->ipoint > 0 && !kstat) 31896 sh1762_s9simple (po1, po2, vedge, &kstat); 31897 if (kstat < 0) 31898 goto error; 31899 /* } */ 31900 /* We may have two different values on kstat. 31901 kstat = 0 : No simple case. 31902 kstat = 1 : Simple case (surfaces possible simple case). */ 31903 31904 if (kstat == 1) 31905 { 31906 /* Possible simple Case, update intersection list. */ 31907 31908 sh1762_s9update (po1, po2, aepsge, pintdat, &vedge, &kstat); 31909 if (kstat < 0) 31910 goto error; 31911 31912 /* We may have two different values on kstat. 31913 kstat = 0 : No simple case, more than two edge intersection. 31914 kstat = 1 : Intersection found. */ 31915 31916 if (kstat == 1) 31917 *jstat = 1; /*Updating found intersection. */ 31918 } 31919 31920 /* UJK,20.01.93, Don't skip s9con when not success in s9update. 31921 removed else.*/ 31922 if (kstat ==0) 31923 { 31924 /* UJK, 17.12.92, for a 1D surface of bezier type 31925 there may be a posibility of dividing out edge 31926 curve intersections */ 31927 if (po1->iobj == SISLSURFACE && po1->s1->idim ==1) 31928 { 31929 sh_1d_div(po1, po2, aepsge, pintdat, vedge, &kstat); 31930 if (kstat < 0) 31931 goto error; 31932 if (kstat == 1) 31933 *jstat = 1; /*Updating found intersection. */ 31934 } 31935 else if (po2->iobj == SISLSURFACE && po2->s1->idim == 1) 31936 { 31937 sh_1d_div(po2, po1, aepsge, pintdat, vedge, &kstat); 31938 if (kstat < 0) 31939 goto error; 31940 if (kstat == 1) 31941 *jstat = 1; /*Updating found intersection. */ 31942 } 31943 31944 else 31945 { 31946 31947 /* Check for interval intersection. */ 31948 31949 kstat = (kxintercept) ? 202 : 0; 31950 sh1762_s9con (po1, po2, aepsge, pintdat, vedge, &kstat); 31951 if (kstat < 0) 31952 goto error; 31953 31954 /* printf("sh1762_s9con. Status = %d \n",kstat); */ 31955 31956 /* We may have two different values on kstat. 31957 kstat = 0 : No intervall intersection. 31958 kstat = 1 : Intervall intersection found. 31959 kstat = 2 : Intersection not possible */ 31960 31961 if (kstat == 1) 31962 *jstat = 1; /*Updating found intersection. */ 31963 } 31964 } 31965 31966 31967 if (kstat == 0) 31968 { 31969 /* Find number of possible subdivision directions. 31970 kdiv1 and kdiv2 may have 4 difference values : 31971 kdiv = 0 : Subdivision not possible. 31972 kdiv = 1 : Subdivision in first parameter direction. 31973 kdiv = 2 : Subdivision in second parameter direction. 31974 kdiv = 3 : Subdivision in both parameter directions. */ 31975 31976 sh1762_s9num (po1, po2, &kdiv1, &kstat); 31977 if (kstat < 0) 31978 goto error; 31979 31980 sh1762_s9num (po2, po1, &kdiv2, &kstat); 31981 if (kstat < 0) 31982 goto error; 31983 31984 if (kdiv1 + kdiv2 == 0) 31985 { 31986 /* There is two almost plane parallel objects, and 31987 there is nothing at the edges (otherwise the 31988 intersections should be found by s9con). Then the 31989 only possibility is that there is no intersection. */ 31990 /* VSK, 11-92. Since partial coincidence is not 31991 implemented, there might be intersections on the 31992 edges. Check this. This should not be necessary 31993 any more. 31994 31995 Check if there are intersection points on edges. 31996 31997 if (vedge[0] == SISL_NULL) 31998 knum = 0; 31999 else 32000 knum = vedge[0]->ipoint; 32001 32002 if (vedge[1] != SISL_NULL) 32003 knum += vedge[1]->ipoint; 32004 32005 32006 32007 if (knum > 0) 32008 { 32009 Do something that makes the routine terminate 32010 until partial coincidence is implemented. 32011 32012 sh1762_s9mic(po1, po2, pintdat, &vedge, &kstat); 32013 if (kstat < 0) goto error; 32014 32015 *jstat = kstat; 32016 } 32017 else 32018 { 32019 *jstat = 0; 32020 goto out; 32021 } */ 32022 32023 *jstat = 0; 32024 goto out; 32025 } 32026 else 32027 { 32028 SISLEdge *uedge[2]; /* Array of pointers to edges 32029 to use in subproblems. */ 32030 32031 32032 /* We do not have simple case and it is possible to 32033 subdivide. We therefor subdivide and update the 32034 edge intersection and then do a recurcive call 32035 to treat the sub problems. Curves are subdivided 32036 into two, surfaces into four. We can therefor get 32037 up to sexteen recurcive calls.*/ 32038 32039 32040 32041 /***** Treating objects on sub problems. *****/ 32042 32043 if (kdiv1 > 0) /* New objects for subdivision of po1. */ 32044 { 32045 for (ki = 0; ki < (kdiv1 < 3 ? 2 : 4); ki++) 32046 { 32047 if ((uob1[ki] = newObject (po1->iobj)) == SISL_NULL) 32048 goto err101; 32049 32050 /* Initiate o1 pointer to point to top level object. */ 32051 32052 uob1[ki]->o1 = po1->o1; 32053 } 32054 32055 /* Subdivide the po1 object. */ 32056 32057 sh1762_s9div (po1, po2, aepsge, 1, kdiv1, uob1, vedge, pintdat, &kstat); 32058 if (kstat < 0) 32059 goto error; 32060 else if (kstat == 1) 32061 *jstat = 1; 32062 } 32063 32064 32065 if (kdiv2 > 0) /* New objects for subdivision of po2. */ 32066 { 32067 for (ki = 0; ki < (kdiv2 < 3 ? 2 : 4); ki++) 32068 { 32069 if ((uob2[ki] = newObject (po2->iobj)) == SISL_NULL) 32070 goto err101; 32071 32072 /* Initiate o1 pointer to point to top level object. */ 32073 32074 uob2[ki]->o1 = po2->o1; 32075 } 32076 32077 /* Subdivide the po2 object. */ 32078 32079 sh1762_s9div (po1, po2, aepsge, 2, kdiv2, uob2, vedge, pintdat, &kstat); 32080 if (kstat < 0) 32081 goto error; 32082 else if (kstat == 1) 32083 *jstat = 1; 32084 } 32085 32086 32087 /***** Recursion. *****/ 32088 32089 if (kdiv1 == 0) /* Only second object subdivided. */ 32090 for (ki = 0; ki < (kdiv2 < 3 ? 2 : 4); ki++) 32091 { 32092 /***** Treating edges on sub problems. *****/ 32093 32094 /* Making new edge object to sub problems. */ 32095 32096 if (po1->iobj == SISLPOINT) 32097 uedge[0] = SISL_NULL; 32098 else if ((uedge[0] = newEdge (vedge[0]->iedge)) == SISL_NULL) 32099 goto err101; 32100 if ((uedge[1] = newEdge (vedge[1]->iedge)) == SISL_NULL) 32101 goto err101; 32102 32103 /* Update edge intersection on sub problems. */ 32104 32105 sh6idalledg (po1, uob2[ki], *pintdat, uedge, &kstat); 32106 if (kstat < 0) 32107 goto error; 32108 32109 at_bottom = FALSE; 32110 kstat = (kxintercept) ? 202 : 0; 32111 sh1762 (po1, uob2[ki], aepsge, pintdat, uedge, &kstat); 32112 if (kstat < 0) 32113 goto error; 32114 else 32115 *jstat = *jstat || kstat; 32116 32117 if (uedge[0] != SISL_NULL) 32118 freeEdge (uedge[0]); 32119 if (uedge[1] != SISL_NULL) 32120 freeEdge (uedge[1]); 32121 } 32122 else if (kdiv2 == 0) /* Only first object subdivided. */ 32123 for (ki = 0; ki < (kdiv1 < 3 ? 2 : 4); ki++) 32124 { 32125 /***** Treating edges on sub problems. *****/ 32126 32127 /* Making new edge object to sub problems. */ 32128 32129 if ((uedge[0] = newEdge (vedge[0]->iedge)) == SISL_NULL) 32130 goto err101; 32131 if (po2->iobj == SISLPOINT) 32132 uedge[1] = SISL_NULL; 32133 else if ((uedge[1] = newEdge (vedge[1]->iedge)) == SISL_NULL) 32134 goto err101; 32135 32136 /* Update edge intersection on sub problems. */ 32137 32138 sh6idalledg (uob1[ki], po2, *pintdat, uedge, &kstat); 32139 if (kstat < 0) 32140 goto error; 32141 32142 at_bottom = FALSE; 32143 kstat = (kxintercept) ? 202 : 0; 32144 sh1762 (uob1[ki], po2, aepsge, pintdat, uedge, &kstat); 32145 if (kstat < 0) 32146 goto error; 32147 else 32148 *jstat = *jstat || kstat; 32149 32150 if (uedge[0] != SISL_NULL) 32151 freeEdge (uedge[0]); 32152 if (uedge[1] != SISL_NULL) 32153 freeEdge (uedge[1]); 32154 } 32155 else /* Both objects subdivided. */ 32156 for (ki1 = 0; ki1 < (kdiv1 < 3 ? 2 : 4); ki1++) 32157 for (ki2 = 0; ki2 < (kdiv2 < 3 ? 2 : 4); ki2++) 32158 { 32159 /***** Treating edges on sub problems. *****/ 32160 32161 /* Making new edge object to sub problems. */ 32162 32163 if ((uedge[0] = newEdge (vedge[0]->iedge)) == SISL_NULL) 32164 goto err101; 32165 if ((uedge[1] = newEdge (vedge[1]->iedge)) == SISL_NULL) 32166 goto err101; 32167 32168 /* Update edge intersection on sub problems. */ 32169 32170 sh6idalledg (uob1[ki1], uob2[ki2], *pintdat, uedge, &kstat); 32171 if (kstat < 0) 32172 goto error; 32173 32174 32175 at_bottom = FALSE; 32176 kstat = (kxintercept) ? 202 : 0; 32177 sh1762 (uob1[ki1], uob2[ki2], aepsge, pintdat, uedge, &kstat); 32178 if (kstat < 0) 32179 goto error; 32180 else 32181 *jstat = *jstat || kstat; 32182 32183 if (uedge[0] != SISL_NULL) 32184 freeEdge (uedge[0]); 32185 if (uedge[1] != SISL_NULL) 32186 freeEdge (uedge[1]); 32187 } 32188 } 32189 } 32190 } 32191 32192 32193 /* Must update vedge before going into reex */ 32194 /* if (vedge[0] != SISL_NULL) 32195 { 32196 knedge1 = vedge[0]->iedge; 32197 freeEdge (vedge[0]); 32198 if ((vedge[0] = newEdge (knedge1)) == SISL_NULL) 32199 goto err101; 32200 } 32201 if (vedge[1] != SISL_NULL) 32202 { 32203 knedge2 = vedge[1]->iedge; 32204 freeEdge (vedge[1]); 32205 if ((vedge[1] = newEdge (knedge2)) == SISL_NULL) 32206 goto err101; 32207 }*/ 32208 32209 /* Making new edge object to sub problems. */ 32210 32211 32212 /* sh6idalledg (po1, po2, *pintdat, vedge, &kstat); 32213 if (kstat < 0) 32214 goto error; */ 32215 32216 32217 /* UPDATE (ujk): s9reex must be changed, interface = ? 32218 Now it connects points on edge when they are 32219 connected to an internal point ?*/ 32220 /* Now changed! ALA and MSF. */ 32221 32222 /* UJK, VSK, ALA, 09.02.93, don't need it any longer !? */ 32223 /* sh1762_s9reex (po1, po2, vedge, aepsge, *pintdat, &kstat); 32224 if (kstat < 0) 32225 goto error; */ 32226 32227 /* VSK, 10.92. Set status if reex takes action. */ 32228 32229 /* *jstat = MAX(*jstat,kstat); 32230 32231 if (debug_flag && kstat) 32232 printf("\n Output reex: %d \n",kstat); */ 32233 32234 /* Reduction rules */ 32235 32236 sh6red (po1, po2, (*pintdat), &kstat); 32237 32238 /* Make help points and pretopology at bottom */ 32239 32240 if (at_bottom) 32241 shmkhlppts (po1, po2, aepsge, pintdat, vedge, &knewpt, &kstat); 32242 32243 /* UJK, aug.92, If we make help points, status must be set !, 32244 are there other updating statuses that we've missed ? */ 32245 if (knewpt) *jstat = 1; 32246 32247 /* Intersections in the inner found. */ 32248 32249 goto out; 32250 32251 /* Error in space allocation. */ 32252 32253 err101:*jstat = -101; 32254 s6err ("sh1762", *jstat, kpos); 32255 goto out; 32256 32257 /* Error in lower level routine. */ 32258 32259 error:*jstat = kstat; 32260 s6err ("sh1762", *jstat, kpos); 32261 goto out; 32262 32263 /* Free the space that is allocated. */ 32264 32265 out: 32266 for (ki = 0; ki < 4; ki++) 32267 { 32268 if (uob1[ki] != SISL_NULL) 32269 freeObject (uob1[ki]); 32270 if (uob2[ki] != SISL_NULL) 32271 freeObject (uob2[ki]); 32272 } 32273 sh1762_xc--; 32274 } 32275 32276 //=========================================================================== 32277 void sh1762_s9mic (SISLObject * po1, SISLObject * po2, SISLIntdat ** rintdat, 32278 SISLEdge ** vedge[], int *jstat) 32279 //=========================================================================== 32280 { 32281 int kpos = 0; /* Position of error. */ 32282 int kstat = 0; /* Local error status. */ 32283 int knum = 0; /* Number of intpt on edges. */ 32284 /*int klist1, klist2; */ /* List index in iintpt. */ 32285 int ind1, ind2; /* Help index in up array. */ 32286 double *spar = SISL_NULL; /* Array to store parameter values. */ 32287 SISLIntpt **up = SISL_NULL; /* Array of poiners to intersection point. */ 32288 double *nullp = SISL_NULL; 32289 double tepsge = 0.0000001; /* Tolerance used in merging of points. */ 32290 32291 /* Initiate to no new intersection point. */ 32292 32293 *jstat = 0; 32294 32295 /* Compute number of intersection points on edges. */ 32296 32297 if ((*vedge)[0] == SISL_NULL) 32298 knum = 0; 32299 else 32300 knum = (*vedge)[0]->ipoint; 32301 32302 if ((*vedge)[1] != SISL_NULL) 32303 knum += (*vedge)[1]->ipoint; 32304 32305 32306 if (knum > 0) 32307 { 32308 /* sh1762_s9edgpoint ((*vedge), &up, &knum, &kstat); */ 32309 sh6edgpoint ((*vedge), &up, &knum, &kstat); 32310 if (kstat < 0) 32311 goto error; 32312 } 32313 32314 32315 if (knum > 1) 32316 { 32317 int kturn, ki; 32318 32319 /* We have more than one intersection point on the edges, 32320 we therefor have to treat these problem. */ 32321 32322 if ((po1->iobj == SISLPOINT && po1->p1->idim <= 2) || 32323 (po2->iobj == SISLPOINT && po2->p1->idim <= 2) || 32324 (po1->iobj == SISLCURVE && po2->iobj == SISLPOINT && knum == 2) || 32325 (po1->iobj == SISLPOINT && po2->iobj == SISLCURVE && knum == 2)) 32326 { 32327 SISLObject *qo1, *qo2; 32328 32329 /* In dimension one and two this function is not 32330 a degenenerate treatment function, it is a coincidence 32331 function. */ 32332 32333 if (po1->iobj == SISLPOINT) 32334 { 32335 qo1 = po1; 32336 qo2 = po2; 32337 kturn = 0; 32338 } 32339 else 32340 { 32341 qo2 = po1; 32342 qo1 = po2; 32343 kturn = 1; 32344 } 32345 32346 if (qo2->iobj == SISLSURFACE) 32347 { 32348 32349 /* Trim area found */ 32350 for (ki=0; ki<(*rintdat)->ipoint; ki++) 32351 { 32352 sh6isinside(po1,po2,(*rintdat)->vpoint[ki],&kstat); 32353 if (kstat < 0) goto error; 32354 if (kstat) 32355 { 32356 sh6tomain((*rintdat)->vpoint[ki], &kstat); 32357 if (kstat < 0) goto error; 32358 (*rintdat)->vpoint[ki]->iinter = SI_TRIM; 32359 } 32360 } 32361 32362 /* UJK 18.09.90 Must set intersection found status */ 32363 *jstat = 1; 32364 goto out; 32365 32366 } 32367 else if (qo2->iobj == SISLCURVE && knum == 2) 32368 { 32369 double tres; 32370 32371 tres = (qo2->c1->et[qo2->c1->in] - 32372 qo2->c1->et[qo2->c1->ik - 1]) / 32373 (qo2->o1->c1->et[qo2->o1->c1->in] - 32374 qo2->o1->c1->et[qo2->o1->c1->ik - 1]); 32375 32376 if (tres > REL_PAR_RES) 32377 { 32378 /* UJK newi :Main points, curve point 1+2D, connect */ 32379 sh6idcon (rintdat, up, up + 1, &kstat); 32380 if (kstat < 0) 32381 goto error; 32382 /* Sort points */ 32383 ind1 = 0; 32384 ind2 = 1; 32385 if (up[0]->epar[0] > up[1]->epar[0]) 32386 { 32387 ind1 = 1; 32388 ind2 = 0; 32389 } 32390 sh6setdir (up[ind1], up[ind2], &kstat); 32391 if (kstat < 0) 32392 goto error; 32393 32394 32395 32396 /* Set pretopology */ 32397 /* No, it's there already */ 32398 32399 /* ind1 = 1; 32400 ind2 = 0; 32401 if (up[0]->epar[0] < up[1]->epar[0]) 32402 { 32403 ind1 = 0; 32404 ind2 = 1; 32405 } 32406 32407 sh6getlist (up[ind1], up[ind2], &klist1, &klist2, &kstat); 32408 if (kstat != 0) 32409 { 32410 kstat = -1; 32411 goto error; 32412 } 32413 if (kturn) 32414 { 32415 sh6settop (up[ind1], -1, 32416 SI_AT, SI_ON, SI_UNDEF, SI_ON, &kstat); 32417 if (kstat < 0) 32418 goto error; 32419 sh6settop (up[ind2], -1, 32420 SI_ON, SI_AT, SI_ON, SI_UNDEF, &kstat); 32421 if (kstat < 0) 32422 goto error; 32423 } 32424 else 32425 { 32426 sh6settop (up[ind1], -1, 32427 SI_UNDEF, SI_ON, SI_AT, SI_ON, &kstat); 32428 if (kstat < 0) 32429 goto error; 32430 sh6settop (up[ind2], -1, 32431 SI_ON, SI_UNDEF, SI_ON, SI_AT, &kstat); 32432 if (kstat < 0) 32433 goto error; 32434 } 32435 32436 */ 32437 32438 /* UJK 18.09.90 Must set intersection found status */ 32439 *jstat = 1; 32440 goto out; 32441 } 32442 } 32443 } 32444 32445 32446 /* VSK to treat degenerated curves. */ 32447 32448 if (po1->iobj == SISLCURVE && po2->iobj == SISLCURVE && knum >= 2) 32449 { 32450 /* The two curves is within a microbox. The intersection will 32451 be represented with two points that are connectd. Merge 32452 the rest of the points into one of the two remaining. */ 32453 32454 for (ki=1; ki<knum-1; ki++) 32455 { 32456 sh6idnewunite(po1,po2,rintdat,&up[0],&up[ki],DZERO, 32457 tepsge,&kstat); 32458 if (kstat < 0) goto error; 32459 } 32460 32461 sh6connect(up[0],up[knum-1],&kstat); 32462 if (kstat < 0) goto error; 32463 32464 /* Update edge structure. */ 32465 32466 if ((*vedge)[0] != SISL_NULL) 32467 { 32468 ki = (*vedge)[0]->iedge; 32469 freeEdge ((*vedge)[0]); 32470 (*vedge)[0] = SISL_NULL; 32471 if (((*vedge)[0] = newEdge (ki)) == SISL_NULL) 32472 goto err101; 32473 } 32474 if ((*vedge)[1] != SISL_NULL) 32475 { 32476 ki = (*vedge)[1]->iedge; 32477 freeEdge ((*vedge)[1]); 32478 (*vedge)[1] = SISL_NULL; 32479 if (((*vedge)[1] = newEdge (ki)) == SISL_NULL) 32480 goto err101; 32481 } 32482 32483 sh6idalledg (po1, po2, *rintdat, *vedge, &kstat); 32484 if (kstat < 0) 32485 goto error; 32486 32487 *jstat = 1; 32488 goto out; 32489 } 32490 32491 /* We have more than one intersection point on the edges. 32492 We therefor kill these points and 32493 try to find a new intersection point. */ 32494 32495 32496 32497 for (ki = 1; ki < knum; ki++) 32498 { 32499 /* UJK newi, unite the points : */ 32500 sh6idnewunite (po1, po2, rintdat, &up[0], &up[ki], (double) 0.5, 32501 tepsge, &kstat); 32502 if (kstat < 0) 32503 goto error; 32504 } 32505 32506 if ((*vedge)[0] != SISL_NULL) 32507 { 32508 ki = (*vedge)[0]->iedge; 32509 freeEdge ((*vedge)[0]); 32510 if (((*vedge)[0] = newEdge (ki)) == SISL_NULL) 32511 goto err101; 32512 } 32513 if ((*vedge)[1] != SISL_NULL) 32514 { 32515 ki = (*vedge)[1]->iedge; 32516 freeEdge ((*vedge)[1]); 32517 if (((*vedge)[1] = newEdge (ki)) == SISL_NULL) 32518 goto err101; 32519 } 32520 /* UJK newi, one point kept : */ 32521 knum = 1; 32522 } 32523 32524 32525 32526 if (knum == 0) 32527 { 32528 int kpar = 0; 32529 SISLIntpt *qt; 32530 32531 32532 /* There is no intersection points on the edges. 32533 We therfore make one new intersection point with parameter 32534 values in senter of each object. */ 32535 32536 32537 /* Number of parameter values of object 1. */ 32538 32539 if (po1->iobj == SISLCURVE) 32540 kpar = 1; 32541 else if (po1->iobj == SISLSURFACE) 32542 kpar = 2; 32543 else 32544 kpar = 0; 32545 32546 /* Number of parameter values of object 2. */ 32547 32548 if (po2->iobj == SISLCURVE) 32549 kpar++; 32550 else if (po2->iobj == SISLSURFACE) 32551 kpar += 2; 32552 32553 32554 /* Allocate array to store midpoint parameter values. */ 32555 32556 if ((spar = newarray (kpar, double)) == SISL_NULL) 32557 goto err101; 32558 32559 32560 /* Compute midpoint parameter values. */ 32561 32562 if (po1->iobj == SISLCURVE) 32563 { 32564 spar[0] = (po1->c1->et[po1->c1->ik - 1] + 32565 po1->c1->et[po1->c1->in]) * (double) 0.5; 32566 kpar = 1; 32567 } 32568 else if (po1->iobj == SISLSURFACE) 32569 { 32570 spar[0] = (po1->s1->et1[po1->s1->ik1 - 1] + 32571 po1->s1->et1[po1->s1->in1]) * (double) 0.5; 32572 spar[1] = (po1->s1->et2[po1->s1->ik2 - 1] + 32573 po1->s1->et2[po1->s1->in2]) * (double) 0.5; 32574 kpar = 2; 32575 } 32576 else 32577 kpar = 0; 32578 32579 if (po2->iobj == SISLCURVE) 32580 { 32581 spar[kpar] = (po2->c1->et[po2->c1->ik - 1] + 32582 po2->c1->et[po2->c1->in]) * (double) 0.5; 32583 kpar++; 32584 } 32585 else if (po2->iobj == SISLSURFACE) 32586 { 32587 spar[kpar] = (po2->s1->et1[po2->s1->ik1 - 1] + 32588 po2->s1->et1[po2->s1->in1]) * (double) 0.5; 32589 spar[kpar + 1] = (po2->s1->et2[po2->s1->ik2 - 1] + 32590 po2->s1->et2[po2->s1->in2]) * (double) 0.5; 32591 kpar += 2; 32592 } 32593 32594 *jstat = 1; /* Mark intersection found. */ 32595 32596 32597 /* Making intersection point. */ 32598 /* UJK newi */ 32599 /* UPDATE: ? Be aware of this situation, can it occur ? */ 32600 32601 qt = hp_newIntpt (kpar, spar, DZERO, SI_ORD, 32602 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 32603 0, 0, nullp, nullp); 32604 if (qt == SISL_NULL) 32605 goto err101; 32606 32607 /* Uppdating pintdat. */ 32608 32609 sh6idnpt (rintdat, &qt, 1, &kstat); 32610 if (kstat < 0) 32611 goto error; 32612 } 32613 32614 goto out; 32615 32616 /* Error in space allocation. */ 32617 32618 err101:*jstat = -101; 32619 s6err ("sh1762_s9mic", *jstat, kpos); 32620 goto out; 32621 32622 /* Error in lower level routine. */ 32623 32624 error:*jstat = kstat; 32625 s6err ("sh1762_s9mic", *jstat, kpos); 32626 goto out; 32627 32628 out:if (spar != SISL_NULL) 32629 freearray (spar); 32630 if (up != SISL_NULL) 32631 freearray (up); 32632 } 32633 32634 //=========================================================================== 32635 double sh1762_sflength(SISLSurf *psurf, int idir, int *jstat) 32636 //=========================================================================== 32637 { 32638 int kstat = 0; 32639 int kleft1 = 0, kleft2 = 0; 32640 int ki; 32641 int kdim = psurf->idim; 32642 double spar[2]; /* Parameter value in which to evaluate. */ 32643 double sint[2]; /* Interval between parameter values. */ 32644 double sder[12]; /* Points on the surface. */ 32645 int kneval; /* Number of points to evaluate. */ 32646 double tlength = 0.0; /* Estimated length of surface. */ 32647 32648 kneval = (idir == 1) ? psurf->ik1 : psurf->ik2; 32649 kneval = max(2, min(kneval, 4)); 32650 32651 /* Set first parameter in which to evaluate. */ 32652 if (idir == 1) 32653 { 32654 spar[0] = psurf->et1[psurf->ik1-1]; 32655 spar[1] = (double)0.5*(psurf->et2[psurf->ik2-1]+psurf->et2[psurf->in2]); 32656 32657 sint[0] = (psurf->et1[psurf->in1] - spar[0])/(double)(kneval-1); 32658 sint[1] = 0.0; 32659 } 32660 else 32661 { 32662 spar[0] = (double)0.5*(psurf->et1[psurf->ik1-1]+psurf->et1[psurf->in1]); 32663 spar[1] = psurf->et2[psurf->ik2-1]; 32664 32665 sint[0] = 0.0; 32666 sint[1] = (psurf->et2[psurf->in2] - spar[1])/(double)(kneval-1); 32667 } 32668 32669 /* Evaluate points. */ 32670 32671 for (ki=0; ki<kneval; ki++, spar[0]+=sint[0], spar[1]+=sint[1]) 32672 { 32673 s1424(psurf, 0, 0, spar, &kleft1, &kleft2, sder+ki*kdim, &kstat); 32674 if (kstat < 0) 32675 goto error; 32676 } 32677 32678 /* Compute the distance between the points. */ 32679 32680 for (tlength=0.0, ki=1; ki<kneval; ki++) 32681 tlength += s6dist(sder+(ki-1)*kdim, sder+ki*kdim, kdim); 32682 32683 *jstat = 0; 32684 goto out; 32685 32686 /* Error in lower level routine. */ 32687 error: 32688 *jstat = kstat; 32689 s6err ("sh1762_sflength", *jstat, 0); 32690 goto out; 32691 32692 out: 32693 return tlength; 32694 } 32695 32696 //=========================================================================== 32697 void sh1762_s9num (SISLObject * po, SISLObject * poref, int *jdiv, int *jstat) 32698 //=========================================================================== 32699 { 32700 int kstat = 0; 32701 int kgtpi1=0, kgtpi2=0; 32702 double tang1=DZERO, tang2=DZERO; 32703 int not_case_2d; 32704 int kbez1=1, kbez2=1; 32705 32706 /* Init. */ 32707 32708 *jdiv = 0; 32709 32710 if (po->iobj < SISLPOINT || po->iobj > SISLSURFACE) 32711 goto err121; 32712 if (poref->iobj < SISLPOINT || poref->iobj > SISLSURFACE) 32713 goto err121; 32714 32715 if (po->iobj == SISLPOINT) 32716 goto out; 32717 32718 kgtpi1 = 10; 32719 tang1 = HUGE; 32720 32721 kgtpi2 = 0; 32722 tang2 = (double) 0.0; /* VSK. 030394. Changed tang1 into tang2. */ 32723 32724 /* Get attributes from object to divide. */ 32725 if (po->iobj == SISLCURVE) 32726 { 32727 if (po->c1->pdir != SISL_NULL) 32728 { 32729 kgtpi1 = po->c1->pdir->igtpi; 32730 tang1 = po->c1->pdir->aang; 32731 } 32732 kbez1 = (po->c1->ik == po->c1->in); 32733 } 32734 else 32735 { 32736 if (po->s1->pdir != SISL_NULL) 32737 { 32738 kgtpi1 = po->s1->pdir->igtpi; 32739 tang1 = po->s1->pdir->aang; 32740 } 32741 kbez1 = (po->s1->ik1 == po->s1->in1 && po->s1->ik2 == po->s1->in2); 32742 } 32743 32744 /* Get attributes from referance object. */ 32745 if (poref->iobj == SISLCURVE) 32746 { 32747 if (poref->c1->pdir != SISL_NULL) 32748 { 32749 kgtpi2 = poref->c1->pdir->igtpi; 32750 tang2 = poref->c1->pdir->aang; 32751 } 32752 kbez2 = (poref->c1->ik == poref->c1->in); 32753 } 32754 else if (poref->iobj == SISLSURFACE) 32755 { 32756 if (poref->s1->pdir != SISL_NULL) 32757 { 32758 kgtpi2 = poref->s1->pdir->igtpi; 32759 tang2 = poref->s1->pdir->aang; 32760 } 32761 kbez2 = (poref->s1->ik1 == poref->s1->in1 && 32762 poref->s1->ik2 == poref->s1->in2); 32763 } 32764 32765 if (poref->iobj == SISLPOINT && poref->p1->idim == 2) 32766 not_case_2d = FALSE; 32767 else 32768 not_case_2d = TRUE; 32769 32770 32771 /* Test for number of division directions. */ 32772 /*---------------------------------------------*/ 32773 /* If linear, we do not subdivide. */ 32774 if (kgtpi1 == 0 && tang1 <= ANGULAR_TOLERANCE/10.0 && not_case_2d) 32775 *jdiv = 0; 32776 32777 else if (po->iobj == SISLCURVE && poref->iobj == SISLSURFACE) 32778 /* Subdivide curve. */ 32779 { 32780 if (s1791 (po->c1->et, po->c1->ik, po->c1->in)) 32781 *jdiv = 1; 32782 32783 else 32784 *jdiv = 0; 32785 32786 } 32787 32788 else if (kgtpi1 == 0 && tang1 < SIMPLECASE / (double) 2.0 && kbez1 == 1 && 32789 (kgtpi2 != 0 || tang2 > tang1 * (double) 2.0)) 32790 *jdiv = 0; 32791 32792 else if (po->iobj == SISLCURVE) 32793 { 32794 if (s1791 (po->c1->et, po->c1->ik, po->c1->in)) 32795 *jdiv = 1; 32796 32797 else 32798 *jdiv = 0; 32799 } 32800 else if (po->iobj == SISLSURFACE) 32801 { 32802 double tsfp1, tsfp2, tref; 32803 tref = 5.0; 32804 32805 tsfp1 = sh1762_sflength(po->s1, 1, &kstat); 32806 if (kstat < 0) 32807 goto error; 32808 32809 tsfp2 = sh1762_sflength(po->s1, 2, &kstat); 32810 if (kstat < 0) 32811 goto error; 32812 32813 if (s1791 (po->s1->et1, po->s1->ik1, po->s1->in1) && 32814 !(po->s1->ik1 == 2 && tsfp1 < tref*tsfp2)) 32815 *jdiv = 1; 32816 32817 else 32818 *jdiv = 0; 32819 32820 if (s1791 (po->s1->et2, po->s1->ik2, po->s1->in2) && 32821 !(po->s1->ik2 == 2 && tsfp2 < tref*tsfp1)) 32822 *jdiv += 2; 32823 32824 } 32825 goto out; 32826 32827 32828 /* Error in lower level routine. */ 32829 error: 32830 *jstat = kstat; 32831 s6err ("sh1762_s9num", *jstat, 0); 32832 goto out; 32833 32834 /* Error. Kind of object does not exist. */ 32835 err121: 32836 *jstat = -121; 32837 s6err ("sh1762_s9num", *jstat, 0); 32838 32839 out:; 32840 } 32841 32842 //=========================================================================== 32843 int sh1762_is_taboo(SISLSurf *psurf1, SISLSurf *psurf2, SISLIntpt *pintpt, 32844 int idir, int *jstat) 32845 //=========================================================================== 32846 { 32847 static double parallel = 0.01; 32848 static double fuzzy_angle = 1e-4; 32849 static double tol = (double) 1000000.0 * REL_COMP_RES; 32850 32851 int kstat = 0; 32852 int is_taboo = 0; 32853 double derivs1[9], derivs2[9], norm[3], nor1[3], nor2[3], angle; 32854 double abs_tang1[2], abs_tang2[2]; 32855 double tmax; 32856 int ilfs = 0, ilft = 0; 32857 32858 if (psurf1->idim == 2) 32859 return 0; 32860 32861 /* Test input. */ 32862 32863 if (psurf2 && (psurf1->idim != psurf2->idim || psurf1->idim != 3)) 32864 goto err104; 32865 32866 if (!psurf2 && psurf1->idim != 1) 32867 goto err105; 32868 32869 if (psurf2) 32870 { 32871 /* Evaluate the intersection point in both surfaces. */ 32872 32873 s1421(psurf1, 1, &pintpt->epar[0], &ilfs, &ilft, derivs1, norm, &kstat); 32874 if (kstat < 0) 32875 goto error; 32876 32877 s1421(psurf2, 1, &pintpt->epar[2], &ilfs, &ilft, derivs2, norm, jstat); 32878 if (kstat < 0) 32879 goto error; 32880 32881 s6crss(derivs2+3, derivs2+6, nor2); 32882 s6crss(derivs1+3, derivs1+6, nor1); 32883 32884 /* If we have a singularity, we don't declare it as taboo. */ 32885 32886 angle = s6ang(nor1, nor2, 3); 32887 32888 abs_tang1[0] = fabs(s6scpr(derivs1+6, nor2, 3)); 32889 abs_tang1[1] = fabs(s6scpr(derivs1+3, nor2, 3)); 32890 32891 abs_tang2[0] = fabs(s6scpr(nor1, derivs2+6, 3)); 32892 abs_tang2[1] = fabs(s6scpr(nor1, derivs2+3, 3)); 32893 32894 if (angle < fuzzy_angle) 32895 is_taboo = 0; 32896 else if (idir == 1 && abs_tang1[0] < parallel*abs_tang1[1]) 32897 is_taboo = 1; 32898 else if (idir == 2 && abs_tang1[1] < parallel*abs_tang1[0]) 32899 is_taboo = 1; 32900 else 32901 is_taboo = 0; 32902 } 32903 else 32904 { 32905 /* Evaluate the intersection point. */ 32906 32907 s1421(psurf1, 1, &pintpt->epar[0], &ilfs, &ilft, derivs1, norm, &kstat); 32908 if (kstat < 0) 32909 goto error; 32910 32911 /* If we have a singularity, we don't declare it as taboo. */ 32912 32913 tmax = sqrt(derivs1[1]*derivs1[1] + derivs1[2]*derivs1[2]); 32914 if (tmax < tol) 32915 /* The length of the surface normal is less than the 32916 given tolerance*/ 32917 is_taboo = 0; 32918 32919 else if (idir == 1 && fabs(derivs1[2]) < parallel*tmax) 32920 is_taboo = 1; 32921 else if (idir == 2 && fabs(derivs1[1]) < parallel*tmax) 32922 is_taboo = 1; 32923 else 32924 is_taboo = 0; 32925 } 32926 32927 *jstat = 0; 32928 goto out; 32929 32930 /* Error in lower order routine. */ 32931 error: 32932 *jstat = kstat; 32933 s6err ("sh1762_is_taboo", *jstat, 0); 32934 goto out; 32935 32936 /* Error. Dimension not equal to 3. */ 32937 err104: 32938 *jstat = -104; 32939 s6err ("sh1762_is_taboo", *jstat, 0); 32940 goto out; 32941 32942 /* Error. Conflicting dimensions. */ 32943 err105: 32944 *jstat = -105; 32945 s6err ("sh1762_is_taboo", *jstat, 0); 32946 goto out; 32947 32948 out: 32949 return is_taboo; 32950 } 32951 32952 //=========================================================================== 32953 void sh1762_s9subdivpt (SISLObject * po1, SISLObject * po2, double aepsge, 32954 int iobj, int idiv, SISLEdge * vedge[], SISLIntdat ** pintdat, 32955 int *fixflag, SISLIntpt ** rpt, double epar[], int *jstat) 32956 //=========================================================================== 32957 { 32958 int kstat = 0; 32959 int kpos = 0; 32960 int kpar; /* First index of subdivision point in the 32961 parameter value of in intersection point. */ 32962 int kfound = 0; /* Indicates if in intersection point / extremal 32963 point is to be used. */ 32964 int kf1=0, kf2=0; /* Indicates if an internal intersection point is 32965 legal in the parameter directions of a surface. */ 32966 double tdel; /* Parameter used to measure closeness to an edge. */ 32967 double tdel1, tdel2; /* Parameters used to measure closeness to an edge. */ 32968 double tstart, tend; /* Endparameters of curve. */ 32969 double tstart2, tend2; /* Endparameters of second curve. */ 32970 double tpar; /* Parameter value of subdivision point. */ 32971 double tpar2; /* Parameter value of point from iteration. */ 32972 double sstart[2], send[2]; /* Endparameters of surface. */ 32973 double spar[2]; /* Parameter value of subdivision point. */ 32974 double spar2[2]; /* Parameter value of subdivision point. */ 32975 double sparsave[2]; /* Parameter value of subdivision point. */ 32976 SISLObject *qo1; /* Pointer to the object that is to be subdivided. */ 32977 SISLObject *qo2; /* Pointer to the other object. */ 32978 SISLIntpt *qpt = SISL_NULL; /* An internal intersection point. */ 32979 32980 /* Set pointer to subdivision object. */ 32981 32982 qo1 = (iobj == 1 ? po1 : po2); 32983 qo2 = (iobj == 1 ? po2 : po1); 32984 kpar = (iobj == 1 ? 0 : po1->iobj); 32985 32986 *jstat = 0; 32987 32988 /* Branch on subdivision object. */ 32989 32990 if (qo1->iobj == SISLCURVE) 32991 { 32992 /* Find a proper subdivision value of the curve. First set when a point 32993 is to close to an edge to be used as a subdivision point. */ 32994 32995 tdel = (double) 0.01 *(qo1->c1->et[qo1->c1->in] - 32996 qo1->c1->et[qo1->c1->ik - 1]); 32997 32998 /* Try to find an internal intersection point. */ 32999 33000 s6idint (po1, po2, *pintdat, &qpt, iobj); 33001 if (!(3*qo1->c1->ik > qo1->c1->in) && 33002 /* if (qo1->c1->ik != qo1->c1->in && */ 33003 (sh6ismain (qpt)) && sh6nmbhelp (qpt,&kstat) == 0) 33004 qpt = SISL_NULL; 33005 33006 if (qpt != SISL_NULL) 33007 { 33008 /* Internal intersection point found. */ 33009 33010 tpar = qpt->epar[kpar]; 33011 33012 if (tpar < (qo1->c1->et[qo1->c1->ik - 1] + tdel) || 33013 tpar > (qo1->c1->et[qo1->c1->in] -tdel)) 33014 qpt = SISL_NULL; /* Do not use the point as a subdivision point. */ 33015 } 33016 33017 if (qpt == SISL_NULL && 33018 vedge[iobj - 1]->ipoint == 0 && qo1->c1->ik == qo1->c1->in) 33019 { 33020 /* No internal intersection is found. The curve is of Bezier type, 33021 and there is no intersection on the endpoints of the curve. 33022 Then we try to iterate in order to find an intersection or 33023 closest point to use as a subdivision point. Branch on the 33024 various kind of other objects involved in the intersection. */ 33025 33026 tstart = qo1->c1->et[qo1->c1->ik - 1]; 33027 tend = qo1->c1->et[qo1->c1->in]; 33028 tpar = (tstart + tend) * (double) 0.5; 33029 kfound = 1; 33030 33031 if (qo2->iobj == SISLPOINT) 33032 { 33033 /* ALA & UJK start 31/10/90. */ 33034 if (qo2->p1->idim == 1) 33035 s1172 (qo1->o1->c1, tstart, tend, 33036 tpar, &tpar, &kstat); 33037 else 33038 { 33039 kstat = 1; /* Use quick iteration. */ 33040 s1771 (qo2->o1->p1, qo1->o1->c1, aepsge, tstart, tend, 33041 tpar, &tpar, &kstat); 33042 } 33043 if (kstat < 0) 33044 goto error; 33045 } 33046 33047 else if (qo2->iobj == SISLCURVE) 33048 { 33049 tstart2 = qo2->c1->et[qo2->c1->ik - 1]; 33050 tend2 = qo2->c1->et[qo2->c1->in]; 33051 tpar2 = (tstart + tend) * (double) 0.5; 33052 tdel2 = (double)0.01*(tend - tstart); 33053 33054 s1770 (qo1->o1->c1, qo2->o1->c1, aepsge, tstart, tstart2, tend, 33055 tend2, tpar, tpar2, &tpar, &tpar2, &kstat); 33056 if (kstat < 0) 33057 goto error; 33058 33059 /* Test the subdivision point towards the endpoint of the 33060 second curve. */ 33061 33062 if (tpar2 < tstart2+tdel2 || tpar2 > tend2-tdel2) 33063 kfound = 0; 33064 } 33065 33066 else if (qo2->iobj == SISLSURFACE) 33067 { 33068 sstart[0] = qo2->s1->et1[qo2->s1->ik1 - 1]; 33069 sstart[1] = qo2->s1->et2[qo2->s1->ik2 - 1]; 33070 33071 send[0] = qo2->s1->et1[qo2->s1->in1]; 33072 send[1] = qo2->s1->et2[qo2->s1->in2]; 33073 33074 spar[0] = (sstart[0] + send[0]) * (double) 0.5; 33075 spar[1] = (sstart[1] + send[1]) * (double) 0.5; 33076 33077 tdel1 = (double)0.01* (send[0] - sstart[0]); 33078 tdel2 = (double)0.01* (send[1] - sstart[1]); 33079 33080 kstat = 1; /* Use quick iteration. */ 33081 s1772 (qo1->o1->c1, qo2->o1->s1, aepsge, tstart, sstart, tend, 33082 send, tpar, spar, &tpar, spar, &kstat); 33083 if (kstat < 0) 33084 goto error; 33085 33086 /* Test the subdivision point towards the edges of the surface. */ 33087 33088 if (spar[0] < sstart[0]+tdel1 || spar[0] > send[0]-tdel1 || 33089 spar[1] < sstart[1]+tdel2 || spar[1] > send[1]-tdel2) 33090 kfound = 0; 33091 } 33092 33093 /* Test the subdivision point towards the edges of the subdivision 33094 curve. */ 33095 33096 if (!kfound || 33097 tpar < tstart+tdel || tpar > tend-tdel) 33098 33099 /* Use the midpoint of the curve as subdivision point. */ 33100 33101 tpar = s1792 (qo1->c1->et, qo1->c1->ik, qo1->c1->in); 33102 } 33103 else if (qpt == SISL_NULL) 33104 /* Use the midpoint as a subdivision point. */ 33105 33106 tpar = s1792 (qo1->c1->et, qo1->c1->ik, qo1->c1->in); 33107 33108 /* Set output variables */ 33109 33110 epar[0] = tpar; 33111 *rpt = qpt; 33112 } 33113 else if (qo1->iobj == SISLSURFACE) 33114 { 33115 /* Find a subdivision point of the surface. Branch on the other 33116 object involved in the intersection. First set the endparameters 33117 of the surface and when a point is to close to an edge 33118 to be used as a subdivision point. */ 33119 33120 sstart[0] = qo1->s1->et1[qo1->s1->ik1 - 1]; 33121 sstart[1] = qo1->s1->et2[qo1->s1->ik2 - 1]; 33122 33123 send[0] = qo1->s1->et1[qo1->s1->in1]; 33124 send[1] = qo1->s1->et2[qo1->s1->in2]; 33125 33126 tdel1 = (double) 0.01 *(send[0] - sstart[0]); 33127 tdel2 = (double) 0.01 *(send[1] - sstart[1]); 33128 33129 /* In the Bezier case, search for an internal intersection point. */ 33130 33131 if (qo1->s1->ik1 == qo1->s1->in1 && qo1->s1->ik2 == qo1->s1->in2) 33132 s6idint (po1, po2, *pintdat, &qpt, iobj); 33133 if (qpt != SISL_NULL) 33134 { 33135 /* Internal intersection point found. */ 33136 sparsave[0] = spar[0] = qpt->epar[kpar]; 33137 sparsave[1] = spar[1] = qpt->epar[kpar + 1]; 33138 kf1 = kf2 = 1; 33139 33140 /* Test the point towards the edges of the surface. */ 33141 33142 if (spar[0] < sstart[0] + tdel1 || spar[0] > send[0] - tdel1) 33143 { 33144 kf1--; 33145 qpt = SISL_NULL; 33146 } 33147 if (spar[1] < sstart[1] + tdel2 || spar[1] > send[1] - tdel2) 33148 { 33149 kf2--; 33150 qpt = SISL_NULL; 33151 } 33152 } 33153 33154 kfound = 0; /* If no iteration is tryed, use the midpoint. */ 33155 if ((!qpt) && qo2->iobj != SISLSURFACE && 33156 !(qo2->iobj == SISLPOINT && qo2->p1->idim == 1) && 33157 qo1->s1->ik1 == qo1->s1->in1 && qo1->s1->ik2 == qo1->s1->in2) 33158 { 33159 /* No internal intersection is found. The second object is not a 33160 surface, and the subdivision surface is of Bezier type. 33161 Prepare for iteration. */ 33162 33163 spar[0] = (sstart[0] + send[0]) * (double) 0.5; 33164 spar[1] = (sstart[1] + send[1]) * (double) 0.5; 33165 kfound = 3; 33166 33167 if (qo2->iobj == SISLPOINT) 33168 { 33169 s1773 (qo2->o1->p1, qo1->o1->s1, aepsge, sstart, send, spar, 33170 spar, &kstat); 33171 if (kstat < 0) 33172 goto error; 33173 } 33174 33175 else if (qo2->iobj == SISLCURVE) 33176 { 33177 tstart = qo2->c1->et[qo2->c1->ik - 1]; 33178 tend = qo2->c1->et[qo2->c1->in]; 33179 tpar = (tstart + tend) * (double) 0.5; 33180 tdel = (double)0.01*(tend - tstart); 33181 33182 kstat = 1; 33183 s1772 (qo2->o1->c1, qo1->o1->s1, aepsge, tstart, sstart, 33184 tend, send, tpar, spar, &tpar, spar, &kstat); 33185 if (kstat < 0) 33186 goto error; 33187 33188 /* Control the edges of the curve. */ 33189 33190 if (tpar < tstart+tdel || tpar > tend-tdel) 33191 kfound = 0; 33192 } 33193 33194 /* Test the edges of the surface to be subdivided. */ 33195 33196 if (spar[0] < sstart[0]+tdel1 || spar[0] > send[0]-tdel1) 33197 kfound--; 33198 if (spar[1] < sstart[1]+tdel2 || spar[1] > send[1]-tdel2) 33199 kfound -= 2; 33200 } 33201 33202 if ((!qpt) && (!(kfound==3) && qo2->iobj != SISLSURFACE && 33203 !(qo2->iobj == SISLPOINT && qo2->p1->idim == 1))) 33204 { 33205 /* Use the midpoint of the surface as a subdivision point. */ 33206 33207 if (kfound != 1) 33208 spar[0] = s1792 (qo1->s1->et1, qo1->s1->ik1, qo1->s1->in1); 33209 if (kfound != 2) 33210 spar[1] = s1792 (qo1->s1->et2, qo1->s1->ik2, qo1->s1->in2); 33211 33212 /* Test if this subdivision point is too close to an existing 33213 inner intersection point. */ 33214 33215 if (kf1 && fabs(spar[0]-sparsave[0]) < tdel1) 33216 spar[0] = sparsave[0]; 33217 if (kf2 && fabs(spar[1]-sparsave[1]) < tdel2) 33218 spar[1] = sparsave[1]; 33219 } 33220 33221 if ((!qpt) && (qo2->iobj == SISLSURFACE || 33222 (qo2->iobj == SISLPOINT && 33223 (qo2->p1->idim == 1 || qo2->p1->idim == 2)))) 33224 { 33225 SISLPtedge *qptedg; /* Pointer used to traverse int. points on edges. */ 33226 SISLIntpt *pt1 = SISL_NULL; /* Intersection point on edge. */ 33227 SISLIntpt *pt2 = SISL_NULL; /* Intersection point on edge. */ 33228 SISLIntpt *ptsing1 = SISL_NULL; /* Singular intersection point on edge. */ 33229 SISLIntpt *ptsing2 = SISL_NULL; /* Singular intersection point on edge. */ 33230 SISLIntpt *pcurr; /* Current intersection point. */ 33231 int kj; /* Counter. */ 33232 double tmean[2]; /* Middle parameter of the surface. */ 33233 double tpar1=HUGE, tpar2=HUGE; /* Used for comparisement with 33234 intersection point. */ 33235 int ktype1=-10, ktype2=-10; /* As previous. */ 33236 33237 /* There is a surface-surface intersection or an intersection 33238 between a surface and a point in 1D. In both cases intersection 33239 curves are the expected output. Start by logging the intersection 33240 points at the edges. */ 33241 /* If the surface is almost a Bezier surface, make it Bezier. */ 33242 33243 s9simple_knot(qo1->s1, idiv, spar, fixflag, &kstat); 33244 if ( kstat < 0 ) goto error; 33245 33246 memcopy(sparsave, spar, 2, DOUBLE); 33247 if (((*fixflag) == 1 || (*fixflag) == 3) && 33248 (spar[0] < sstart[0]+tdel1 || spar[0] > send[0]-tdel1)) 33249 *fixflag -= 1; 33250 if (((*fixflag) == 2 || (*fixflag) == 3) && 33251 (spar[1] < sstart[1]+tdel2 || spar[1] > send[1]-tdel2)) 33252 *fixflag -= 2; 33253 33254 if ( *fixflag < 3 ) 33255 { 33256 /* In at least one parameter direction there is a freedom 33257 of the subdivision point. */ 33258 33259 /* Set the middle parameter. */ 33260 33261 tmean[0] = s1792 (qo1->s1->et1, qo1->s1->ik1, qo1->s1->in1); 33262 tmean[1] = s1792 (qo1->s1->et2, qo1->s1->ik2, qo1->s1->in2); 33263 33264 if (!(*fixflag == 1) && vedge[iobj - 1]->ipoint > 0) 33265 { 33266 /* Search for intersection points on the edges in the 33267 first paramter direction, i.e. edge 1 and 3. Find the 33268 intersection point closest to the middle parameter value 33269 and distinguish between ordinary intersection points and 33270 singular or almost singular (touchy) points. */ 33271 33272 /* Loop for edges no 1 and 3*/ 33273 for (kj = 0; kj < 3; kj += 2) 33274 /* Loop for all points on edge*/ 33275 for (qptedg = vedge[iobj - 1]->prpt[kj]; qptedg != SISL_NULL; 33276 qptedg = qptedg->pnext) 33277 { 33278 pcurr = qptedg->ppt; 33279 33280 /* Test if the point is too close to an edge. */ 33281 33282 if (pcurr->epar[kpar] < sstart[0]+tdel1 || 33283 pcurr->epar[kpar] > send[0]-tdel1) continue; 33284 33285 /* Check if the intersection curve passing through 33286 the point is always parallel to an iso-curve. */ 33287 33288 if (sh1762_is_taboo(qo1->s1, 33289 (qo2->iobj == SISLSURFACE) ? 33290 qo2->s1 : SISL_NULL, 33291 pcurr, 1, &kstat)) 33292 continue; 33293 33294 if (kstat < 0) 33295 goto error; 33296 33297 if (pcurr->iinter == SI_SING) 33298 { 33299 /* Test if the singular/near singular point is the one 33300 closest to the middle point. */ 33301 33302 if (!ptsing1 || fabs(pcurr->epar[kpar]-tmean[0]) < 33303 fabs(ptsing1->epar[kpar]-tmean[0])) 33304 ptsing1 = pcurr; 33305 } 33306 else 33307 { 33308 /* Test if the intersection point is the one closest 33309 to the middle. */ 33310 33311 if (!pt1 || fabs(pcurr->epar[kpar]-tmean[0]) < 33312 fabs(pt1->epar[kpar]-tmean[0])) 33313 pt1 = pcurr; 33314 } 33315 } 33316 } 33317 33318 if (!(*fixflag == 2) && vedge[iobj - 1]->ipoint > 0) 33319 { 33320 /* Search for intersection points on the edges in the 33321 second paramter direction, i.e. edge 2 and 4. Find the 33322 intersection point closest to the middle parameter value 33323 and distinguish between ordinary intersection points and 33324 singular or almost singular (touchy) points. */ 33325 33326 /* Loop for edges no 2 and 4*/ 33327 for (kj = 1; kj < 4; kj += 2) 33328 /* Loop for all points on edge*/ 33329 for (qptedg = vedge[iobj - 1]->prpt[kj]; qptedg != SISL_NULL; 33330 qptedg = qptedg->pnext) 33331 { 33332 pcurr = qptedg->ppt; 33333 33334 /* Test if the point is too close to an edge. */ 33335 33336 if (pcurr->epar[kpar+1] < sstart[1]+tdel2 || 33337 pcurr->epar[kpar+1] > send[1]-tdel2) continue; 33338 33339 /* Check if the intersection curve passing through 33340 the point is always parallel to an iso-curve. */ 33341 33342 if (sh1762_is_taboo(qo1->s1, 33343 (qo2->iobj == SISLSURFACE) ? 33344 qo2->s1 : SISL_NULL, 33345 pcurr, 2, &kstat)) 33346 continue; 33347 33348 if (kstat < 0) 33349 goto error; 33350 33351 if (pcurr->iinter == SI_SING) 33352 { 33353 /* Test if the singular/near singular point is the one 33354 closest to the middle point. */ 33355 33356 if (!ptsing2 || fabs(pcurr->epar[kpar+1]-tmean[1]) < 33357 fabs(ptsing2->epar[kpar+1]-tmean[1])) 33358 ptsing2 = pcurr; 33359 } 33360 else 33361 { 33362 /* Test if the intersection point is the one closest 33363 to the middle. */ 33364 33365 if (!pt2 || fabs(pcurr->epar[kpar+1]-tmean[1]) < 33366 fabs(pt2->epar[kpar+1]-tmean[1])) 33367 pt2 = pcurr; 33368 } 33369 } 33370 } 33371 33372 if (qo1->s1->idim == 1) 33373 { 33374 /* One-dimensional case. Iterate to find an extremal point. */ 33375 33376 if (!(*fixflag == 1) && ptsing1) 33377 { 33378 /* Set startpoint to iteration. */ 33379 33380 spar[0] = ptsing1->epar[kpar]; 33381 spar[1] = ptsing1->epar[kpar+1]; 33382 } 33383 else if (!(*fixflag == 2) && ptsing2) 33384 { 33385 spar[0] = ptsing2->epar[kpar]; 33386 spar[1] = ptsing2->epar[kpar+1]; 33387 } 33388 else 33389 { 33390 /* No (almost) singular intersection point is found 33391 at the edge. */ 33392 33393 spar[0] = (double)0.5*(sstart[0] + send[0]); 33394 spar[1] = (double)0.5*(sstart[1] + send[1]); 33395 } 33396 33397 /* Perform iteration. */ 33398 33399 kfound = 0; 33400 s1174 (qo1->o1->s1, sstart, send, spar, spar, &kstat); 33401 if (kstat < 0) 33402 goto error; 33403 if (kstat == 1) 33404 { 33405 /* An extremal point is found. Test if it is too close 33406 to an edge. */ 33407 33408 kfound = 3; 33409 if (spar[0] < sstart[0]+tdel1 || spar[0] > send[0]-tdel1) 33410 kfound--; 33411 if (spar[1] < sstart[1]+tdel2 || spar[1] > send[1]-tdel2) 33412 kfound -= 2; 33413 } 33414 33415 if (*fixflag == 0 && ptsing2 && ptsing1) 33416 { 33417 /* Try a second iteration for an extremal point 33418 in order to find a subdivision parameter in the 33419 second parameter direction. */ 33420 33421 spar2[0] = ptsing2->epar[kpar]; 33422 spar2[1] = ptsing2->epar[kpar+1]; 33423 33424 s1174(qo1->o1->s1, sstart, send, spar2, spar2, &kstat); 33425 if (kstat < 0) 33426 goto error; 33427 if (kstat == 1) 33428 { 33429 /* An extremal point is found. Test it against the edges. */ 33430 33431 if (!(spar2[1] < sstart[1]+tdel2 || spar2[1] > send[1]-tdel2)) 33432 { 33433 spar[1] = spar2[1]; 33434 if (kfound < 2) kfound += 2; 33435 } 33436 } 33437 } 33438 33439 /* Set intermediate subdivision point. */ 33440 33441 if (*fixflag == 1) 33442 spar[0] = sparsave[0]; 33443 else if (kfound == 1 || kfound == 3) 33444 (*fixflag)++; 33445 else if (ptsing1) 33446 { 33447 spar[0] = ptsing1->epar[kpar]; 33448 (*fixflag)++; 33449 } 33450 else if (pt1) 33451 { 33452 spar[0] = pt1->epar[kpar]; 33453 (*fixflag)++; 33454 } 33455 else 33456 spar[0] = tmean[0]; 33457 33458 if (*fixflag == 2) 33459 spar[1] = sparsave[1]; 33460 else if (kfound == 2 || kfound == 3) 33461 (*fixflag) += 2; 33462 else if (ptsing2) 33463 { 33464 spar[1] = ptsing2->epar[kpar+1]; 33465 (*fixflag) += 2; 33466 } 33467 else if (pt2) 33468 { 33469 spar[1] = pt2->epar[kpar+1]; 33470 (*fixflag) += 2; 33471 } 33472 else 33473 spar[1] = tmean[1]; 33474 } 33475 else 33476 { 33477 /* Surface-surface intersection. Set intermediate 33478 subdivision point. */ 33479 33480 if (*fixflag == 1) 33481 spar[0] = sparsave[0]; 33482 else if (ptsing1 && pt1) 33483 { 33484 if (fabs(ptsing1->epar[kpar]-tmean[0]) <= 33485 fabs(pt1->epar[kpar]-tmean[0])) 33486 spar[0] = ptsing1->epar[kpar]; 33487 else 33488 spar[0] = pt1->epar[kpar]; 33489 (*fixflag)++; 33490 } 33491 else if (ptsing1) 33492 { 33493 spar[0] = ptsing1->epar[kpar]; 33494 (*fixflag)++; 33495 } 33496 else if (pt1) 33497 { 33498 spar[0] = pt1->epar[kpar]; 33499 (*fixflag)++; 33500 } 33501 else spar[0] = tmean[0]; 33502 33503 if (*fixflag == 2) 33504 spar[1] = sparsave[1]; 33505 else if (ptsing2 && pt2) 33506 { 33507 if (fabs(ptsing2->epar[kpar+1]-tmean[1]) <= 33508 fabs(pt2->epar[kpar+1]-tmean[1])) 33509 spar[1] = ptsing2->epar[kpar+1]; 33510 else 33511 spar[1] = pt2->epar[kpar+1]; 33512 (*fixflag) += 2; 33513 } 33514 else if (ptsing2) 33515 { 33516 spar[1] = ptsing2->epar[kpar+1]; 33517 (*fixflag) += 2; 33518 } 33519 else if (pt2) 33520 { 33521 spar[1] = pt2->epar[kpar+1]; 33522 (*fixflag) += 2; 33523 } 33524 else spar[1] = tmean[1]; 33525 33526 } 33527 } 33528 33529 /* Test if the found subdivision value lies very close to an 33530 existing intersection point. In that case move the subdivision 33531 point to the intersection point. The two parameter directions 33532 are treated separately. */ 33533 33534 if ((*pintdat) && (*pintdat)->ipoint > 0) 33535 for (kj=0; kj<(*pintdat)->ipoint; kj++) 33536 { 33537 pcurr = (*pintdat)->vpoint[kj]; 33538 33539 if ((*fixflag)==1 || (*fixflag)==3) 33540 { 33541 if (fabs(spar[0]-pcurr->epar[kpar]) < (double)0.001*tdel1) 33542 { 33543 if (fabs(spar[0]-pcurr->epar[kpar]) < fabs(tpar1-spar[0]) && 33544 ktype1 <= pcurr->iinter) 33545 { 33546 tpar1 = pcurr->epar[kpar]; 33547 ktype1 = pcurr->iinter; 33548 } 33549 } 33550 } 33551 else 33552 { 33553 if (fabs(spar[0]-pcurr->epar[kpar]) < (double)0.1*tdel1 && 33554 pcurr->epar[kpar] >= sstart[0]+tdel1 && 33555 pcurr->epar[kpar] <= send[0]-tdel1) 33556 { 33557 if (fabs(spar[0]-pcurr->epar[kpar]) < fabs(tpar1-spar[0]) && 33558 ktype1 <= pcurr->iinter) 33559 { 33560 tpar1 = pcurr->epar[kpar]; 33561 ktype1 = pcurr->iinter; 33562 } 33563 } 33564 } 33565 33566 if ((*fixflag)==2 || (*fixflag)==3) 33567 { 33568 if (fabs(spar[1]-pcurr->epar[kpar+1]) < (double)0.001*tdel2) 33569 { 33570 if (fabs(spar[1]-pcurr->epar[kpar+1]) < fabs(tpar2-spar[1]) && 33571 ktype2 <= pcurr->iinter) 33572 { 33573 tpar2 = pcurr->epar[kpar+1]; 33574 ktype2 = pcurr->iinter; 33575 } 33576 } 33577 } 33578 else 33579 { 33580 if (fabs(spar[1]-pcurr->epar[kpar+1]) < (double)0.1*tdel2 && 33581 pcurr->epar[kpar+1] >= sstart[1]+tdel2 && 33582 pcurr->epar[kpar+1] <= send[1]-tdel2) 33583 { 33584 if (fabs(spar[1]-pcurr->epar[kpar+1]) < fabs(tpar2-spar[1]) && 33585 ktype2 <= pcurr->iinter) 33586 { 33587 tpar2 = pcurr->epar[kpar+1]; 33588 ktype2 = pcurr->iinter; 33589 } 33590 } 33591 } 33592 } 33593 33594 if (ktype1 > -10 && tpar1 > sstart[0]+tdel1 && tpar1 < send[0]-tdel1) 33595 { 33596 if (!((*fixflag == 1 || *fixflag == 3) && ktype1 < 0)) 33597 spar[0] = tpar1; 33598 } 33599 if (ktype2 > -10 && tpar2 > sstart[1]+tdel2 && tpar2 < send[1]-tdel2) 33600 { 33601 if (!((*fixflag == 2 || *fixflag == 3) && ktype2 < 0)) 33602 spar[1] = tpar2; 33603 } 33604 } 33605 33606 /* Set output variables. */ 33607 33608 epar[0] = spar[0]; 33609 epar[1] = spar[1]; 33610 *rpt = qpt; 33611 *fixflag = ((*fixflag) >=2) ? 1 : 0; 33612 } 33613 else goto err122; /* Unexpected kind of object. */ 33614 33615 goto out; 33616 33617 /* Error. Unexpected kind of object. */ 33618 33619 err122:*jstat = -122; 33620 s6err ("sh1762_s9subdivpt", *jstat, kpos); 33621 goto out; 33622 33623 /* Error in lower level routine. */ 33624 33625 error:*jstat = kstat; 33626 s6err ("sh1762_s9subdivpt", *jstat, kpos); 33627 goto out; 33628 33629 out: 33630 return; 33631 33632 } 33633 33634 //=========================================================================== 33635 void sh1762_s9div (SISLObject * po1, SISLObject * po2, double aepsge, 33636 int iobj, int idiv, SISLObject * wob[], SISLEdge * vedge[], 33637 SISLIntdat ** pintdat, int *jstat) 33638 //=========================================================================== 33639 33640 { 33641 int kpos = 0; /* Position of error. */ 33642 int kstat = 0; /* Local status variable. */ 33643 int ki, kn; /* Counters. */ 33644 int kpar; /* First parameter direction corresponding the the object 33645 that is to be subdivided. */ 33646 int knum; /* Total number of points in the data structures of the 33647 original problem, and the problem of reduced dimension. */ 33648 double tdel; /* Parameter used to measure closeness between an 33649 intersection point and the subdivision point. */ 33650 double spar[2]; /* Parameter values of subdividing point. If a curve is to 33651 be subdivided, only the first element is used. */ 33652 SISLCurve *qcrv = SISL_NULL; /* Mother curve of subdivision curve. */ 33653 SISLObject *qso = SISL_NULL; /* Subdivision object, it is a point if a curve is subdivided 33654 and a curve if a surface is subdivided. */ 33655 SISLObject *qmotherobj = SISL_NULL; /* Mother object of subdivision object. */ 33656 SISLObject *qo1 = SISL_NULL; /* Pointer to the object that is to be subdivided. */ 33657 SISLObject *qo2 = SISL_NULL; /* Pointer to the other object. */ 33658 SISLObject *qs1 = SISL_NULL, *qs2 = SISL_NULL; /* Subobjects to be used in the case where a surface 33659 is to be subdivided in both parameter direction to 33660 store intermediate subsurfaces. */ 33661 SISLIntpt *qpt = SISL_NULL; /* An eventual found inner intersection used as subdivision 33662 point. If the subdivision point is found in another way, 33663 qpt = SISL_NULL. */ 33664 SISLIntdat *qintdat = SISL_NULL; /* Data structure of intersection problem with lower dim. */ 33665 SISLIntpt *qp; /* Closest intersection point to the subdiv point */ 33666 SISLEdge *uedge[2]; /* Edge intersections of subproblem. */ 33667 int fixflag = 0; /* UJK 31.10.90 */ 33668 int idummy; 33669 33670 /* Fetch subdivision point of object. */ 33671 33672 sh1762_s9subdivpt (po1, po2, aepsge, iobj, idiv, vedge, pintdat, &fixflag, &qpt, spar, &kstat); 33673 if (kstat < 0) 33674 goto error; 33675 33676 qo1 = (iobj == 1 ? po1 : po2); 33677 qo2 = (iobj == 1 ? po2 : po1); 33678 kpar = (iobj == 1 ? 0 : po1->iobj); 33679 33680 *jstat = 0; 33681 33682 33683 if (qo1->iobj == SISLCURVE) 33684 { 33685 /* Subdivide the curve at the found subdivision parameter value. */ 33686 33687 /* printf("Subdivide curve. Parameter value = %10.6f \n",spar[0]); */ 33688 33689 s1231 (qo1->c1, spar[0], &(wob[0]->c1), &(wob[1]->c1), &kstat); 33690 if (kstat < 0) 33691 goto error; 33692 33693 33694 if (wob[0]->edg[1] == SISL_NULL) 33695 { 33696 if ((qso = wob[0]->edg[1] = newObject (SISLPOINT)) == SISL_NULL) 33697 goto err101; 33698 33699 /* Pick out end point from a curve. */ 33700 33701 s1438 (wob[0]->c1, 1, &(qso->p1), &spar[0], &kstat); 33702 if (kstat < 0) 33703 goto error; 33704 } 33705 else 33706 qso = wob[0]->edg[1]; 33707 33708 if (po1->iobj + po2->iobj > SISLCURVE) 33709 { 33710 /***** Treating edges on sub problems. *****/ 33711 33712 /* We first have to transform intersection points to the the new 33713 intersection format qintdat. */ 33714 33715 /* UJK, newi */ 33716 sh6idget (po1, po2, kpar, spar[0], *pintdat, &qintdat, aepsge, &kstat); 33717 33718 33719 /* Making new edge object to sub problems. */ 33720 33721 if ((iobj == 1 ? qso : po1)->iobj == SISLPOINT) 33722 uedge[0] = SISL_NULL; 33723 else if ((uedge[0] = newEdge (vedge[0]->iedge - (iobj == 1 ? 2 : 0))) == SISL_NULL) 33724 goto err101; 33725 if ((iobj == 2 ? qso : po2)->iobj == SISLPOINT) 33726 uedge[1] = SISL_NULL; 33727 else if ((uedge[1] = newEdge (vedge[1]->iedge - (iobj == 2 ? 2 : 0))) == SISL_NULL) 33728 goto err101; 33729 33730 /* Update edge intersection on sub problems. */ 33731 33732 sh6idalledg ((iobj == 1 ? qso : po1), (iobj == 1 ? po2 : qso), qintdat, uedge, &kstat); 33733 if (kstat < 0) 33734 goto error; 33735 33736 /* Examine if the subdividing point intersect the second object. */ 33737 33738 qso->o1 = qso; 33739 33740 sh1762 ((iobj == 1 ? qso : po1), (iobj == 1 ? po2 : qso), aepsge, 33741 &qintdat, uedge, &kstat); 33742 if (kstat < 0) 33743 goto error; 33744 33745 if (uedge[0] != SISL_NULL) 33746 freeEdge (uedge[0]); 33747 if (uedge[1] != SISL_NULL) 33748 freeEdge (uedge[1]); 33749 } 33750 else 33751 { 33752 sh1761 ((iobj == 1 ? qso : po1), (iobj == 1 ? po2 : qso), aepsge, 33753 &qintdat, &kstat); 33754 if (kstat < 0) 33755 goto error; 33756 } 33757 33758 if (kstat) 33759 { 33760 /* Total number of points. */ 33761 33762 knum = (*pintdat == SISL_NULL ? 0 : (*pintdat)->ipoint) + qintdat->ipoint; 33763 33764 *jstat = 1; /* Mark intersection found. */ 33765 33766 /* Intersection found and we have to register the intersection 33767 points. */ 33768 33769 /* UJK newi */ 33770 sh1782 (po1, po2, aepsge, qintdat, kpar, spar[0], pintdat, &idummy, &kstat); 33771 if (kstat < 0) 33772 goto error; 33773 33774 /* UJK newi divide curve */ 33775 /* UPDATE: ? what about help points from s1782 knum?? */ 33776 if (qpt != SISL_NULL && (*pintdat)->ipoint == knum) 33777 { 33778 /* Find the closest poin to qpt. */ 33779 33780 s6idcpt (*pintdat, qpt, &qp); 33781 33782 /* UJK newi, unite the points : */ 33783 sh6idnewunite (po1, po2, pintdat, &qpt, &qp, (double) 0.5, 33784 aepsge, &kstat); 33785 if (kstat < 0) 33786 goto error; 33787 } 33788 } 33789 33790 if (qintdat != SISL_NULL) 33791 { 33792 freeIntdat (qintdat); 33793 qintdat = SISL_NULL; 33794 } 33795 } 33796 else if (qo1->iobj == SISLSURFACE) 33797 { 33798 33799 /* Subdivide surface and treat subdivision curves. */ 33800 33801 for (ki = 0; ki < (idiv < 3 ? 1 : 3); ki++) 33802 { 33803 if (idiv == 1) 33804 { 33805 /* printf("Subdivide surface. 1. par dir. par = %10.6f \n",spar[0]); */ 33806 33807 s1711 (qo1->s1, 1, spar[0], &(wob[0]->s1), &(wob[1]->s1), &kstat); 33808 if (kstat < 0) 33809 goto error; 33810 33811 if (wob[0]->edg[1] == SISL_NULL) 33812 { 33813 if ((qso = wob[0]->edg[1] = newObject (SISLCURVE)) == SISL_NULL) 33814 goto err101; 33815 33816 /* Pick out edge curve from a surface. */ 33817 33818 s1435 (wob[0]->s1, 1, &(qso->c1), spar, &kstat); 33819 if (kstat < 0) 33820 goto error; 33821 } 33822 else 33823 qso = wob[0]->edg[1]; 33824 33825 /* Pick curve from mother object of surface, and make 33826 motherobject of curve. */ 33827 33828 s1437(qo1->o1->s1,spar[0],&qcrv,&kstat); 33829 if (kstat < 0) goto error; 33830 33831 if ((qmotherobj = newObject(SISLCURVE)) == SISL_NULL) goto err101; 33832 qmotherobj->c1 = qcrv; 33833 qso->o1 = qmotherobj; 33834 } 33835 else if (idiv == 2) 33836 { 33837 /* printf("Subdivide surface. 2. par dir. par = %10.6f \n",spar[1]); */ 33838 33839 s1711 (qo1->s1, 2, spar[1], &(wob[0]->s1), &(wob[1]->s1), &kstat); 33840 if (kstat < 0) 33841 goto error; 33842 33843 if (wob[0]->edg[2] == SISL_NULL) 33844 { 33845 if ((qso = wob[0]->edg[2] = newObject (SISLCURVE)) == SISL_NULL) 33846 goto err101; 33847 33848 /* Pick out edge curve from a surface. */ 33849 33850 s1435 (wob[0]->s1, 2, &(qso->c1), spar + 1, &kstat); 33851 if (kstat < 0) 33852 goto error; 33853 } 33854 else 33855 qso = wob[0]->edg[2]; 33856 33857 /* Pick curve from mother object of surface, and make 33858 motherobject of curve. */ 33859 33860 s1436(qo1->o1->s1,spar[1],&qcrv,&kstat); 33861 if (kstat < 0) goto error; 33862 33863 if ((qmotherobj = newObject(SISLCURVE)) == SISL_NULL) goto err101; 33864 qmotherobj->c1 = qcrv; 33865 qso->o1 = qmotherobj; 33866 } 33867 else if (ki == 0) 33868 { 33869 if ((qs1 = newObject (SISLSURFACE)) == SISL_NULL) 33870 goto err101; 33871 if ((qs2 = newObject (SISLSURFACE)) == SISL_NULL) 33872 goto err101; 33873 33874 /* printf("Subdivide surface. 1. par dir. par = %10.6f \n",spar[0]); */ 33875 33876 s1711 (qo1->s1, 1, spar[0], &(qs1->s1), &(qs2->s1), &kstat); 33877 if (kstat < 0) 33878 goto error; 33879 33880 if (qs1->edg[1] == SISL_NULL) 33881 { 33882 if ((qso = qs1->edg[1] = newObject (SISLCURVE)) == SISL_NULL) 33883 goto err101; 33884 33885 /* Pick out edge curve from a surface. */ 33886 33887 s1435 (qs1->s1, 1, &(qso->c1), spar, &kstat); 33888 if (kstat < 0) 33889 goto error; 33890 } 33891 else 33892 qso = qs1->edg[1]; 33893 33894 /* Pick curve from mother object of surface, and make 33895 motherobject of curve. */ 33896 33897 s1437(qo1->o1->s1,spar[0],&qcrv,&kstat); 33898 if (kstat < 0) goto error; 33899 33900 if ((qmotherobj = newObject(SISLCURVE)) == SISL_NULL) goto err101; 33901 qmotherobj->c1 = qcrv; 33902 qso->o1 = qmotherobj; 33903 } 33904 else if (ki == 1) 33905 { 33906 /* printf("Subdivide surface. 2. par dir. par = %10.6f \n",spar[1]); */ 33907 33908 s1711 (qs1->s1, 2, spar[1], &(wob[0]->s1), &(wob[1]->s1), &kstat); 33909 if (kstat < 0) 33910 goto error; 33911 33912 if (wob[0]->edg[2] == SISL_NULL) 33913 { 33914 if ((qso = wob[0]->edg[2] = newObject (SISLCURVE)) == SISL_NULL) 33915 goto err101; 33916 33917 /* Pick out edge curve from a surface. */ 33918 33919 s1435 (wob[0]->s1, 2, &(qso->c1), spar + 1, &kstat); 33920 if (kstat < 0) 33921 goto error; 33922 } 33923 else 33924 qso = wob[0]->edg[2]; 33925 33926 /* Pick curve from mother object of surface, and make 33927 motherobject of curve. */ 33928 33929 s1436(qo1->o1->s1,spar[1],&qcrv,&kstat); 33930 if (kstat < 0) goto error; 33931 33932 if ((qmotherobj = newObject(SISLCURVE)) == SISL_NULL) goto err101; 33933 qmotherobj->c1 = qcrv; 33934 qso->o1 = qmotherobj; 33935 } 33936 else 33937 /* if (ki == 2) */ 33938 { 33939 /* printf("Subdivide surface. 2. par dir. par = %10.6f \n",spar[1]); */ 33940 33941 s1711 (qs2->s1, 2, spar[1], &(wob[2]->s1), &(wob[3]->s1), &kstat); 33942 if (kstat < 0) 33943 goto error; 33944 33945 if (wob[2]->edg[2] == SISL_NULL) 33946 { 33947 if ((qso = wob[2]->edg[2] = newObject (SISLCURVE)) == SISL_NULL) 33948 goto err101; 33949 33950 /* Pick out edge curve from a surface. */ 33951 33952 s1435 (wob[2]->s1, 2, &(qso->c1), spar + 1, &kstat); 33953 if (kstat < 0) 33954 goto error; 33955 } 33956 else 33957 qso = wob[2]->edg[2]; 33958 33959 /* Pick curve from mother object of surface, and make 33960 motherobject of curve. */ 33961 33962 s1436(qo1->o1->s1,spar[1],&qcrv,&kstat); 33963 if (kstat < 0) goto error; 33964 33965 if ((qmotherobj = newObject(SISLCURVE)) == SISL_NULL) goto err101; 33966 qmotherobj->c1 = qcrv; 33967 qso->o1 = qmotherobj; 33968 } 33969 33970 /***** Treating edges on sub problems. *****/ 33971 33972 /* We first have to transform intersection points to the the new 33973 intersection format qintdat. */ 33974 33975 /* UJK, newi */ 33976 sh6idget ((iobj == 1 ? (ki == 0 ? po1 : (ki == 1 ? qs1 : qs2)) : po1), 33977 (iobj == 2 ? (ki == 0 ? po2 : (ki == 1 ? qs1 : qs2)) : po2), 33978 (ki == 0 ? (idiv == 2 ? 1 : 0) : 1) + kpar, 33979 (ki == 0 ? (idiv == 2 ? spar[1] : spar[0]) : spar[1]), 33980 *pintdat, &qintdat, aepsge, &kstat); 33981 33982 /* Making new edge object to sub problems. */ 33983 33984 if ((iobj == 1 ? qso : po1)->iobj == SISLPOINT) 33985 uedge[0] = SISL_NULL; 33986 else if ((uedge[0] = newEdge (vedge[0]->iedge - (iobj == 1 ? 2 : 0))) == SISL_NULL) 33987 goto err101; 33988 if ((iobj == 2 ? qso : po2)->iobj == SISLPOINT) 33989 uedge[1] = SISL_NULL; 33990 else if ((uedge[1] = newEdge (vedge[1]->iedge - (iobj == 2 ? 2 : 0))) == SISL_NULL) 33991 goto err101; 33992 33993 /* Update edge intersection on sub problems. */ 33994 33995 sh6idalledg ((iobj == 1 ? qso : po1), (iobj == 1 ? po2 : qso), qintdat, uedge, &kstat); 33996 if (kstat < 0) 33997 goto error; 33998 33999 /* START of update, UJK,jan.93.__________________________ */ 34000 /* UJK, jan 1993, 1D: test if end pt of curve is intersection pt 34001 and not registred on edge. 34002 This will very seldom ocurr, boarder line case. */ 34003 if (qso->c1->idim == 1) 34004 { 34005 int changes = FALSE; 34006 int loop; 34007 double endpar; 34008 double qt_par[2]; 34009 SISLPoint *end_point=SISL_NULL; 34010 SISLObject *pt_obj=SISL_NULL; 34011 SISLCurve *pcrv=SISL_NULL; 34012 int knum; 34013 int ind_missing, ind_kept; 34014 SISLIntpt *qt = SISL_NULL; 34015 SISLIntpt *pcl = SISL_NULL; 34016 SISLIntpt **up = SISL_NULL; /* Array of poiners to intersection point. */ 34017 34018 /* Get edge points to SUB-problem. */ 34019 sh6edgpoint (uedge, &up, &knum, &kstat); 34020 if (kstat < 0) 34021 goto error; 34022 34023 /* Set up case navigators. */ 34024 pcrv = qso->c1; 34025 pt_obj = (iobj == 1 ? po2 :po1); 34026 ind_missing = (ki == 0 ? (idiv == 2 ? 1 : 0) : 1); 34027 ind_kept = (ki == 0 ? (idiv == 2 ? 0 : 1) : 0); 34028 34029 if (knum < 2) 34030 for (loop = 0; loop < 2; loop++) 34031 { 34032 34033 /* Pick out end point from a curve. */ 34034 s1438 (pcrv, loop, &end_point, &endpar, &kstat); 34035 if (kstat < 0) 34036 goto error; 34037 if (fabs(end_point->ecoef[0] - pt_obj->p1->ecoef[0]) < aepsge && 34038 (knum == 0 || DNEQUAL(up[0]->epar[0], endpar))) 34039 { 34040 /* Making intersection point. */ 34041 double *nullp = SISL_NULL; 34042 34043 changes = TRUE; 34044 qt_par[ind_kept] = endpar; 34045 qt_par[ind_missing] = spar[ind_missing]; 34046 qt = hp_newIntpt (2, qt_par, DZERO, SI_ORD, 34047 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 34048 0, 0, nullp, nullp); 34049 34050 if (qt == SISL_NULL) 34051 goto err101; 34052 34053 sh6tohelp (qt,&kstat); 34054 if (kstat < 0) goto error; 34055 34056 /* get closest point pcl to qt in pintdat. */ 34057 sh6idnpt(pintdat,&qt,TRUE,&kstat); 34058 if (kstat < 0) goto error; 34059 kpos=1; 34060 if (kstat) goto errinconsis; 34061 34062 kpos=2; 34063 s6idcpt(*pintdat,qt,&pcl); 34064 if (!pcl) goto errinconsis; 34065 34066 if (DEQUAL(pcl->epar[ind_kept],qt_par[ind_kept]) && 34067 fabs(pcl->epar[ind_missing] - qt_par[ind_missing]) 34068 < 0.000001) 34069 { 34070 qt->epar[ind_missing] = pcl->epar[ind_missing]; 34071 pcl->epar[ind_missing] = qt_par[ind_missing]; 34072 sh6tomain (pcl,&kstat); 34073 if (kstat < 0) goto error; 34074 sh6idcon (pintdat,&qt,&pcl,&kstat); 34075 if (kstat < 0) goto error; 34076 } 34077 } 34078 if (end_point) 34079 freePoint(end_point); 34080 end_point = SISL_NULL; 34081 34082 } 34083 34084 if (changes) 34085 { 34086 /* Clean up and regenerate uedge and qintdat. */ 34087 if (uedge[0] != SISL_NULL) 34088 freeEdge (uedge[0]); 34089 if (uedge[1] != SISL_NULL) 34090 freeEdge (uedge[1]); 34091 34092 if (qintdat != SISL_NULL) 34093 { 34094 freeIntdat (qintdat); 34095 qintdat = SISL_NULL; 34096 } 34097 34098 sh6idget ((iobj == 1 ? (ki == 0 ? po1 : (ki == 1 ? qs1 : qs2)) : po1), 34099 (iobj == 2 ? (ki == 0 ? po2 : (ki == 1 ? qs1 : qs2)) : po2), 34100 (ki == 0 ? (idiv == 2 ? 1 : 0) : 1) + kpar, 34101 (ki == 0 ? (idiv == 2 ? spar[1] : spar[0]) : spar[1]), 34102 *pintdat, &qintdat, aepsge, &kstat); 34103 34104 /* Making new edge object to sub problems. */ 34105 34106 if ((iobj == 1 ? qso : po1)->iobj == SISLPOINT) 34107 uedge[0] = SISL_NULL; 34108 else if ((uedge[0] = newEdge (vedge[0]->iedge - (iobj == 1 ? 2 : 0))) == SISL_NULL) 34109 goto err101; 34110 if ((iobj == 2 ? qso : po2)->iobj == SISLPOINT) 34111 uedge[1] = SISL_NULL; 34112 else if ((uedge[1] = newEdge (vedge[1]->iedge - (iobj == 2 ? 2 : 0))) == SISL_NULL) 34113 goto err101; 34114 34115 /* Update edge intersection on sub problems. */ 34116 34117 sh6idalledg ((iobj == 1 ? qso : po1), (iobj == 1 ? po2 : qso), qintdat, uedge, &kstat); 34118 if (kstat < 0) 34119 goto error; 34120 34121 34122 } 34123 if (up) freearray(up); 34124 } 34125 /* END of update, UJK,jan.93.__________________________ */ 34126 34127 34128 /* Examine if the subdividing curve intersect the second object. */ 34129 34130 sh1762 ((iobj == 1 ? qso : po1), (iobj == 1 ? po2 : qso), aepsge, 34131 &qintdat, uedge, &kstat); 34132 if (kstat < 0) 34133 goto error; 34134 34135 if (uedge[0] != SISL_NULL) 34136 freeEdge (uedge[0]); 34137 if (uedge[1] != SISL_NULL) 34138 freeEdge (uedge[1]); 34139 34140 34141 /* Free mother object of the subdividing curve. */ 34142 34143 if (qmotherobj != SISL_NULL) freeObject(qmotherobj); 34144 qmotherobj = SISL_NULL; 34145 qcrv = SISL_NULL; 34146 qso->o1 = qso; 34147 34148 /* Examine if there is an intersection point close to the 34149 subdivision point. If there is, correct the subdivision point. */ 34150 34151 /* ALA and UJK 31.10.90 don't change divide point 34152 when fixflag is set */ 34153 if ((fixflag == 0) && idiv == 3 && ki == 0 && qintdat != SISL_NULL) 34154 /* if (idiv == 3 && ki == 0 && qintdat != SISL_NULL) */ 34155 { 34156 tdel = (qso->c1->et[qso->c1->in] - 34157 qso->c1->et[qso->c1->ik - 1]) * (double) 0.1; 34158 34159 for (kn = 0; kn < qintdat->ipoint; kn++) 34160 /* UJK, aug.92 Do NOT subdiv in a help point */ 34161 if (sh6ismain(qintdat->vpoint[kn])) 34162 if ((fabs (qintdat->vpoint[kn]->epar[kpar] 34163 - spar[1]) < fabs (tdel)) && 34164 DNEQUAL (qintdat->vpoint[kn]->epar[kpar], 34165 qso->c1->et[qso->c1->in]) && 34166 DNEQUAL (qintdat->vpoint[kn]->epar[kpar], 34167 qso->c1->et[qso->c1->ik - 1])) 34168 spar[1] = qintdat->vpoint[kn]->epar[kpar]; 34169 } 34170 34171 /*ujk, ala 921218, dont't split very close to a 34172 new intersection point */ 34173 else if ((fixflag) && idiv == 3 && ki == 0 && qintdat != SISL_NULL) 34174 { 34175 tdel = (qso->c1->et[qso->c1->in] - 34176 qso->c1->et[qso->c1->ik - 1]) * (double) 0.000001; 34177 34178 for (kn = 0; kn < qintdat->ipoint; kn++) 34179 if (DNEQUAL(qintdat->vpoint[kn]->epar[kpar],spar[1]) 34180 && (fabs (qintdat->vpoint[kn]->epar[kpar] 34181 - spar[1]) < fabs (tdel))) break; 34182 34183 if (kn < qintdat->ipoint) 34184 /* Using midpoint */ 34185 { 34186 spar[1] = s1792 (qo1->s1->et2, qo1->s1->ik2, qo1->s1->in2); 34187 fixflag = 0; 34188 } 34189 } 34190 34191 /* TDO,UJK 02.08.89 */ 34192 /* A possible better strategy for 34193 subdividing is to divide in the 34194 middle value of the first and last 34195 intersection on the subdividing curve.*/ 34196 /* 34197 if (idiv == 3 && ki == 0 && qintdat != SISL_NULL) 34198 { 34199 int kn; 34200 double tdel,tdiv,tmin,tmax; 34201 34202 if(qintdat->ipoint > 0) 34203 { 34204 tmin = qintdat->vpoint[0]->epar[kpar]; 34205 tmax = qintdat->vpoint[0]->epar[kpar]; 34206 34207 for (kn=1;kn<qintdat->ipoint;kn++) 34208 { 34209 if (tmin < qintdat->vpoint[kn]->epar[kpar]) 34210 tmin = qintdat->vpoint[kn]->epar[kpar]; 34211 34212 if (tmax > qintdat->vpoint[kn]->epar[kpar]) 34213 tmax = qintdat->vpoint[kn]->epar[kpar]; 34214 34215 } 34216 34217 tdiv = (tmax + tmin)/(double)2.0; 34218 34219 if (DNEQUAL(tdiv,qso->c1->et[qso->c1->in]) && 34220 DNEQUAL(tdiv,qso->c1->et[qso->c1->ik-1])) 34221 spar[1]=tdiv; 34222 34223 } 34224 } 34225 */ 34226 34227 34228 if (kstat) 34229 { 34230 /* Total number of points. */ 34231 34232 knum = (*pintdat == SISL_NULL ? 0 : (*pintdat)->ipoint) + 34233 qintdat->ipoint; 34234 34235 *jstat = 1; /* Mark intersection found. */ 34236 34237 /* Intersection found and we have to register the intersection 34238 points. */ 34239 34240 /* UJK newi */ 34241 sh1782 (po1, po2, aepsge, qintdat, 34242 (ki == 0 ? (idiv == 2 ? 1 : 0) : 1) + kpar, 34243 (ki == 0 ? (idiv == 2 ? spar[1] : spar[0]) : spar[1]), 34244 pintdat, &idummy, &kstat); 34245 if (kstat < 0) 34246 goto error; 34247 34248 /* UJK newi divide surface */ 34249 /* UPDATE: ? what about help points from s1782 knum?? */ 34250 if (qpt != SISL_NULL && (*pintdat)->ipoint == knum) 34251 { 34252 /* Find the closest poin to qpt. */ 34253 34254 s6idcpt (*pintdat, qpt, &qp); 34255 34256 /* UJK newi, unite the points : */ 34257 sh6idnewunite (po1, po2, pintdat, &qpt, &qp, (double) 0.5, 34258 aepsge, &kstat); 34259 if (kstat < 0) 34260 goto error; 34261 } 34262 34263 } 34264 34265 if (qintdat != SISL_NULL) 34266 { 34267 freeIntdat (qintdat); 34268 qintdat = SISL_NULL; 34269 } 34270 } 34271 if (qs1 != SISL_NULL) 34272 freeObject (qs1); 34273 if (qs2 != SISL_NULL) 34274 freeObject (qs2); 34275 } 34276 else 34277 goto err121; 34278 34279 34280 goto out; 34281 34282 /* Error. Inconsistency. */ 34283 34284 errinconsis:*jstat = -231; 34285 s6err ("sh1762_s9div", *jstat, kpos); 34286 goto out; 34287 34288 /* Error. Kind of object does not exist. */ 34289 34290 err121:*jstat = -121; 34291 s6err ("sh1762_s9div", *jstat, kpos); 34292 goto out; 34293 34294 /* Error in space allocation. */ 34295 34296 err101:*jstat = -101; 34297 s6err ("sh1762_s9div", *jstat, kpos); 34298 goto out; 34299 34300 /* Error in lower level routine. */ 34301 34302 error:*jstat = kstat; 34303 s6err ("sh1762_s9div", *jstat, kpos); 34304 goto out; 34305 34306 out:; 34307 } 34308 34309 //=========================================================================== 34310 void sh1762_s9update (SISLObject * po1, SISLObject * po2, double aepsge, 34311 SISLIntdat ** pintdat, SISLEdge ** vedge[], int *jstat) 34312 //=========================================================================== 34313 { 34314 /* UJK newi */ 34315 int ki, no_new; 34316 SISLIntpt *qt = SISL_NULL; 34317 34318 int kpos = 0; 34319 int kstat = 0; 34320 int kdim; 34321 SISLObject *qo; 34322 SISLIntpt **up = SISL_NULL; 34323 34324 /* Test input. */ 34325 34326 kdim = (po1->iobj == SISLPOINT ? po1->p1->idim : 34327 (po1->iobj == SISLCURVE ? po1->c1->idim : po1->s1->idim)); 34328 34329 if (kdim != (po2->iobj == SISLPOINT ? po2->p1->idim : 34330 (po2->iobj == SISLCURVE ? po2->c1->idim : po2->s1->idim))) 34331 goto err106; 34332 34333 /* Initiate to no intersection. */ 34334 34335 *jstat = 2; 34336 34337 if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT) 34338 { 34339 int kturn = 0; 34340 int knum = 0; 34341 34342 if (po1->iobj != SISLPOINT) 34343 { 34344 qo = po1; 34345 po1 = po2; 34346 po2 = qo; 34347 kturn = 1; 34348 } 34349 34350 knum = (*vedge)[1 - kturn]->ipoint; 34351 34352 34353 /* UPDATE ALA 010993. Start */ 34354 if (knum == 0 && (*pintdat) != SISL_NULL) 34355 { 34356 for (ki = 0; ki < (*pintdat)->ipoint; ki++) 34357 if (po2->iobj == SISLCURVE) 34358 { 34359 if ((*pintdat)->vpoint[ki]->epar[0] > po2->c1->et[po2->c1->ik-1] && 34360 (*pintdat)->vpoint[ki]->epar[0] < po2->c1->et[po2->c1->in]) 34361 { 34362 knum = 1; 34363 } 34364 } 34365 else 34366 { 34367 if ((*pintdat)->vpoint[ki]->epar[0] > po2->s1->et1[po2->s1->ik1-1] && 34368 (*pintdat)->vpoint[ki]->epar[0] < po2->s1->et1[po2->s1->in1] && 34369 (*pintdat)->vpoint[ki]->epar[1] > po2->s1->et2[po2->s1->ik2-1] && 34370 (*pintdat)->vpoint[ki]->epar[1] < po2->s1->et2[po2->s1->in2]) 34371 { 34372 knum = 1; 34373 } 34374 } 34375 } 34376 /* UPDATE ALA 010993. End */ 34377 34378 34379 if (knum > 1) 34380 { 34381 /* sh1762_s9edgpoint ((*vedge), &up, &knum, &kstat); */ 34382 sh6edgpoint ((*vedge), &up, &knum, &kstat); 34383 if (kstat < 0) 34384 goto error; 34385 } 34386 34387 34388 /* We have more than one intersection point on the edges. 34389 If the dimension is one and the second object is a point 34390 we just connect the point else we kill these points and 34391 try to find a new intersection point. */ 34392 34393 if (knum > 1) 34394 { 34395 if (po2->iobj == SISLSURFACE && kdim == 1) 34396 { 34397 int ksimple; 34398 if (po2->o1 == po2) 34399 ksimple = 0; 34400 else 34401 ksimple = 1; 34402 34403 /* UPDATE: UJK, new parameter turn ?? */ 34404 sh1762_s9edgpscon ((*vedge)[1 - kturn], po1->p1->ecoef[0], 34405 po2->s1, ksimple, *pintdat, aepsge, &kstat); 34406 if (kstat < 0) 34407 goto error; 34408 else if (kstat) 34409 *jstat = 0; /* Not a simple case. */ 34410 } 34411 34412 else if (po2->iobj == SISLSURFACE && kdim == 2 && knum == 2) 34413 { 34414 /* 2D point surf, connect */ 34415 sh6idcon (pintdat, up, up + 1, &kstat); 34416 if (kstat < 0) 34417 goto error; 34418 } 34419 34420 else 34421 { 34422 /* UJK newi */ 34423 for (ki = 1; ki < knum; ki++) 34424 { 34425 sh6idnewunite (po1, po2, pintdat, &up[0], &up[ki], 34426 (double) 0.5, aepsge, &kstat); 34427 if (kstat < 0) 34428 goto error; 34429 34430 } 34431 qt = up[0]; 34432 34433 ki = (*vedge)[1 - kturn]->iedge; 34434 freeEdge ((*vedge)[1 - kturn]); 34435 if (((*vedge)[1 - kturn] = newEdge (ki)) == SISL_NULL) 34436 goto err101; 34437 knum = 0; 34438 } 34439 } 34440 34441 if (knum == 0) 34442 { 34443 double spar[2]; 34444 34445 if (po2->iobj == SISLCURVE) 34446 { 34447 double tstart, tend; 34448 34449 tstart = po2->c1->et[po2->c1->ik - 1]; 34450 tend = po2->c1->et[po2->c1->in]; 34451 spar[0] = (tstart + tend) * (double) 0.5; 34452 34453 34454 s1771 (po1->p1, po2->o1->c1, aepsge, 34455 tstart, tend, spar[0], spar, &kstat); 34456 if (kstat < 0) 34457 goto error; 34458 34459 if (kstat == 1) 34460 /*Intersection point found. Control edges. */ 34461 if (DEQUAL (spar[0], tstart) || DEQUAL (spar[0], tend)) 34462 kstat = 0; 34463 } 34464 else if (po2->iobj == SISLSURFACE) 34465 { 34466 double sstart[2], send[2]; 34467 34468 sstart[0] = po2->s1->et1[po2->s1->ik1 - 1]; 34469 sstart[1] = po2->s1->et2[po2->s1->ik2 - 1]; 34470 34471 send[0] = po2->s1->et1[po2->s1->in1]; 34472 send[1] = po2->s1->et2[po2->s1->in2]; 34473 34474 spar[0] = (sstart[0] + send[0]) * (double) 0.5; 34475 spar[1] = (sstart[1] + send[1]) * (double) 0.5; 34476 34477 s1773 (po1->p1, po2->o1->s1, aepsge, sstart, send, spar, spar, &kstat); 34478 if (kstat < 0) 34479 goto error; 34480 34481 if (kstat == 1) 34482 /*Intersection point found. Control edges. */ 34483 if (DEQUAL (spar[0], sstart[0]) || DEQUAL (spar[0], send[0]) 34484 || DEQUAL (spar[1], sstart[1]) || DEQUAL (spar[1], send[1])) 34485 kstat = 0; 34486 } 34487 34488 34489 34490 /* UJK, October 91, 2D crv and surf's may be degenerate, 34491 continue when iteration fails */ 34492 if (po1->p1->idim == 2) 34493 { 34494 if ((po2->iobj == SISLSURFACE && kstat == 9)|| 34495 (po2->iobj == SISLCURVE && kstat != 1)) 34496 { 34497 *jstat = 0; 34498 goto out; 34499 } 34500 } 34501 34502 34503 /* TESTING UJK !!!!!!!!!!!!!!!!!!!!! */ 34504 /* UJK, August 92, 1D crvs may be "degenerate", 34505 continue when iteration fails */ 34506 if (kstat != 1 && po1->p1->idim == 1) 34507 { 34508 *jstat = 0; 34509 goto out; 34510 } 34511 34512 34513 if (kstat == 1) /* Intersection point found. */ 34514 { 34515 *jstat = 1; /* Mark intersection found. */ 34516 34517 /* UJK newi */ 34518 if (qt) 34519 { 34520 /* We have an instance of a point, use it */ 34521 for (ki = 0; ki < qt->ipar; ki++) 34522 qt->epar[ki] = spar[ki]; 34523 } 34524 else 34525 { 34526 /* Making intersection point. */ 34527 double *nullp = SISL_NULL; 34528 qt = hp_newIntpt (po2->iobj, spar, DZERO, SI_ORD, 34529 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 34530 0, 0, nullp, nullp); 34531 34532 if (qt == SISL_NULL) 34533 goto err101; 34534 34535 /* Uppdating pintdat. */ 34536 sh6idnpt (pintdat, &qt, 1, &kstat); 34537 if (kstat < 0) 34538 goto error; 34539 34540 /* Set pretopology */ 34541 if (po2->iobj == SISLCURVE) 34542 { 34543 /* Case point, curve */ 34544 if (po1->p1->idim == 1) 34545 { 34546 /* 1D point curve treated, 34547 2D, 3D is set to undef */ 34548 34549 sh1781 ((kturn ? po2 : po1), 34550 (kturn ? po1 : po2), 34551 aepsge, pintdat, qt, &no_new, &kstat); 34552 if (kstat < 0) 34553 goto error; 34554 } 34555 else 34556 { 34557 /* UPDATE (ujk) 1D touch well defined ? */ 34558 /* Case point, surface */ 34559 if (po1->p1->idim == 2) 34560 { 34561 /* 2D point surface is treated, 34562 1D, 3D is set to undef */ 34563 sh1786 ((kturn ? po2 : po1), 34564 (kturn ? po1 : po2), 34565 aepsge, pintdat, qt, &no_new, &kstat); 34566 34567 if (kstat < 0) 34568 goto error; 34569 } 34570 } 34571 34572 } 34573 } 34574 } 34575 } 34576 } 34577 else if (po1->iobj == SISLCURVE || po2->iobj == SISLCURVE) 34578 { 34579 int kturn1 = 1, kturn2 = 0; 34580 34581 if (po1->iobj != SISLCURVE) 34582 { 34583 qo = po1; 34584 po1 = po2; 34585 po2 = qo; 34586 kturn1 = 0; 34587 kturn2 = 2; 34588 } 34589 34590 if ((*vedge)[0]->ipoint + (*vedge)[1]->ipoint > 1) 34591 { 34592 int knum; 34593 34594 /* sh1762_s9edgpoint ((*vedge), &up, &knum, &kstat); */ 34595 sh6edgpoint ((*vedge), &up, &knum, &kstat); 34596 if (kstat < 0) 34597 goto error; 34598 34599 if (knum > 1) 34600 { 34601 int ki; 34602 34603 /* We have more than one intersection point on the edges. 34604 We therefor kill these points and 34605 try to find a new intersection point. */ 34606 34607 /* UJK newi CONNECT */ 34608 for (ki = 1; ki < knum; ki++) 34609 { 34610 /* sh6idnewunite (po1, po2, pintdat, &up[0], &up[ki], 34611 (double) 0.5, aepsge, &kstat); */ 34612 sh6idcon(pintdat, &up[0], &up[ki], &kstat); 34613 if (kstat < 0) 34614 goto error; 34615 34616 } 34617 34618 *jstat = 1; 34619 goto out; 34620 34621 /* qt = up[0]; 34622 34623 ki = (*vedge)[0]->iedge; 34624 freeEdge ((*vedge)[0]); 34625 if (((*vedge)[0] = newEdge (ki)) == SISL_NULL) 34626 goto err101; 34627 ki = (*vedge)[1]->iedge; 34628 freeEdge ((*vedge)[1]); 34629 if (((*vedge)[1] = newEdge (ki)) == SISL_NULL) 34630 goto err101; 34631 knum = 0; */ 34632 } 34633 } 34634 34635 if ((*vedge)[0]->ipoint + (*vedge)[1]->ipoint == 0) 34636 { 34637 double spar[3]; 34638 34639 /* UPDATE ALA 010993. Start */ 34640 if ((*pintdat) != SISL_NULL) 34641 { 34642 for (ki = 0; ki < (*pintdat)->ipoint; ki++) 34643 if (po2->iobj == SISLCURVE) 34644 { 34645 if ((*pintdat)->vpoint[ki]->epar[0] > po1->c1->et[po1->c1->ik-1] && 34646 (*pintdat)->vpoint[ki]->epar[0] < po1->c1->et[po1->c1->in] && 34647 (*pintdat)->vpoint[ki]->epar[1] > po2->c1->et[po2->c1->ik-1] && 34648 (*pintdat)->vpoint[ki]->epar[1] < po2->c1->et[po2->c1->in]) 34649 goto out; 34650 } 34651 else 34652 { 34653 if ((*pintdat)->vpoint[ki]->epar[kturn2] > po1->c1->et[po1->c1->ik-1] && 34654 (*pintdat)->vpoint[ki]->epar[kturn2] < po1->c1->et[po1->c1->in] && 34655 (*pintdat)->vpoint[ki]->epar[kturn1] > po2->s1->et1[po2->s1->ik1-1] && 34656 (*pintdat)->vpoint[ki]->epar[kturn1] < po2->s1->et1[po2->s1->in1] && 34657 (*pintdat)->vpoint[ki]->epar[kturn1+1] > po2->s1->et2[po2->s1->ik2-1] && 34658 (*pintdat)->vpoint[ki]->epar[kturn1+1] < po2->s1->et2[po2->s1->in2]) 34659 goto out; 34660 } 34661 } 34662 /* UPDATE ALA 010993. End */ 34663 34664 if (po2->iobj == SISLCURVE) 34665 { 34666 double tstart1, tend1; 34667 double tstart2, tend2; 34668 34669 tstart1 = po1->c1->et[po1->c1->ik - 1]; 34670 tend1 = po1->c1->et[po1->c1->in]; 34671 spar[0] = (tstart1 + tend1) * (double) 0.5; 34672 34673 tstart2 = po2->c1->et[po2->c1->ik - 1]; 34674 tend2 = po2->c1->et[po2->c1->in]; 34675 spar[1] = (tstart2 + tend2) * (double) 0.5; 34676 34677 34678 s1770 (po1->o1->c1, po2->o1->c1, aepsge, tstart1, 34679 tstart2, tend1, tend2, spar[0], spar[1], spar, spar + 1, &kstat); 34680 if (kstat < 0) 34681 goto error; 34682 34683 if (kstat == 2) 34684 { 34685 /* Search for a better start point for the 34686 iteration. */ 34687 sh6cvvert(po1->c1, po2->c1, spar, spar+1); 34688 34689 /* Iterate. */ 34690 kstat = 0; 34691 s1770 (po1->o1->c1, po2->o1->c1, aepsge, tstart1, 34692 tstart2, tend1, tend2, spar[0], spar[1], 34693 spar, spar + 1, &kstat); 34694 if (kstat < 0) 34695 { kpos=__LINE__; goto error; } 34696 } 34697 34698 if (kstat == 1) 34699 /*Intersection point found. Control edges. */ 34700 if (DEQUAL (spar[0], tstart1) || DEQUAL (spar[0], tend1) 34701 || DEQUAL (spar[1], tstart2) || DEQUAL (spar[1], tend2)) 34702 kstat = 0; 34703 } 34704 else if (po2->iobj == SISLSURFACE) 34705 { 34706 double tstart, tend; 34707 double sstart[2], send[2]; 34708 34709 tstart = po1->c1->et[po1->c1->ik - 1]; 34710 tend = po1->c1->et[po1->c1->in]; 34711 spar[kturn2] = (tstart + tend) * (double) 0.5; 34712 34713 34714 sstart[0] = po2->s1->et1[po2->s1->ik1 - 1]; 34715 sstart[1] = po2->s1->et2[po2->s1->ik2 - 1]; 34716 34717 send[0] = po2->s1->et1[po2->s1->in1]; 34718 send[1] = po2->s1->et2[po2->s1->in2]; 34719 34720 spar[kturn1] = (sstart[0] + send[0]) * (double) 0.5; 34721 spar[kturn1 + 1] = (sstart[1] + send[1]) * (double) 0.5; 34722 34723 kstat = 0; 34724 s1772 (po1->o1->c1, po2->o1->s1, aepsge, tstart, sstart, tend, send, 34725 spar[kturn2], &spar[kturn1], 34726 &spar[kturn2], &spar[kturn1], &kstat); 34727 if (kstat < 0) 34728 goto error; 34729 34730 if (kstat == 3) 34731 { 34732 /* FLAT */ 34733 *jstat = 0; 34734 goto out; 34735 } 34736 34737 /* UJIK, Retry, with better startpoint */ 34738 if (kstat == 2) 34739 { 34740 /* No intersection point is found. Try again with a new 34741 start point to the iteration. */ 34742 34743 sh6closevert(po1->c1,po2->s1,&spar[kturn2],&spar[kturn1]); 34744 kstat = 0; 34745 s1772 (po1->o1->c1, po2->o1->s1, aepsge, tstart, sstart, tend, send, 34746 spar[kturn2], &spar[kturn1], 34747 &spar[kturn2], &spar[kturn1], &kstat); 34748 if (kstat < 0) 34749 goto error; 34750 } 34751 34752 if (kstat == 1) 34753 /*Intersection point found. Control edges. */ 34754 if (DEQUAL (spar[kturn2], tstart) || 34755 DEQUAL (spar[kturn2], tend) || 34756 DEQUAL (spar[kturn1], sstart[0]) || 34757 DEQUAL (spar[kturn1], send[0]) || 34758 DEQUAL (spar[kturn1 + 1], sstart[1]) || 34759 DEQUAL (spar[kturn1 + 1], send[1])) 34760 kstat = 0; 34761 } 34762 34763 if (kstat == 1) /* Intersection point found. */ 34764 { 34765 34766 *jstat = 1; /* Mark intersection found. */ 34767 34768 /* UJK newi */ 34769 if (qt) 34770 { 34771 /* We have an instance of a point, use it */ 34772 for (ki = 0; ki < qt->ipar; ki++) 34773 qt->epar[ki] = spar[ki]; 34774 } 34775 else 34776 { 34777 /* Making intersection point. */ 34778 double *nullp = SISL_NULL; 34779 qt = hp_newIntpt (po1->iobj + po2->iobj, spar, DZERO, SI_ORD, 34780 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 34781 0, 0, nullp, nullp); 34782 34783 if (qt == SISL_NULL) 34784 goto err101; 34785 34786 /* Uppdating pintdat. */ 34787 sh6idnpt (pintdat, &qt, 1, &kstat); 34788 if (kstat < 0) 34789 goto error; 34790 34791 /* Set pretopology */ 34792 if (po2->iobj == SISLCURVE) 34793 { 34794 /* Case curve, curve */ 34795 if (po1->c1->idim == 2) 34796 { 34797 /* Only 2D is treated */ 34798 sh1780 (po1, po2, 34799 aepsge, pintdat, qt, &no_new, &kstat); 34800 if (kstat < 0) 34801 goto error; 34802 } 34803 } 34804 else if (po2->iobj == SISLSURFACE) 34805 { 34806 /* Case curve, surface */ 34807 if (po1->c1->idim == 3) 34808 { 34809 /* Only 3D */ 34810 sh1779 ((kturn1 ? po1 : po2), 34811 (kturn1 ? po2 : po1), 34812 aepsge, pintdat, qt, &no_new, &kstat); 34813 if (kstat < 0) 34814 goto error; 34815 } 34816 } 34817 34818 } 34819 } 34820 } 34821 } 34822 else if (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE) 34823 { 34824 if ((*vedge)[0]->ipoint + (*vedge)[1]->ipoint > 1) 34825 { 34826 /* We have more than one intersection point on the edges, 34827 we therefor connect these points to each other. */ 34828 int ksimple; 34829 34830 if (po1->psimple == po2) 34831 ksimple = 1; 34832 else 34833 ksimple = 0; 34834 34835 sh1762_s9edgsscon ((*vedge), po1->s1, po2->s1, *pintdat, ksimple, 34836 aepsge, &kstat); 34837 if (kstat < 0) 34838 goto error; 34839 else if (kstat) 34840 *jstat = 0; /* Not a simple case. */ 34841 } 34842 } 34843 else 34844 goto err121; 34845 34846 goto out; 34847 34848 /* Error. Kind of object does not exist. */ 34849 34850 err121:*jstat = -121; 34851 s6err ("sh1762_s9update", *jstat, kpos); 34852 goto out; 34853 34854 /* Error in input. Conflicting dimensions. */ 34855 34856 err106:*jstat = -106; 34857 s6err ("s1770", *jstat, kpos); 34858 goto out; 34859 34860 /* Error in space allocation. */ 34861 34862 err101:*jstat = -101; 34863 s6err ("sh1762_s9update", *jstat, kpos); 34864 goto out; 34865 34866 /* Error in lower level routine. */ 34867 34868 error:*jstat = kstat; 34869 s6err ("sh1762_s9update", *jstat, kpos); 34870 goto out; 34871 34872 out:if (up != SISL_NULL) 34873 freearray (up); 34874 } 34875 34876 //=========================================================================== 34877 void sh1762_s9con (SISLObject * po1, SISLObject * po2, double aepsge, 34878 SISLIntdat ** pintdat, SISLEdge * vedge[], int *jstat) 34879 //=========================================================================== 34880 { 34881 int kstat = 0; /* Status variable. */ 34882 int ki,kj; /* Counter. */ 34883 int knum = 0; /* Number of intersection points on edges. */ 34884 SISLIntpt **up = SISL_NULL; /* Intersection points on edges. */ 34885 SISLdir *qd1, *qd2; /* Direction cones of objects. */ 34886 SISLIntpt *qpt; /* Evt 3. intersection point. */ 34887 int knpar=po1->iobj+po2->iobj; /* Number of parameter directions. */ 34888 int kcrv1; /* Indicates if 1. object is a curve. */ 34889 int kcrv2; /* Indicates if 2. object is a curve. */ 34890 int pretop[2][4]; 34891 SISLObject *qobj; 34892 int ind1, ind2, perm[2], obj, ipar; 34893 int klist1, klist2; 34894 int linear = FALSE; 34895 int kpt,kpt2; /* Number of elements in int. list. */ 34896 int kstat2 = 0; /* Remember status from s9toucharea. */ 34897 double mintang1; 34898 double mintang2; 34899 double tboxsize1; 34900 double tboxsize2; 34901 int kxintercept = (*jstat == 202); /* Extra interception */ 34902 34903 /*int loopcount;*/ /* Count up num intpts in a list. */ 34904 int one_edge = 0; /* Indicates if all intersection points 34905 lies on one edge in each surface. */ 34906 SISLPtedge *qpt1, *qpt2; /* Pointers used to traverse edge intersections. */ 34907 34908 /* Set kcrv parameters. */ 34909 34910 kcrv1 = (po1->iobj == SISLCURVE) ? 1 : 0; 34911 kcrv2 = (po2->iobj == SISLCURVE) ? 1 : 0; 34912 34913 if ((po1->iobj == SISLPOINT && po1->p1->idim == 1) || 34914 (po2->iobj == SISLPOINT && po2->p1->idim == 1)) 34915 *jstat = 0; 34916 else 34917 { 34918 34919 if (po1->iobj == SISLPOINT) qd1 = SISL_NULL; 34920 else 34921 qd1 = (po1->iobj == SISLCURVE ? po1->c1->pdir : po1->s1->pdir); 34922 34923 if (po2->iobj == SISLPOINT) qd2 = SISL_NULL; 34924 else 34925 qd2 = (po2->iobj == SISLCURVE ? po2->c1->pdir : po2->s1->pdir); 34926 34927 knum = 0; 34928 if (vedge[0] != SISL_NULL) knum += vedge[0]->ipoint; 34929 if (vedge[1] != SISL_NULL) knum += vedge[1]->ipoint; 34930 34931 if (knum > 0) 34932 { 34933 /* Organize intersection points on an array. */ 34934 34935 /* sh1762_s9edgpoint (vedge, &up, &knum, &kstat); */ 34936 sh6edgpoint (vedge, &up, &knum, &kstat); 34937 if (kstat < 0) 34938 goto error; 34939 } 34940 34941 /* We test coincide by linearity. If the two object is liniar 34942 and have end/edge intersection we just connect these 34943 intersection points, else we have no internal intersections. */ 34944 34945 if (po1->iobj == SISLCURVE) 34946 { 34947 tboxsize1 = po1->c1->pbox->e2max[2][0] - po1->c1->pbox->e2min[2][0]; 34948 if (po1->c1->idim > 1) 34949 tboxsize1 = MAX(tboxsize1, 34950 po1->c1->pbox->e2max[2][1] - po1->c1->pbox->e2min[2][1]); 34951 if (po1->c1->idim > 2) 34952 tboxsize1 = MAX(tboxsize1, 34953 po1->c1->pbox->e2max[2][2] - po1->c1->pbox->e2min[2][2]); 34954 mintang1 = aepsge/((double)2*tboxsize1); 34955 } 34956 else if (po1->iobj == SISLSURFACE) 34957 mintang1 = ANGULAR_TOLERANCE/(double)10; 34958 34959 if (po2->iobj == SISLCURVE) 34960 { 34961 tboxsize2 = po2->c1->pbox->e2max[2][0] - po2->c1->pbox->e2min[2][0]; 34962 if (po2->c1->idim > 1) 34963 tboxsize2 = MAX(tboxsize2, 34964 po2->c1->pbox->e2max[2][1] - po2->c1->pbox->e2min[2][1]); 34965 if (po2->c1->idim > 2) 34966 tboxsize2 = MAX(tboxsize2, 34967 po2->c1->pbox->e2max[2][2] - po2->c1->pbox->e2min[2][2]); 34968 mintang2 = aepsge/((double)2*tboxsize2); 34969 } 34970 else if (po2->iobj == SISLSURFACE) 34971 mintang2 = ANGULAR_TOLERANCE/(double)10; 34972 34973 /* if (qd1->igtpi || qd2->igtpi || qd1->aang > ANGULAR_TOLERANCE || 34974 qd2->aang > ANGULAR_TOLERANCE) */ 34975 if (qd1 == SISL_NULL || qd2 == SISL_NULL) 34976 *jstat = 0; 34977 else if (qd1->igtpi || qd2->igtpi || qd1->aang > mintang1 || 34978 qd2->aang > mintang2) 34979 *jstat = 0; 34980 else if (knum == 2) 34981 /* Newi (ujk) When linear and 2 points, we know how to set 34982 the pretopology for curves, this is done a bit further down */ 34983 linear = TRUE; 34984 else if (po1->iobj + po2->iobj < 2*SISLSURFACE) 34985 { 34986 if (knum > 1) 34987 { 34988 /* We have more than one intersection point on the edges. 34989 We therefore connect these points. */ 34990 /* UPDATE (ujk) don't like this connection */ 34991 34992 for (ki = 0; ki < knum; ki++) 34993 sh6tomain (up[ki], &kstat); 34994 34995 for (ki = 1; ki < knum; ki++) 34996 { 34997 sh6idcon (pintdat, &up[ki - 1], &up[ki], &kstat); 34998 if (kstat < 0) 34999 goto error; 35000 } 35001 *jstat = 1; 35002 } 35003 else 35004 *jstat = 2; 35005 35006 goto out; /* Test performed. */ 35007 } 35008 35009 if (knum >= 2 && 35010 po1->iobj == SISLSURFACE && 35011 po2->iobj == SISLSURFACE) 35012 { 35013 /* VSK. Change test on possibility of coincidence. 35014 More than two intersection points on the edges. 35015 Check if there is 35016 coincidence between the (surface) objects. 35017 Fetch all closed loops. Then call s9toucharea to 35018 see if the surfaces coincide everywhere inside the loop. */ 35019 35020 for (kstat2=0, kpt=0; kpt<knum; kpt+=kpt2) 35021 { 35022 sh6floop(up+kpt,knum-kpt,&kpt2,&kstat); 35023 35024 if (kstat == 1) 35025 { 35026 sh1762_s9toucharea (po1, po2, aepsge, kpt2, up+kpt, &kstat); 35027 /*fprintf (stdout, "\n s9_toucharea, kstat=%d", kstat); */ 35028 if (kstat < 0) 35029 goto error; 35030 kstat2 = MAX(kstat2,kstat); 35031 } 35032 else if (kpt == 0 && kpt2 == knum) 35033 { 35034 /* Only one open edge curve. Test if the entire 35035 curve lies on one edge in each surface. */ 35036 35037 for (one_edge=1, ki=1; ki<knum; ki++) 35038 { 35039 sh6comedg(po1, po2, up[ki-1], up[ki], &kstat); 35040 if (kstat < 0) goto error; 35041 35042 if (kstat != 3) one_edge = 0; /* Not a common edge. */ 35043 } 35044 } 35045 35046 } 35047 35048 *jstat = kstat2; 35049 35050 if (kstat2 == 1) 35051 { 35052 /* Do something with the pertopology. */ 35053 /* fprintf (stdout, "\n Coincidence, kstat=%d", kstat); */ 35054 } 35055 } 35056 35057 if (knum < 2 || (po1->iobj == SISLSURFACE && 35058 po2->iobj == SISLSURFACE && one_edge)) 35059 { 35060 /* Number of intersection points on the edges is less than 35061 two. Try to intercept further subdivision by performing 35062 improved box tests. */ 35063 35064 kstat = (kxintercept) ? 202 : 0; 35065 sh1762_s9intercept (po1, po2, aepsge, knum, up, &kstat); 35066 if (kstat < 0) 35067 goto error; 35068 35069 *jstat = kstat; 35070 } 35071 else if (knum == 2 && !(po1->iobj == SISLSURFACE && 35072 po2->iobj == SISLSURFACE)) 35073 { 35074 /* Two intersection points on the edges. Check if there is 35075 coincidence between the objects. */ 35076 35077 if (linear) 35078 kstat = 1; 35079 else 35080 { 35081 sh1762_s9coincide (po1, po2, aepsge, knum, up, &kstat); 35082 if (kstat < 0) 35083 goto error; 35084 } 35085 35086 *jstat = kstat; 35087 35088 if (kstat == 1) 35089 { 35090 int kstat1 = 0; 35091 35092 for (ki = 0; ki < knum; ki++) 35093 sh6tomain (up[ki], &kstat); 35094 35095 sh6idcon (pintdat, &up[0], &up[1], &kstat); 35096 if (kstat < 0) 35097 goto error; 35098 /* Newi (ujk) */ 35099 /* for (ind1 = 0; ind1 < 2; ind1++) 35100 for (ind2 = 0; ind2 < 4; ind2++) 35101 pretop[ind1][ind2] = SI_UNDEF; */ 35102 35103 /* Fetch existing pretopology. */ 35104 sh6gettop (up[0], -1, &pretop[0][0], &pretop[0][1], 35105 &pretop[0][2], &pretop[0][3], &kstat1); 35106 35107 sh6gettop (up[1], -1, &pretop[1][0], &pretop[1][1], 35108 &pretop[1][2], &pretop[1][3], &kstat1); 35109 35110 for (qobj = po1, obj = 0, ipar = 0; obj < 2; 35111 qobj = po2, obj++, ipar = ((po1->iobj == SISLCURVE) ? 1 : 2)) 35112 /* Pretopology for curves */ 35113 if (qobj->iobj == SISLCURVE) 35114 { 35115 if (up[0]->epar[ipar] < up[1]->epar[ipar]) 35116 { 35117 perm[0] = 0; 35118 perm[1] = 1; 35119 ind1 = 0; 35120 ind2 = 1; 35121 } 35122 else 35123 { 35124 perm[0] = 1; 35125 perm[1] = 0; 35126 ind1 = 1; 35127 ind2 = 0; 35128 } 35129 35130 /* Left point on curve */ 35131 pretop[ind1][1 + 2 * obj] = SI_ON; 35132 /* Point at edge */ 35133 if (pretop[ind1][2 * obj] != SI_IN && 35134 pretop[ind1][2 * obj] != SI_OUT && 35135 DEQUAL (up[perm[0]]->epar[ipar], 35136 qobj->c1->et[qobj->c1->ik - 1])) 35137 { 35138 /* Point at edge */ 35139 pretop[ind1][2 * obj] = SI_AT; 35140 } 35141 35142 /* Right point of curve */ 35143 pretop[ind2][2 * obj] = SI_ON; 35144 if (pretop[ind2][1 + 2 * obj] != SI_IN && 35145 pretop[ind2][1 + 2 * obj] != SI_OUT && 35146 DEQUAL (up[perm[1]]->epar[ipar], 35147 qobj->c1->et[qobj->c1->in])) 35148 { 35149 /* Point at edge */ 35150 pretop[ind2][1 + 2 * obj] = SI_AT; 35151 } 35152 35153 /* / Left point on curve / 35154 if (DEQUAL (up[perm[0]]->epar[ipar], 35155 qobj->c1->et[qobj->c1->ik - 1])) 35156 { 35157 * Point at edge * 35158 pretop[ind1][2 * obj] = SI_AT; 35159 pretop[ind1][1 + 2 * obj] = SI_ON; 35160 } 35161 else 35162 { 35163 pretop[ind1][1 + 2 * obj] = SI_ON; 35164 } 35165 35166 * Right point of curve * 35167 if (DEQUAL (up[perm[1]]->epar[ipar], 35168 qobj->c1->et[qobj->c1->in])) 35169 { 35170 * Point at edge * 35171 pretop[ind2][2 * obj] = SI_ON; 35172 pretop[ind2][1 + 2 * obj] = SI_AT; 35173 } 35174 else 35175 { 35176 pretop[ind2][2 * obj] = SI_ON; 35177 } */ 35178 35179 } 35180 sh6getlist (up[0], up[1], &klist1, &klist2, &kstat); 35181 if (kstat != 0) 35182 { 35183 kstat = -1; 35184 goto error; 35185 } 35186 35187 sh6settop (up[0], -1, pretop[0][0], pretop[0][1], 35188 pretop[0][2], pretop[0][3], &kstat); 35189 if (kstat < 0) 35190 goto error; 35191 35192 sh6settop (up[1], -1, pretop[1][0], pretop[1][1], 35193 pretop[1][2], pretop[1][3], &kstat); 35194 if (kstat < 0) 35195 goto error; 35196 35197 35198 if (knpar<4 && (*pintdat)->ipoint == 3) 35199 { 35200 /* There is 3 intersection points. Test if the 3. point 35201 lies between the endpoints of the coincidence curve. 35202 First fetch 3. point. */ 35203 35204 for (kj=0; kj<3; kj++) 35205 { 35206 qpt = (*pintdat)->vpoint[kj]; 35207 if (qpt!=up[0] && qpt!=up[1]) break; 35208 } 35209 35210 /* Check if the point lies inside the current 35211 intersection area. */ 35212 35213 sh6isinside(po1,po2,qpt,&kstat); 35214 if (kstat < 0) goto error; 35215 35216 if (kstat == 1) 35217 { 35218 /* Check parameter value of evt curves. */ 35219 35220 if ((kcrv1 && 35221 (up[0]->epar[0] < qpt->epar[0] && 35222 qpt->epar[0] < up[1]->epar[0])) || 35223 (up[1]->epar[0] < qpt->epar[0] && 35224 qpt->epar[0] < up[0]->epar[0])) kcrv1 = -1; 35225 35226 if ((kcrv2 && 35227 (up[0]->epar[po1->iobj] < qpt->epar[po1->iobj] && 35228 qpt->epar[po1->iobj] < up[1]->epar[po1->iobj])) || 35229 (up[1]->epar[po1->iobj] < qpt->epar[po1->iobj] && 35230 qpt->epar[po1->iobj] < up[0]->epar[po1->iobj])) 35231 kcrv2 = -1; 35232 35233 if (kcrv1 < 1 && kcrv2 < 1) 35234 { 35235 35236 /* The point lies inside the coincidence curve. 35237 Place it between the endpoints of the curve. */ 35238 35239 sh6tomain(qpt,&kstat); 35240 sh6insertpt(up[0],up[1],qpt,&kstat); 35241 if (kstat < 0) goto error; 35242 } 35243 } 35244 } 35245 35246 } 35247 } 35248 else if (knum > 2 && !(po1->iobj == SISLSURFACE && 35249 po2->iobj == SISLSURFACE)) 35250 { 35251 /* There is more than two edge intersection and it is no 35252 surface - surface intersection. Check if the edge 35253 intersections are already connected. */ 35254 35255 sh6floop(up, knum, &kpt2, &kstat); 35256 if (kpt2 == knum) 35257 /* All edge intersections lie in one loop. */ 35258 35259 *jstat = 1; 35260 else 35261 { 35262 /* Check if (one of) the curve(s) lies entirely in an 35263 intersection curve found at an edge. */ 35264 35265 if (po1->iobj == SISLCURVE) 35266 { 35267 for (qpt1=vedge[0]->prpt[0]; qpt1!=SISL_NULL; qpt1=qpt1->pnext) 35268 { 35269 for (qpt2=vedge[0]->prpt[1]; qpt2!=SISL_NULL; qpt2=qpt2->pnext) 35270 { 35271 /* UJK, aug 93, oo-loop in sh6isconn, BEOrd20786. */ 35272 int is_conn,kcount; 35273 is_conn = sh6isconnect(SISL_NULL, qpt1->ppt, qpt2->ppt); 35274 for (kcount = 0;kcount<(*pintdat)->ipoint;kcount++) 35275 (*pintdat)->vpoint[kcount]->marker = 0; 35276 35277 if (is_conn) break; 35278 } 35279 if (qpt2 != SISL_NULL) break; 35280 } 35281 35282 if (qpt1 != SISL_NULL && qpt2 != SISL_NULL) *jstat = 1; 35283 else *jstat = 0; 35284 } 35285 if (*jstat != 1 && po2->iobj == SISLCURVE) 35286 { 35287 for (qpt1=vedge[1]->prpt[0]; qpt1!=SISL_NULL; qpt1=qpt1->pnext) 35288 { 35289 for (qpt2=vedge[1]->prpt[1]; qpt2!=SISL_NULL; qpt2=qpt2->pnext) 35290 { 35291 /* UJK, aug 93, oo-loop in sh6isconn, BEOrd20786. */ 35292 int is_conn,kcount; 35293 is_conn = sh6isconnect(SISL_NULL, qpt1->ppt, qpt2->ppt); 35294 for (kcount = 0;kcount<(*pintdat)->ipoint;kcount++) 35295 (*pintdat)->vpoint[kcount]->marker = 0; 35296 35297 if (is_conn) break; 35298 } 35299 35300 if (qpt2 != SISL_NULL) break; 35301 } 35302 35303 if (qpt1 != SISL_NULL && qpt2 != SISL_NULL) *jstat = 1; 35304 else *jstat = 0; 35305 } 35306 } 35307 } 35308 } 35309 35310 goto out; 35311 35312 /* Error in subroutines */ 35313 35314 error:*jstat = kstat; 35315 s6err ("sh1762_s9con", *jstat, 0); 35316 goto out; 35317 35318 out: 35319 if (up != SISL_NULL) 35320 freearray (up); 35321 35322 return; 35323 } 35324 35325 //=========================================================================== 35326 void sh1762_s9intercept (SISLObject * po1, SISLObject * po2, double aepsge, 35327 int inmbpt, SISLIntpt * vintpt[], int *jstat) 35328 //=========================================================================== 35329 { 35330 int kstat = 0; /* Status variable. */ 35331 int kdim; /* Dimension of geometry space. */ 35332 int kleft = 0; /* Parameter to curve evaluation. */ 35333 int kleft2 = 0; /* Parameter to evaluator. */ 35334 int incr, ind; /* indexes and loop control */ 35335 int ratflag = 0; /* Indicates if rational object. */ 35336 int kxintercept = (*jstat == 202); /* Extra interception */ 35337 double tepsge; /* Local tolerance in 1D box test. */ 35338 double testpar[2]; /* Par val when treating help p. */ 35339 double trad; /* Radius of geometry object. */ 35340 double spar[2]; /* Parameter pair of surface. */ 35341 double scentre[3]; /* Centre of sphere of cylinder. */ 35342 double sder1[9]; /* Value and derivative of object. */ 35343 double sder2[9]; /* Pointer to value of second object.*/ 35344 double snorm1[3]; /* Normal to first surface. */ 35345 double snorm2[3]; /* Normal to second surface. */ 35346 double splitgeom[16]; /* Matrix description of a sphere 35347 or cylinder. */ 35348 SISLSurf *qs1=SISL_NULL; /* B-spline surface put into sphere 35349 or cylinder equation. */ 35350 SISLSurf *qs2=SISL_NULL; /* B-spline surface put into sphere 35351 or cylinder equation. */ 35352 SISLCurve *qc=SISL_NULL; /* B-spline curve put into sphere 35353 equation. */ 35354 SISLCurve *qc2=SISL_NULL; /* B-spline curve put into sphere 35355 equation. */ 35356 SISLPoint *pp1=SISL_NULL; 35357 SISLObject *qobjs; /* Pointer to surface object. */ 35358 SISLObject *qobjc; /* Pointer to curve object. */ 35359 35360 /* long time_before; 35361 long time_used = 0; */ 35362 35363 /* Test number of found intersection points. */ 35364 35365 /* VSK, 01/93. if (inmbpt > 1 || inmbpt < 0) 35366 goto err128; */ 35367 35368 *jstat = 0; 35369 35370 if (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE) 35371 { 35372 kdim = po1->s1->idim; 35373 35374 /* rotate_nmb++; 35375 time_before = clock(); */ 35376 35377 if (inmbpt == 0) 35378 { 35379 /* No intersections at the edges. */ 35380 35381 if (sh1762_xc % 2 == 0) 35382 { 35383 sh1839 (po1, po2, aepsge, &kstat); 35384 if (kstat < 0) 35385 goto error; 35386 } 35387 else 35388 { 35389 sh1839 (po2, po1, aepsge, &kstat); 35390 if (kstat < 0) 35391 goto error; 35392 } 35393 /* time_used = clock() - time_before; */ 35394 35395 if (kstat == 1) 35396 { 35397 if (sh1762_xc % 2 == 0) 35398 { 35399 sh6findsplit(po1->s1, po2->s1, aepsge, &kstat); 35400 if (kstat < 0) goto error; 35401 } 35402 else 35403 { 35404 sh6findsplit(po2->s1, po1->s1, aepsge, &kstat); 35405 if (kstat < 0) goto error; 35406 } 35407 } 35408 35409 if (kstat == 0 || kstat == 2) 35410 { 35411 *jstat = 2; 35412 goto out; 35413 } 35414 35415 } 35416 else 35417 { 35418 /* Evaluate the surfaces in the first intersection point, and 35419 use the partial derivatives in this point as rotation axises. */ 35420 35421 s1421(po1->s1,1,vintpt[0]->epar,&kleft,&kleft2,sder1,snorm1,&kstat); 35422 if (kstat < 0) goto error; 35423 35424 s1421(po2->s1,1,vintpt[0]->epar+2,&kleft,&kleft2,sder2,snorm2,&kstat); 35425 if (kstat < 0) goto error; 35426 35427 sh1834(po1,po2,aepsge,kdim,sder1+kdim,sder1+2*kdim,&kstat); 35428 if (kstat < 0) goto error; 35429 35430 if (kstat == 1 && 35431 fabs(s6ang(sder1+kdim,sder1+2*kdim,kdim) - PIHALF) > ANGULAR_TOLERANCE) 35432 { 35433 sh1834(po1,po2,aepsge,kdim,sder1+2*kdim,sder1+kdim,&kstat); 35434 if (kstat < 0) goto error; 35435 } 35436 35437 if (kstat == 1 && 35438 s6ang(sder1+kdim,sder2+kdim,kdim) > ANGULAR_TOLERANCE && 35439 s6ang(sder1+2*kdim,sder2+kdim,kdim) > ANGULAR_TOLERANCE) 35440 { 35441 sh1834(po1,po2,aepsge,kdim,sder2+kdim,sder2+2*kdim,&kstat); 35442 if (kstat < 0) goto error; 35443 } 35444 35445 if (kstat == 1 && 35446 fabs(s6ang(sder2+kdim,sder2+2*kdim,kdim) - PIHALF) > ANGULAR_TOLERANCE && 35447 s6ang(sder1+kdim,sder2+2*kdim,kdim) > ANGULAR_TOLERANCE && 35448 s6ang(sder1+2*kdim,sder2+2*kdim,kdim) > ANGULAR_TOLERANCE) 35449 35450 { 35451 sh1834(po1,po2,aepsge,kdim,sder2+2*kdim,sder2+kdim,&kstat); 35452 if (kstat < 0) goto error; 35453 } 35454 35455 if (kstat == 0 || kstat == 2) 35456 { 35457 *jstat = 2; 35458 goto out; 35459 } 35460 35461 } 35462 } 35463 else if ((po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE) || 35464 (po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE)) 35465 { 35466 /*We test if intersection is possible using 35467 rotated box tests. */ 35468 35469 if (po1->iobj == SISLSURFACE) 35470 { 35471 qobjs = po1; 35472 qobjc = po2; 35473 } 35474 else 35475 { 35476 qobjs = po2; 35477 qobjc = po1; 35478 } 35479 35480 /* Perform improved box-test. */ 35481 35482 /* rotate_nmb++; 35483 time_before = clock(); */ 35484 35485 /* Improved box-test based on main tangent of curve and 35486 main normal of surface. */ 35487 35488 sh1830 (qobjs, qobjc, aepsge, &kstat); 35489 if (kstat < 0) 35490 goto error; 35491 35492 if (kstat == 1) 35493 { 35494 sh1839 (qobjs, qobjc, aepsge, &kstat); 35495 if (kstat < 0) 35496 goto error; 35497 } 35498 /* time_used = clock() - time_before; */ 35499 /* 35500 if (kstat == 1) 35501 { 35502 Try to separate the objects by a sphere. 35503 35504 sh6sepgeom(qobjs->s1, qobjc->c1, aepsge, scentre, &trad, &kstat); 35505 if (kstat < 0) goto error; 35506 35507 If kstat = 0 is returned, no splitting geometry is found, 35508 and no further interception is to be tried. 35509 35510 if (kstat > 0) 35511 { 35512 The splitting geometry object is a sphere. 35513 Make a matrix of dimension (idim+1)x(idim+1) describing a hyper 35514 sphere as an implicit function. 35515 35516 s1321(scentre,trad,qobjc->c1->idim,1,splitgeom,&kstat); 35517 if (kstat < 0) goto error; 35518 35519 35520 35521 * Put the description of the surface and the curve into the 35522 * implicit equation for the sphere. 35523 * ---------------------------------------------------------- 35524 35525 ratflag = (qobjs->s1->ikind == 2 || qobjs->s1->ikind == 4) ? 1 : 0; 35526 s1320(qobjs->s1,splitgeom,1,ratflag,&qs1,&kstat); 35527 if (kstat < 0) goto error; 35528 35529 ratflag = (qobjc->c1->ikind == 2 || qobjc->c1->ikind == 4) ? 1 : 0; 35530 s1370(qobjc->c1,splitgeom,qobjc->c1->idim,1,ratflag,&qc,&kstat); 35531 if (kstat < 0) goto error; 35532 35533 Set up local tolerance. 35534 35535 tepsge = (double)2.0*trad*aepsge; 35536 35537 Make box of 1D surface. 35538 35539 sh1992su(qs1,2,tepsge,&kstat); 35540 if (kstat < 0) goto error; 35541 35542 Make box of 1D curve. 35543 35544 sh1992cu(qc,2,tepsge,&kstat); 35545 if (kstat < 0) goto error; 35546 35547 Check if the boxes overlap. 35548 35549 if (qs1->pbox->e2min[2][0] > qc->pbox->e2max[2][0] || 35550 qs1->pbox->e2max[2][0] < qc->pbox->e2min[2][0]) 35551 { 35552 35553 No intersection is possible. 35554 35555 *jstat = 2; 35556 goto out; 35557 } 35558 else kstat = 1; Mark possibility of intersection. 35559 } 35560 else kstat = 1; Mark possibility of intersection. 35561 } */ 35562 35563 if (kstat == 0 || kstat == 2) 35564 { 35565 *jstat = 2; 35566 goto out; 35567 } 35568 } 35569 else if (po1->iobj == SISLCURVE && po2->iobj == SISLCURVE && 35570 2*po1->c1->ik >= po1->c1->in && 2*po2->c1->ik >= po2->c1->in) 35571 { 35572 double spoint[3]; /* Point in splitting plane. */ 35573 double snorm[3]; /* Normal to splitting plane. */ 35574 double sn1[3], sn2[3]; 35575 int ki; 35576 double t1, t2; 35577 int ksign; 35578 35579 /* Find dimension of geometry space. */ 35580 35581 kdim = po1->c1->idim; 35582 if (kdim != po2->c1->idim) 35583 goto err106; 35584 35585 if (inmbpt == 1) 35586 { 35587 /* One intersection point between two curves found. Find splitting 35588 plane. */ 35589 /* First allocate space for local arrays. */ 35590 /* NEWI, (ujk), Lets try to find a help point */ 35591 35592 incr = 0; 35593 if (DEQUAL (vintpt[0]->epar[0], po1->c1->et[po1->c1->ik - 1])) 35594 { 35595 incr++; 35596 testpar[0] = po1->c1->et[po1->c1->in]; 35597 } 35598 else if (DEQUAL (vintpt[0]->epar[0], po1->c1->et[po1->c1->in])) 35599 { 35600 incr++; 35601 testpar[0] = po1->c1->et[po1->c1->ik - 1]; 35602 } 35603 35604 if (DEQUAL (vintpt[0]->epar[1], po2->c1->et[po2->c1->ik - 1])) 35605 { 35606 incr++; 35607 testpar[1] = po2->c1->et[po2->c1->in]; 35608 } 35609 else if (DEQUAL (vintpt[0]->epar[1], po2->c1->et[po2->c1->in])) 35610 { 35611 incr++; 35612 testpar[1] = po2->c1->et[po2->c1->ik - 1]; 35613 } 35614 35615 if (incr == 2) 35616 for (ind = 0; ind < vintpt[0]->no_of_curves; ind++) 35617 if (sh6ishelp (vintpt[0]->pnext[ind]) && 35618 DEQUAL (vintpt[0]->pnext[ind]->epar[0], testpar[0]) && 35619 DEQUAL (vintpt[0]->pnext[ind]->epar[1], testpar[1])) 35620 { 35621 *jstat = 2; 35622 goto out; 35623 } 35624 35625 /* Evaluate the curves in the intersection point. */ 35626 35627 s1221 (po1->c1, 1, vintpt[0]->epar[0], &kleft, sder1, &kstat); 35628 if (kstat < 0) 35629 goto error; 35630 35631 s1221 (po2->c1, 1, vintpt[0]->epar[1], &kleft, sder2, &kstat); 35632 if (kstat < 0) 35633 goto error; 35634 35635 /* Normalize derivatives. */ 35636 35637 t1 = s6norm(sder1+kdim, kdim, sder1+kdim, &kstat); 35638 t2 = s6norm(sder2+kdim, kdim, sder2+kdim, &kstat); 35639 ksign = (s6scpr(sder1+kdim, sder2+kdim, kdim) > 35640 DZERO) ? 1 : -1; 35641 for (ki=0; ki<kdim; ki++) 35642 { 35643 /* sder1[kdim+ki] *= t2; 35644 sder2[kdim+ki] *= t1; */ 35645 spoint[ki] = (double)0.5*(sder1[ki] + sder2[ki]); 35646 sn1[ki] = (double)0.5*(sder1[kdim+ki]+sder2[kdim+ki]); 35647 } 35648 if (kdim == 2) 35649 { 35650 snorm[0] = sn1[1]; /* KYS 5/7-94: normal corrected */ 35651 snorm[1] = -sn1[0]; 35652 } 35653 else if (kdim == 3) 35654 { 35655 s6crss(sder1+kdim, sder2+kdim, sn2); 35656 s6crss(sn1, sn2, snorm); 35657 } 35658 (void)s6norm(snorm, kdim, snorm, &kstat); 35659 if (!kstat) kstat = 1; 35660 else kstat = 0; 35661 } 35662 else if (inmbpt == 0 && po1->c1->pdir->aang < ANGULAR_TOLERANCE && 35663 po2->c1->pdir->aang < ANGULAR_TOLERANCE && 35664 s6ang(po1->c1->pdir->ecoef,po1->c1->pdir->ecoef,kdim) < 35665 (double)10*ANGULAR_TOLERANCE) 35666 { 35667 double tpar2; 35668 SISLPoint *pt = SISL_NULL; 35669 double *s1, *s2, *s3, *s4; 35670 35671 s1 = po1->c1->ecoef; 35672 s2 = po1->c1->ecoef+kdim*(po1->c1->in-1); 35673 s3 = po2->c1->ecoef; 35674 s4 = po2->c1->ecoef+kdim*(po2->c1->in-1); 35675 35676 /* Evaluate midpoint of first curve. */ 35677 35678 /* tpar1 = (double)0.5*(po1->c1->et[po1->c1->ik-1] + 35679 po1->c1->et[po1->c1->in]); 35680 s1221 (po1->c1, 0, tpar1, &kleft, sder1, &kstat); 35681 if (kstat < 0) 35682 goto error; */ 35683 if (MIN(s6dist(s1,s3,kdim),s6dist(s1,s4,kdim)) < 35684 MIN(s6dist(s2,s3,kdim),s6dist(s2,s4,kdim))) 35685 memcopy(sder1,s1,kdim,DOUBLE); 35686 else 35687 memcopy(sder1,s2,kdim,DOUBLE); 35688 35689 /* Find closest point on the other curve. */ 35690 35691 if ((pt = newPoint(sder1, kdim, 0)) == SISL_NULL) goto err101; 35692 35693 /* tpar2 = (double)0.5*(po2->c1->et[po2->c1->ik-1] + 35694 po2->c1->et[po2->c1->in]); */ 35695 if (s6dist(s3,sder1,kdim) < s6dist(s4,sder1,kdim)) 35696 tpar2 = po2->c1->et[po2->c1->ik-1]; 35697 else 35698 tpar2 = po2->c1->et[po2->c1->in]; 35699 s1771(pt, po2->c1, aepsge, po2->c1->et[po2->c1->ik-1], 35700 po2->c1->et[po2->c1->in], tpar2, &tpar2, &kstat); 35701 35702 if (pt) freePoint(pt); 35703 if (kstat < 0) 35704 goto error; 35705 35706 s1221 (po1->c1, 1, tpar2, &kleft, sder1, &kstat); 35707 if (kstat < 0) 35708 goto error; 35709 s1221 (po2->c1, 1, tpar2, &kleft, sder2, &kstat); 35710 if (kstat < 0) 35711 goto error; 35712 35713 /* Let the splitting plane pass through the midpoint of the 35714 points on the two curves and let the medium of the 35715 axises of the direction cones of the curves lie in the 35716 plane. */ 35717 35718 /* Normalize the tangents. */ 35719 35720 t1 = s6norm(sder1+kdim, kdim, sder1+kdim, &kstat); 35721 t2 = s6norm(sder2+kdim, kdim, sder2+kdim, &kstat); 35722 ksign = (s6scpr(sder1+kdim, sder2+kdim, kdim) > 35723 DZERO) ? 1 : -1; 35724 for (ki=0; ki<kdim; ki++) 35725 { 35726 /* sder1[kdim+ki] *= t2; 35727 sder2[kdim+ki] *= t1; */ 35728 spoint[ki] = (double)0.5*(sder1[ki] + sder2[ki]); 35729 sn1[ki] = (double)0.5*(sder1[kdim+ki] + 35730 (double)ksign*sder2[kdim+ki]); 35731 } 35732 35733 if (kdim == 3) 35734 { 35735 s6crss(sder1+kdim, sder2+kdim, sn2); 35736 s6crss(sn1, sn2, snorm); 35737 } 35738 else 35739 { 35740 snorm[0] = sn1[1]; /* KYS 5/7-94: normal corrected */ 35741 snorm[1] = -sn1[0]; 35742 } 35743 35744 (void)s6norm(snorm, kdim, snorm, &kstat); 35745 if (!kstat) kstat = 1; 35746 else kstat = 0; 35747 } 35748 else kstat = 1; 35749 35750 35751 /* Try to intercept with the found plane. */ 35752 35753 if (kstat == 0) 35754 { 35755 /* nmb_rotated++; */ 35756 sh1831(po1->c1, po2->c1, ksign, spoint, snorm, aepsge, &kstat); 35757 if (kstat < 0) goto error; 35758 } 35759 35760 if (kstat == 0) 35761 { 35762 /* nmb_succ_rotated++; */ 35763 *jstat = 2; 35764 goto out; 35765 } 35766 35767 35768 if (kstat == 1 && inmbpt == 0 && po1->c1->idim > 2) 35769 { 35770 /* kstat = 1; */ /* Make sure to subdivide further if there 35771 is two curves and no intersection point. */ 35772 /* Try to separate the objects by a sphere. */ 35773 35774 if (sh1762_xc % 2 == 0) 35775 { 35776 /* nmb_sep++; */ 35777 sh6sepcrv(po1->c1, po2->c1, aepsge, scentre, &trad, &kstat); 35778 if (kstat < 0) goto error; 35779 } 35780 else 35781 { 35782 /* nmb_sep++; */ 35783 sh6sepcrv(po2->c1, po1->c1, aepsge, scentre, &trad, &kstat); 35784 if (kstat < 0) goto error; 35785 } 35786 35787 /* If kstat = 0 is returned, no splitting geometry is found, 35788 and no further interception is to be tried. */ 35789 35790 if (kstat) 35791 { 35792 /* The splitting geometry object is a sphere. 35793 Make a matrix of dimension (idim+1)x(idim+1) describing a hyper 35794 sphere as an implicit function. */ 35795 35796 /* nmb_try_sep++; */ 35797 s1321(scentre,trad,po1->c1->idim,1,splitgeom,&kstat); 35798 if (kstat < 0) goto error; 35799 35800 35801 /* 35802 * Put the description of the surface and the curve into the 35803 * implicit equation for the sphere. 35804 * ---------------------------------------------------------- 35805 */ 35806 35807 ratflag = (po1->c1->ikind == 2 || po1->c1->ikind == 4) ? 1 : 0; 35808 s1370(po1->c1,splitgeom,po1->c1->idim,1,ratflag,&qc,&kstat); 35809 if (kstat < 0) goto error; 35810 35811 ratflag = (po2->c1->ikind == 2 || po2->c1->ikind == 4) ? 1 : 0; 35812 s1370(po2->c1,splitgeom,po2->c1->idim,1,ratflag,&qc2,&kstat); 35813 if (kstat < 0) goto error; 35814 35815 /* Set up local tolerance. */ 35816 35817 tepsge = (double)2.0*trad*aepsge; 35818 35819 /* Make box of 1D surface. */ 35820 35821 sh1992cu(qc,2,tepsge,&kstat); 35822 if (kstat < 0) goto error; 35823 35824 /* Make box of 1D curve. */ 35825 35826 sh1992cu(qc2,2,tepsge,&kstat); 35827 if (kstat < 0) goto error; 35828 35829 /* Check if the boxes overlap. */ 35830 35831 if (qc2->pbox->e2min[2][0] > qc->pbox->e2max[2][0] || 35832 qc2->pbox->e2max[2][0] < qc->pbox->e2min[2][0]) 35833 { 35834 35835 /* No intersection is possible. */ 35836 35837 /* numb_succ_sep++; */ 35838 *jstat = 2; 35839 goto out; 35840 } 35841 else kstat = 1; /* Mark possibility of intersection. */ 35842 } 35843 else kstat = 1; 35844 } 35845 else kstat = 1; 35846 } 35847 else if ((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT && 35848 po2->p1->idim == 2) || 35849 (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT && 35850 po1->p1->idim == 2)) 35851 { 35852 /* Compute the mid-parameter value of the surface. First set 35853 pointer to the surface. */ 35854 35855 if (po1->iobj == SISLSURFACE) qs1 = po1->s1; 35856 else qs1 = po2->s1; 35857 35858 spar[0] = (double)0.5*(qs1->et1[qs1->ik1-1] + qs1->et1[qs1->in1]); 35859 spar[1] = (double)0.5*(qs1->et2[qs1->ik2-1] + qs1->et2[qs1->in2]); 35860 35861 /* Evaluate the surface in the midpoint. */ 35862 35863 s1421(qs1, 1, spar, &kleft, &kleft2, sder1, snorm1, &kstat); 35864 if (kstat < 0) goto error; 35865 35866 if (s6ang(sder1+2, sder1+4, 2) < ANGULAR_TOLERANCE) 35867 { 35868 spar[0] = (double)0.5*(sder1[2]+sder1[4]); 35869 spar[1] = (double)0.5*(sder1[3]+sder1[5]); 35870 sh1834(po1, po2, aepsge, 2, spar, sder1+4, &kstat); 35871 if (kstat < 0) goto error; 35872 if (kstat == 5) kstat = 0; /* No 45 degree testing for rotated 35873 box test meens no danger of 35874 intersection point near corner that 35875 is not caught by the box test. */ 35876 } 35877 else kstat = 1; 35878 35879 qs1 = SISL_NULL; /* Make sure that the input surface is not freed. */ 35880 } 35881 else if (((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT && 35882 po2->p1->idim == 3) || 35883 (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT && 35884 po1->p1->idim == 3)) && kxintercept && sh1762_xc > 7 && sh1762_xc % 2 == 0) 35885 { 35886 if (po1->iobj == SISLSURFACE) 35887 { 35888 qs1 = po1->s1; 35889 pp1 = po2->p1; 35890 } 35891 else 35892 { 35893 qs1 = po2->s1; 35894 pp1 = po1->p1; 35895 } 35896 kdim = qs1->idim; 35897 35898 if (qs1->in1 > qs1->ik1 || qs1->in2 > qs1->ik2) 35899 kstat = 1; 35900 else 35901 { 35902 int ind1, ind2, ind3; 35903 int kpt = 0; 35904 int kcrv = 0; 35905 double *spar = SISL_NULL; 35906 SISLIntcurve **ucurve = SISL_NULL; 35907 double eps = 0.001*aepsge; 35908 35909 /* Find the closest points between the surface and the point */ 35910 s1954(qs1, pp1->ecoef, qs1->idim, 0.0, eps, &kpt, &spar, 35911 &kcrv, &ucurve, &kstat); 35912 if (kstat < 0) 35913 goto error; 35914 35915 35916 /* Test distance between the closest points on the surface and 35917 the point */ 35918 for (ind1=0; ind1<kpt; ind1++) 35919 { 35920 s1421(qs1, 0, spar+2*ind1, &kleft, &kleft2, sder1, 35921 snorm1, &kstat); 35922 if (s6dist(pp1->ecoef, sder1, kdim) <= aepsge) 35923 break; 35924 } 35925 35926 for (ind2=0; ind2<kcrv; ind2++) 35927 { 35928 for (ind3=0; ind3<ucurve[ind2]->ipoint; ind3++) 35929 { 35930 s1421(qs1, 0, ucurve[ind2]->epar1+2*ind3, &kleft, &kleft2, 35931 sder1, snorm1, &kstat); 35932 if (s6dist(pp1->ecoef, sder1, kdim) <= aepsge) 35933 break; 35934 } 35935 if (ind3 < ucurve[ind2]->ipoint) 35936 break; 35937 } 35938 35939 if (ind1 < kpt || ind2 < kcrv) 35940 kstat = 1; 35941 else kstat = 0; 35942 35943 /* fprintf(stdout,"%7.13f %7.13f %7.13f %7.13f \n",qs1->et1[0], 35944 qs1->et1[qs1->in1],qs1->et2[0],qs1->et2[qs1->in2]); 35945 fprintf(stdout,"Point-srf : kstat = %d\n",kstat); */ 35946 35947 if (spar) 35948 freearray(spar); 35949 if (ucurve) 35950 freeIntcrvlist(ucurve, kcrv); 35951 } 35952 qs1 = SISL_NULL; 35953 } 35954 else kstat = 1; 35955 35956 35957 *jstat = (kstat == 0 || kstat == 2) ? 2 : 0; 35958 goto out; 35959 35960 /* Error in scratch allocation. */ 35961 35962 err101: *jstat = -101; 35963 goto out; 35964 35965 /* Error in input. Confliciting dimensions. */ 35966 35967 err106:*jstat = -106; 35968 goto out; 35969 35970 /* Wrong number of intersection points on edge. */ 35971 35972 /* err128:*jstat = -128; 35973 goto out; */ 35974 35975 /* Error in lower level routine. */ 35976 35977 error:*jstat = kstat; 35978 goto out; 35979 35980 out: 35981 /* Free scratch used by 1D surfaces. */ 35982 35983 if (qs1 != SISL_NULL) freeSurf(qs1); 35984 if (qs2 != SISL_NULL) freeSurf(qs2); 35985 if (qc != SISL_NULL) freeCurve(qc); 35986 if (qc2 != SISL_NULL) freeCurve(qc2); 35987 35988 /* rotate_box_time += time_used; */ 35989 return; 35990 } 35991 35992 //=========================================================================== 35993 void sh1762_s9coincide (SISLObject * po1, SISLObject * po2, double aepsge, 35994 int inmbpt, SISLIntpt * vintpt[], int *jstat) 35995 //=========================================================================== 35996 { 35997 int kstat = 0; /* Status variable. */ 35998 int kdim; /* Dimension of geometry space. */ 35999 int kcur; /* Indicates the curve in curve-surface 36000 intersection. */ 36001 int kn; /* Counter. */ 36002 int kleft1 = 0, kleft2 = 0; /* Parameters used in evaluation. */ 36003 int kind1,kind2; /* Dummy parameters to sh6getlist. */ 36004 double tang; /* Angle between vectors. */ 36005 double *snorm; /* Pointer to surface normal. */ 36006 double *sder1 = SISL_NULL; /* Array containing position etc. of objects. */ 36007 double *sder2; /* Pointer to position of second object. */ 36008 SISLSurf *qs; /* Pointer to surface. */ 36009 SISLCurve *qc; /* Pointer to curve. */ 36010 SISLPoint *qp; 36011 36012 if (inmbpt != 2) 36013 goto err128; 36014 36015 if ((po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE) || 36016 (po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE)) 36017 { 36018 /* We test coincidence for curve-surface. */ 36019 36020 /* VSK, 10.92. First check if the points are already connected. */ 36021 36022 sh6getlist(vintpt[0],vintpt[1],&kind1,&kind2,&kstat); 36023 if (kstat < 0) goto error; 36024 36025 if (kstat == 0) 36026 { 36027 /* The points are already connected. */ 36028 36029 *jstat = 1; 36030 goto out; 36031 } 36032 36033 if (po1->iobj == SISLSURFACE) 36034 { 36035 qs = po1->s1; 36036 qc = po2->c1; 36037 kcur = 0; 36038 } 36039 else 36040 { 36041 qs = po2->s1; 36042 qc = po1->c1; 36043 kcur = 1; 36044 } 36045 36046 /* Allocate space for local arrays. */ 36047 36048 if ((sder1 = newarray (6 * qc->idim, double)) == SISL_NULL) 36049 goto err101; 36050 sder2 = sder1 + 2 * qc->idim; 36051 snorm = sder2 + 3 * qc->idim; 36052 36053 for (kn = 0; kn < 2; kn++) 36054 { 36055 /* We have to test if the curve and the surface 36056 have coinciding derivatives in intersection ponts. */ 36057 36058 s1221 (qc, 1, vintpt[kn]->epar[(kcur ? 0 : 2)], &kleft1, sder1, &kstat); 36059 if (kstat < 0) 36060 goto error; 36061 36062 s1421 (qs, 1, vintpt[kn]->epar + kcur, &kleft1, &kleft2, sder2, snorm, &kstat); 36063 if (kstat < 0) 36064 goto error; 36065 else if (kstat > 0) 36066 { 36067 /* Singular point. */ 36068 36069 *jstat = 0; 36070 goto out; 36071 } 36072 /* 36073 tang = s6ang (sder1 + qc->idim, snorm, qc->idim); 36074 36075 if (PIHALF - tang > ANGULAR_TOLERANCE) 36076 { 36077 *jstat = 0; 36078 goto out; 36079 } 36080 */ 36081 } 36082 /* Removed the angle test. M.F. 30/8/91. */ 36083 /* If the first derivatives are equal we call a routine 36084 to test further for coincidence. */ 36085 36086 s1785 (qc, qs, aepsge, vintpt[0]->epar, vintpt[1]->epar, kcur, &kstat); 36087 if (kstat < 0) 36088 goto error; 36089 36090 } 36091 else if (po1->iobj == SISLCURVE && po2->iobj == SISLCURVE) 36092 { 36093 kdim = po1->c1->idim; 36094 if (kdim != po2->c1->idim) 36095 goto err106; 36096 36097 /* Test coincidence between two curves. First allocate 36098 space for local arrays. */ 36099 36100 if ((sder1 = newarray (8 * kdim, double)) == SISL_NULL) 36101 goto err101; 36102 sder2 = sder1 + 4 * kdim; 36103 36104 /* Evaluate the curves in the first intersection point. */ 36105 36106 s1221 (po1->c1, 1, vintpt[0]->epar[0], &kleft1, sder1, &kstat); 36107 if (kstat < 0) 36108 goto error; 36109 36110 s1221 (po2->c1, 1, vintpt[0]->epar[1], &kleft1, sder2, &kstat); 36111 if (kstat < 0) 36112 goto error; 36113 36114 /* Evaluate the curves in the second intersection point. */ 36115 36116 s1221 (po1->c1, 1, vintpt[1]->epar[0], &kleft1, sder1 + (2 * kdim), &kstat); 36117 if (kstat < 0) 36118 goto error; 36119 36120 s1221 (po2->c1, 1, vintpt[1]->epar[1], &kleft2, sder2 + (2 * kdim), &kstat); 36121 if (kstat < 0) 36122 goto error; 36123 36124 /* Test if the curves are parallel in the endpoints. */ 36125 36126 tang = s6ang (sder1 + kdim, sder2 + kdim, kdim); 36127 36128 if (tang > ANGULAR_TOLERANCE) 36129 { 36130 *jstat = 0; 36131 goto out; 36132 } 36133 36134 tang = s6ang (sder1 + (3 * kdim), sder2 + (3 * kdim), kdim); 36135 36136 if (tang > ANGULAR_TOLERANCE) 36137 { 36138 *jstat = 0; 36139 goto out; 36140 } 36141 36142 s1786 (po1->c1, po2->c1, aepsge, vintpt[0]->epar, vintpt[1]->epar, &kstat); 36143 if (kstat < 0) 36144 goto error; 36145 36146 } 36147 else if ((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT && 36148 po2->p1->idim >= 2) || 36149 (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT && 36150 po1->p1->idim >= 2)) 36151 { 36152 if (po1->iobj == SISLSURFACE) 36153 { 36154 qs = po1->s1; 36155 qp = po2->p1; 36156 } 36157 else 36158 { 36159 qs = po2->s1; 36160 qp = po1->p1; 36161 } 36162 36163 /* Allocate space for local arrays. */ 36164 36165 if ((sder1 = newarray (7 * qs->idim, double)) == SISL_NULL) 36166 goto err101; 36167 sder2 = sder1 + 3 * qs->idim; 36168 snorm = sder2 + 3 * qs->idim; 36169 36170 /* Evaluate the surface in the intersection points at the edges. */ 36171 36172 s1421 (qs, 1, vintpt[0]->epar, &kleft1, &kleft2, sder1, snorm, &kstat); 36173 if (kstat < 0) 36174 goto error; 36175 36176 s1421 (qs, 1, vintpt[1]->epar, &kleft1, &kleft2, sder2, snorm, &kstat); 36177 if (kstat < 0) 36178 goto error; 36179 36180 /* Test if this is a singular situation. */ 36181 36182 if (s6ang(sder1+qs->idim, sder1+2*qs->idim, qs->idim) <= 36183 ANGULAR_TOLERANCE && 36184 s6ang(sder2+qs->idim, sder2+2*qs->idim, qs->idim) <= 36185 ANGULAR_TOLERANCE) 36186 { 36187 /* Perform marching to check if there is coincidence between 36188 the intersection points. */ 36189 36190 /* fprintf(stdout,"Try coincidence marching \n"); 36191 fprintf(stdout,"%7.13f %7.13f %7.13f %7.13f \n",qs->et1[0], 36192 qs->et1[qs->in1],qs->et2[0],qs->et2[qs->in2]); */ 36193 36194 s1789(qp, qs, aepsge, vintpt[0]->epar, vintpt[1]->epar, &kstat); 36195 if (kstat < 0) goto error; 36196 /* fprintf(stdout,"kstat = %d \n",kstat); */ 36197 } 36198 else 36199 kstat = 0; /* No coincidence. */ 36200 } 36201 36202 *jstat = kstat; 36203 goto out; 36204 36205 /* Error in scratc allocation. */ 36206 36207 err101:*jstat = -101; 36208 goto out; 36209 36210 /* Error in input. Conflicting dimensions. */ 36211 36212 err106:*jstat = -106; 36213 goto out; 36214 36215 /* Wrong number of edge intersections found. */ 36216 36217 err128:*jstat = -128; 36218 goto out; 36219 36220 /* Error in lower level routine. */ 36221 36222 error:*jstat = kstat; 36223 goto out; 36224 36225 out: 36226 36227 /* Free scratch occupied by local array. */ 36228 36229 if (sder1 != SISL_NULL) 36230 freearray (sder1); 36231 36232 return; 36233 } 36234 36235 //=========================================================================== 36236 void sh1762_s9toucharea (SISLObject * po1, SISLObject * po2, double aepsge, 36237 int inmbpt, SISLIntpt * vintpt[], int *jstat) 36238 //=========================================================================== 36239 { 36240 int kstat = 0; /* Local status variable. */ 36241 int kntest1, kntest2; /* Number of locations to test coincidence in 36242 both parameter directions. */ 36243 double tint1, tint2; /* Parameter interval between testing spots. */ 36244 int ki,kj; /* Counters. */ 36245 int kdim = po1->s1->idim; /* Dimension of geometry space. */ 36246 double spar[2]; /* Parameter of testing spot. */ 36247 double sder1[3]; /* Position of first surface. */ 36248 double sder2[3]; /* Position of second surface. */ 36249 double snorm1[3], snorm2[3]; /* Dummy normals of surface. */ 36250 int kleft11 = 0, kleft12 = 0; /* Pointers into knot arrays of surface. */ 36251 int kleft21 = 0, kleft22 = 0; /* Pointers into knot arrays of surface. */ 36252 int kn11 = po1->s1->in1; 36253 int kn12 = po1->s1->in2; 36254 int kk11 = po1->s1->ik1; 36255 int kk12 = po1->s1->ik2; 36256 double *st11 = po1->s1->et1; 36257 double *st12 = po1->s1->et2; 36258 int kn21 = po2->s1->in1; 36259 int kn22 = po2->s1->in2; 36260 int kk21 = po2->s1->ik1; 36261 int kk22 = po2->s1->ik2; 36262 double *st21 = po2->s1->et1; 36263 double *st22 = po2->s1->et2; 36264 SISLPoint *pt = SISL_NULL; /* Point in point surface iteration. */ 36265 double sstart[2], send[2]; /* Parameter boundaries of second surface. */ 36266 double spar2[2]; /* Parameter value of second surface. */ 36267 36268 /* Set number of locations to test coincidence. */ 36269 36270 kntest1 = 30*(kn11 - kk11 + 1); 36271 kntest2 = 30*(kn12 - kk12 + 1); 36272 tint1 = (st11[kn11] - st11[kk11-1])/(double)(kntest1+1); 36273 tint2 = (st12[kn12] - st12[kk12-1])/(double)(kntest2+1); 36274 36275 /* Set parameter boundaries and midpoint of second surface. */ 36276 36277 sstart[0] = st21[kk21-1]; 36278 sstart[1] = st22[kk22-1]; 36279 send[0] = st21[kn21]; 36280 send[1] = st22[kn22]; 36281 spar2[0] = (double)0.5*(sstart[0] + send[0]); 36282 spar2[1] = (double)0.5*(sstart[1] + send[1]); 36283 36284 for (spar[0]=st11[kk11-1]+tint1, ki=0; ki<kntest1; ki++, spar[0]+=tint1) 36285 { 36286 for (spar[1]=st12[kk12-1]+tint2, kj=0; kj<kntest2; kj++, spar[1]+=tint2) 36287 { 36288 /* Evaluate first surface. */ 36289 36290 s1421(po1->s1, 0, spar, &kleft11, &kleft12, sder1, snorm1, &kstat); 36291 if (kstat < 0) goto error; 36292 36293 /* Find closest point on the other surface. */ 36294 36295 if ((pt = newPoint(sder1, kdim, 0)) == SISL_NULL) goto err101; 36296 36297 s1773(pt, po2->s1, aepsge, sstart, send, spar2, spar2, &kstat); 36298 if (kstat < 0) goto error; 36299 36300 /* Evalutate second surface. */ 36301 36302 s1421(po2->s1, 0, spar2, &kleft21, &kleft22, sder2, snorm2, &kstat); 36303 if (kstat < 0) goto error; 36304 36305 if (pt != SISL_NULL) freePoint(pt); 36306 pt = SISL_NULL; 36307 36308 /* Check distance between the closest points. */ 36309 36310 if (s6dist(sder1, sder2, kdim) > aepsge) break; /* Not a coincidence.*/ 36311 } 36312 if (kj < kntest2) break; /* Not a coincidence. */ 36313 } 36314 36315 *jstat = (ki==kntest1 && kj==kntest2) ? 1 : 0; 36316 goto out; 36317 36318 err101 : *jstat = -101; /* Error in scratch allocation. */ 36319 goto out; 36320 36321 error : *jstat = kstat; /* Error in lower level function. */ 36322 goto out; 36323 36324 out: 36325 if (pt != SISL_NULL) freePoint(pt); 36326 36327 return; 36328 } 36329 36330 //=========================================================================== 36331 void sh1762_s9edgsscon (SISLEdge * vedge[], SISLSurf * ps1, SISLSurf * ps2, 36332 SISLIntdat * rintdat, int isimple, double aepsge, 36333 int *jstat) 36334 //=========================================================================== 36335 { 36336 int kstat,kstat1,kstat2; 36337 int kmarch = 0; /* Indicates if marching is to be done. */ 36338 int *ldir = SISL_NULL; /* Local array containing one of the statusvalues for 36339 * each point: 36340 * 0 - The intersect.curve is parallel to one 36341 * parameter direction. 36342 * 1 - The intersect.curve has direction into the 36343 * domain. 36344 * -1 - The intersect.curve has direction out of the 36345 * domain. 36346 * 2 - The point is singulear. 36347 * 10 - The intersect.curve touch one corner of the 36348 * domain. 36349 * -------------------------------------------------- 36350 */ 36351 36352 int lant[2]; 36353 unsigned char *edg = SISL_NULL; 36354 double *sval1 = SISL_NULL; 36355 SISLIntpt **uipt = SISL_NULL; 36356 SISLIntpt **uinewpt = SISL_NULL; 36357 36358 double *spar = SISL_NULL; /* Local array with parameter values used as 36359 input to s9surmarch. */ 36360 int *lperm = SISL_NULL; /* Local permutation array after sorting 36361 input points to s9surmarch.*/ 36362 int *lpermdir = SISL_NULL; /* Local array with status values used as 36363 input to s9surmarch. */ 36364 int lstatus[4]; /* Local array containing the possible status 36365 constants -1,1,0,2. */ 36366 int lnumb[4]; /* Local array containing the number of points 36367 with status lstatus. */ 36368 36369 double *sparout = SISL_NULL; /* Local array with parameter values used as 36370 output from s9surmarch.*/ 36371 int *lpar = SISL_NULL; /* Local array containing the connection information 36372 from s9surmarch.*/ 36373 int kpoints; /* Local integer containing number of points returned 36374 from s9surmarch.*/ 36375 double *nullp = SISL_NULL; 36376 int klist1, klist2; /* List index in iintpt. */ 36377 36378 double tdist; /* Distance between surfaces in point. */ 36379 double tref; /* Reference value. */ 36380 double spos[4]; /* Parameter value of singular point. */ 36381 double start[4]; /* Start parameter to iteration. */ 36382 double slimit[8]; /* Limits to the parameter areas. */ 36383 SISLIntpt *qsing=SISL_NULL; /* Singular intersection point. */ 36384 36385 /* Experiment UJK, sept 92 (BEOrd12754) */ 36386 double tolpar = (double) 0.001; 36387 36388 /* double tolpar = (double) 0.01; */ 36389 36390 if (ps1->idim != 3 || ps2->idim != 3) 36391 goto err200; 36392 36393 *jstat = 0; 36394 36395 if (vedge[0] == SISL_NULL) 36396 lant[0] = 0; 36397 else 36398 lant[0] = vedge[0]->ipoint; 36399 36400 if (vedge[1] == SISL_NULL) 36401 lant[1] = 0; 36402 else 36403 lant[1] = vedge[1]->ipoint; 36404 36405 36406 if (lant[0] + lant[1] > 1) 36407 { 36408 int kn1, kn, ki, kj, kv, kant, klfs, klft, kdir, kpar; 36409 double *sval2, *snorm1, *snorm2, *stang, *sdec1, *sdec2; 36410 SISLPtedge *qpt; 36411 double tang; 36412 36413 kant = lant[0] + lant[1]; 36414 36415 /* Allocate array of pointers to the points. */ 36416 36417 if ((uipt = newarray (kant, SISLIntpt *)) == SISL_NULL) 36418 goto err101; 36419 if ((edg = new0array (kant, unsigned char)) == SISL_NULL) 36420 goto err101; 36421 if ((ldir = new0array (kant, int)) == SISL_NULL) 36422 goto err101; 36423 if ((sval1 = newarray (33 * kant, double)) == SISL_NULL) 36424 goto err101; 36425 sval2 = sval1 + 9 * kant; 36426 snorm1 = sval2 + 9 * kant; 36427 snorm2 = snorm1 + 3 * kant; 36428 stang = snorm2 + 3 * kant; 36429 sdec1 = stang + 3 * kant; 36430 sdec2 = sdec1 + 3 * kant; 36431 36432 36433 /* UPDATE (ujk) Main point vs helppoints covered ? */ 36434 /* Update the arrays. */ 36435 36436 for (kn1 = 0, kn = 0; kn < 2; kn++) 36437 if (lant[kn] > 0) 36438 for (kj = 0; kj < vedge[kn]->iedge; kj++) 36439 for (qpt = vedge[kn]->prpt[kj]; qpt != SISL_NULL; qpt = qpt->pnext) 36440 { 36441 for (ki = 0; ki < kn1; ki++) 36442 { 36443 if (qpt->ppt == uipt[ki]) 36444 break; 36445 } 36446 if (ki == kn1) 36447 uipt[kn1++] = qpt->ppt; 36448 36449 edg[ki] |= 1 << (vedge[kn]->iedge * kn + kj); 36450 } 36451 36452 if (kn1 > 1) 36453 for (ki = 0; ki < kn1; ki++) 36454 { 36455 kv = 3 * ki; 36456 kn = 9 * ki; 36457 /* UPDATE (ujk) : getgeom !! */ 36458 36459 klfs = klft = 0; 36460 s1421 (ps1, 1, uipt[ki]->epar, &klfs, &klft, sval1 + kn, snorm1 + kv, 36461 &kstat); 36462 if (kstat < 0) 36463 goto error; 36464 else if (kstat > 0) 36465 { 36466 ldir[ki] = 2; 36467 continue; 36468 } 36469 36470 klfs = klft = 0; 36471 s1421 (ps2, 1, uipt[ki]->epar + 2, &klfs, &klft, sval2 + kn, snorm2 + kv, 36472 &kstat); 36473 if (kstat < 0) 36474 goto error; 36475 else if (kstat > 0) 36476 { 36477 ldir[ki] = 2; 36478 continue; 36479 } 36480 36481 tang = s6ang (snorm1 + kv, snorm2 + kv, 3); 36482 if (tang < REL_PAR_RES) 36483 /* if (tang < ANGULAR_TOLERANCE) */ 36484 { 36485 ldir[ki] = 2; 36486 continue; 36487 } 36488 36489 s6crss (snorm1 + kv, snorm2 + kv, stang + kv); 36490 36491 s6decomp (stang + kv, sdec1 + kv, sval1 + kn + 3, sval1 + kn + 6, 36492 snorm1 + kv, &kstat); 36493 if (kstat < 0) 36494 goto error; 36495 else if (kstat > 0) 36496 { 36497 ldir[ki] = 2; 36498 continue; 36499 } 36500 36501 36502 s6decomp (stang + kv, sdec2 + kv, sval2 + kn + 3, sval2 + kn + 6, 36503 snorm2 + kv, &kstat); 36504 if (kstat < 0) 36505 goto error; 36506 else if (kstat > 0) 36507 { 36508 ldir[ki] = 2; 36509 continue; 36510 } 36511 36512 for (kpar = 1, kj = 0; kj < 8; kj++) 36513 if ((edg[ki] & 1 << kj) == 1 << kj) 36514 { 36515 switch (kj) 36516 { 36517 case 0: 36518 tang = s6ang (stang + kv, sval1 + kn + 3, 3); 36519 kdir = (sdec1[kv + 1] > DZERO ? 1 : -1); 36520 break; 36521 case 4: 36522 tang = s6ang (stang + kv, sval2 + kn + 3, 3); 36523 kdir = (sdec2[kv + 1] > DZERO ? 1 : -1); 36524 break; 36525 case 1: 36526 tang = s6ang (stang + kv, sval1 + kn + 6, 3); 36527 kdir = (sdec1[kv] > DZERO ? -1 : 1); 36528 break; 36529 case 5: 36530 tang = s6ang (stang + kv, sval2 + kn + 6, 3); 36531 kdir = (sdec2[kv] > DZERO ? -1 : 1); 36532 break; 36533 case 2: 36534 tang = s6ang (stang + kv, sval1 + kn + 3, 3); 36535 kdir = (sdec1[kv + 1] > DZERO ? -1 : 1); 36536 break; 36537 case 6: 36538 tang = s6ang (stang + kv, sval2 + kn + 3, 3); 36539 kdir = (sdec2[kv + 1] > DZERO ? -1 : 1); 36540 break; 36541 case 3: 36542 tang = s6ang (stang + kv, sval1 + kn + 6, 3); 36543 kdir = (sdec1[kv] > DZERO ? 1 : -1); 36544 break; 36545 case 7: 36546 tang = s6ang (stang + kv, sval2 + kn + 6, 3); 36547 kdir = (sdec2[kv] > DZERO ? 1 : -1); 36548 } 36549 36550 if (tang < tolpar) 36551 kdir = 0; 36552 /* if (tang < REL_PAR_RES) 36553 kdir = 0; */ 36554 /* if (tang < ANGULAR_TOLERANCE) kdir = 0;*/ 36555 if (kdir == 0) 36556 kpar = 0; 36557 else if (ldir[ki] != kdir) 36558 { 36559 if (ldir[ki] == 0) 36560 ldir[ki] = kdir; 36561 else 36562 { 36563 ldir[ki] = 10; 36564 break; 36565 } 36566 } 36567 } 36568 if (kpar == 0 && ldir[ki] != 10) 36569 ldir[ki] = 0; 36570 } 36571 36572 36573 /* When only two points, check if they are connected. */ 36574 if (kn1 == 2) 36575 { 36576 sh6getlist (uipt[0], uipt[1], &klist1, &klist2, &kstat); 36577 if (kstat == 0) 36578 kn1 = 0; 36579 } 36580 36581 36582 for (kv = ki = 0; ki < kn1; ki++) 36583 if (ldir[ki] < 10) 36584 kv++; 36585 36586 if (kv == 1 && kn1 > 1 ) 36587 { 36588 int i,j; 36589 36590 if (kn1 > 2) 36591 { 36592 *jstat = 0; 36593 for (i=0;i<kn1;i++) 36594 if (ldir[i] == 1 || ldir[i] == -1) 36595 *jstat = 1; 36596 goto out; 36597 } 36598 36599 36600 if (ldir[0] == 1 || ldir[0] == -1) 36601 { 36602 i = 0; 36603 j = 1; 36604 } 36605 else if (ldir[1] == 1 || ldir[1] == -1) 36606 { 36607 i = 1; 36608 j = 0; 36609 } 36610 else i = -1; 36611 36612 if (i >=0) 36613 { 36614 /* We have one point, and the direction is in/out. 36615 The other point is touching a corner it is probably 36616 an error and the point must be close to tangential.*/ 36617 if (ldir[i] == -1) 36618 { 36619 int k=j; 36620 j = i; 36621 i = k; 36622 } 36623 36624 sh6tomain (uipt[i], &kstat); 36625 sh6tomain (uipt[j], &kstat); 36626 36627 sh6idcon (&rintdat, &uipt[i], &uipt[j], &kstat); 36628 if (kstat < 0) 36629 goto error; 36630 sh6setdir (uipt[i], uipt[j], &kstat); 36631 if (kstat < 0) 36632 goto error; 36633 *jstat = 0; 36634 } 36635 } 36636 else if (kv < 2) 36637 /* Less than two points, it's a simple case. */ 36638 *jstat = 0; 36639 36640 else if (kv > 8) 36641 /* More than eight points, it's not a simple case. */ 36642 *jstat = 1; 36643 36644 else if (kv == 4 && isimple > 0) 36645 { 36646 /* Connect point in to closest point out. */ 36647 int kinn = 0, kout = 0; 36648 int ki, ki1, ki2, ko1, ko2; 36649 36650 for (ki = 0; ki < kn1; ki++) 36651 if (ldir[ki] == 1) 36652 { 36653 if (kinn == 0) 36654 ki1 = ki; 36655 else 36656 ki2 = ki; 36657 kinn++; 36658 } 36659 else if (ldir[ki] == -1) 36660 { 36661 if (kout == 0) 36662 ko1 = ki; 36663 else 36664 ko2 = ki; 36665 kout++; 36666 } 36667 36668 if (kinn == 2 && kout == 2) 36669 { 36670 double tdist1, tdist2, tdir1, tdir2; 36671 36672 tdist1 = s6dist (sval1 + (ki1 * 9), sval1 + (ko1 * 9), 3); 36673 tdist2 = s6dist (sval1 + (ki1 * 9), sval1 + (ko2 * 9), 3); 36674 36675 tdir1 = s6scpr (stang + (ki1 * 3), stang + (ko1 * 3), 3); 36676 tdir2 = s6scpr (stang + (ki1 * 3), stang + (ko2 * 3), 3); 36677 36678 if (tdir2 < DZERO || (tdir1 >= DZERO && tdist1 <= tdist2)) 36679 { 36680 /* We can connect the points. */ 36681 /* UPDATE (ujk) : do we need to make conistency 36682 between the points ? or can it be delayed until 36683 s6idlis ?? (this comments is valid for all 36684 connects in sscon and pscon)*/ 36685 36686 sh6tomain (uipt[ki1], &kstat); 36687 sh6tomain (uipt[ko1], &kstat); 36688 sh6tomain (uipt[ki2], &kstat); 36689 sh6tomain (uipt[ko2], &kstat); 36690 36691 sh6idcon (&rintdat, &uipt[ki1], &uipt[ko1], &kstat); 36692 if (kstat < 0) 36693 goto error; 36694 /* Newi (ujk) Set in/out direction */ 36695 sh6setdir (uipt[ki1], uipt[ko1], &kstat); 36696 if (kstat < 0) 36697 goto error; 36698 36699 sh6idcon (&rintdat, &uipt[ki2], &uipt[ko2], &kstat); 36700 if (kstat < 0) 36701 goto error; 36702 /* Newi (ujk) Set in/out direction */ 36703 sh6setdir (uipt[ki2], uipt[ko2], &kstat); 36704 if (kstat < 0) 36705 goto error; 36706 36707 } 36708 else 36709 { 36710 /* We can connect the points. */ 36711 36712 sh6tomain (uipt[ki1], &kstat); 36713 sh6tomain (uipt[ko1], &kstat); 36714 sh6tomain (uipt[ki2], &kstat); 36715 sh6tomain (uipt[ko2], &kstat); 36716 36717 sh6idcon (&rintdat, &uipt[ki1], &uipt[ko2], &kstat); 36718 if (kstat < 0) 36719 goto error; 36720 /* Newi (ujk) Set in/out direction */ 36721 sh6setdir (uipt[ki1], uipt[ko2], &kstat); 36722 if (kstat < 0) 36723 goto error; 36724 36725 sh6idcon (&rintdat, &uipt[ki2], &uipt[ko1], &kstat); 36726 if (kstat < 0) 36727 goto error; 36728 /* Newi (ujk) Set in/out direction */ 36729 sh6setdir (uipt[ki2], uipt[ko1], &kstat); 36730 if (kstat < 0) 36731 goto error; 36732 36733 } 36734 *jstat = 0; 36735 } 36736 else 36737 *jstat = 1; 36738 } 36739 36740 else 36741 /* Prepare a marching strategy for connection.*/ 36742 { 36743 lstatus[0] = 1; 36744 lstatus[1] = -1; 36745 lstatus[2] = 0; 36746 lstatus[3] = 2; 36747 36748 lnumb[0] = 0; 36749 lnumb[1] = 0; 36750 lnumb[2] = 0; 36751 lnumb[3] = 0; 36752 36753 if ((lperm = new0array (kv, int)) == SISL_NULL) 36754 goto err101; 36755 if ((lpermdir = new0array (kv, int)) == SISL_NULL) 36756 goto err101; 36757 if ((spar = newarray (4 * kv, double)) == SISL_NULL) 36758 goto err101; 36759 36760 for (kn = 0, kj = 0; kn < 4 && kj < kv; kn++) 36761 { 36762 /* We pass through the points four times, one for each 36763 possible statusvalue.*/ 36764 /* In this way they will be sorted : 111..-1-1-1..000..222.. */ 36765 36766 for (ki = 0; ki < kn1 && kj < kv; ki++) 36767 { 36768 36769 if (ldir[ki] == lstatus[kn]) 36770 { 36771 lnumb[kn] += 1; 36772 spar[4 * kj] = uipt[ki]->epar[0]; 36773 spar[4 * kj + 1] = uipt[ki]->epar[1]; 36774 spar[4 * kj + 2] = uipt[ki]->epar[2]; 36775 spar[4 * kj + 3] = uipt[ki]->epar[3]; 36776 lperm[kj] = ki; 36777 lpermdir[kj] = ldir[ki]; 36778 kj++; 36779 } 36780 } 36781 } 36782 36783 /* If the first point is a parallel point, change status. */ 36784 if (lpermdir[0] == 0) 36785 lpermdir[0] = 11; 36786 36787 36788 /* UJK, aug. 92 */ 36789 if (kv == 3) 36790 { 36791 /* When three points, check if they are connected. */ 36792 36793 sh6getlist (uipt[lperm[0]], uipt[lperm[1]], 36794 &klist1, &klist2, &kstat); 36795 if (kstat < 0) goto error; 36796 sh6getlist (uipt[lperm[0]], uipt[lperm[2]], 36797 &klist1, &klist2, &kstat1); 36798 if (kstat1 < 0) goto error; 36799 sh6getlist (uipt[lperm[1]], uipt[lperm[2]], 36800 &klist1, &klist2, &kstat2); 36801 if (kstat2 < 0) goto error; 36802 36803 if (kstat + kstat1 + kstat2 <= 1) 36804 { 36805 *jstat=0; 36806 goto out; 36807 } 36808 } 36809 if (kv == 3 && lpermdir[2] == 2) 36810 { 36811 /* When three points, one singular, check if they are connected. */ 36812 36813 sh6getlist (uipt[lperm[0]], uipt[lperm[2]], 36814 &klist1, &klist2, &kstat); 36815 sh6getlist (uipt[lperm[1]], uipt[lperm[2]], 36816 &klist1, &klist2, &kstat1); 36817 36818 if (kstat == 0 && kstat1 == 0) 36819 { 36820 *jstat=0; 36821 goto out; 36822 } 36823 else if (kstat1 == 0 && 36824 abs(lpermdir[0]) == 1 && 36825 lpermdir[1] == 0 && 36826 lpermdir[2] == 2) 36827 { 36828 /* Sing point is connected to parallell, 36829 connect singular point to in(out) point. */ 36830 sh6tomain (uipt[lperm[0]], &kstat); 36831 sh6tomain (uipt[lperm[2]], &kstat); 36832 36833 sh6idcon (&rintdat, &uipt[lperm[0]], 36834 &uipt[lperm[2]], &kstat); 36835 if (kstat < 0) 36836 goto error; 36837 36838 /* Set in/out direction */ 36839 if (lpermdir[0] == 1) 36840 sh6setdir (uipt[lperm[0]], 36841 uipt[lperm[2]], &kstat); 36842 else 36843 sh6setdir (uipt[lperm[2]], 36844 uipt[lperm[0]], &kstat); 36845 36846 if (kstat < 0) 36847 goto error; 36848 36849 /* Set status JUNCTION point. */ 36850 uipt[lperm[2]]->iinter = SI_SING; 36851 36852 36853 *jstat=0; 36854 goto out; 36855 } 36856 } 36857 36858 36859 /* UJK 18.09.90 Connecting whenever we have two points and 36860 at least one of them is moving in or out. */ 36861 if (kv == 2 && (abs (lpermdir[0]) == 1)) 36862 /* if (kv==2 && 36863 ((lpermdir[0]*lpermdir[1] == -1) || 36864 (abs(lpermdir[0])==1 && lpermdir[1] == 0))) */ 36865 { 36866 /* We have only two points and there has to be a curve, 36867 connect. */ 36868 sh6tomain (uipt[lperm[0]], &kstat); 36869 sh6tomain (uipt[lperm[1]], &kstat); 36870 36871 sh6idcon (&rintdat, &uipt[lperm[0]], &uipt[lperm[1]], &kstat); 36872 if (kstat < 0) 36873 goto error; 36874 36875 /* Newi (ujk) Set in/out direction */ 36876 if (lpermdir[0] == 1) 36877 sh6setdir (uipt[lperm[0]], 36878 uipt[lperm[1]], &kstat); 36879 else 36880 sh6setdir (uipt[lperm[1]], 36881 uipt[lperm[0]], &kstat); 36882 36883 if (kstat < 0) 36884 goto error; 36885 36886 /* ALA && UJK 19.09.90 Set status JUNCTION point. */ 36887 if (lpermdir[1] == 2) 36888 uipt[lperm[1]]->iinter = SI_SING; 36889 36890 36891 *jstat = 0; 36892 goto out; 36893 } 36894 36895 else if (kv > 4 && lpermdir[kv - 1] != -1) 36896 { 36897 /* More than four points, some with status /= +-1; 36898 , it's not a simple case. */ 36899 *jstat = 1; 36900 goto out; 36901 } 36902 36903 36904 else if (kv == 3 && 36905 lpermdir[0] == 1 && 36906 lpermdir[1] == -1 && 36907 lpermdir[2] == 0) 36908 /* Three points, one in, one out, one parallel, connect in-out, 36909 delete parallel.. */ 36910 { 36911 36912 sh6tomain (uipt[lperm[0]], &kstat); 36913 sh6tomain (uipt[lperm[1]], &kstat); 36914 sh6idcon (&rintdat, &uipt[lperm[0]], &uipt[lperm[1]], &kstat); 36915 if (kstat < 0) 36916 goto error; 36917 36918 /* Newi (ujk) Set in/out direction */ 36919 sh6setdir (uipt[lperm[0]], uipt[lperm[1]], &kstat); 36920 36921 /* UPDATE: (ujk) Avoid killing on edge !!! */ 36922 /* UJK, Aug.92, can't delete the parallel point 36923 if it's in a corner. */ 36924 36925 /* Corner first surface ? */ 36926 for (kn1 = kj = 0; kj < 4; kj++) 36927 if (edg[lperm[2]] & (1<<kj)) kn1++; 36928 36929 /* Corner second surface ? */ 36930 if (kn1 < 2) 36931 for (kn1 = 0, kj = 4; kj < 8; kj++) 36932 if (edg[lperm[2]] & (1<<kj)) kn1++; 36933 36934 if (kn1 < 2) 36935 { 36936 sh6idkpt (&rintdat, &uipt[lperm[2]], 1, &kstat); 36937 if (kstat < 0) 36938 goto error; 36939 } 36940 36941 *jstat = 0; 36942 goto out; 36943 } 36944 36945 36946 else if (kv == 3 && (lpermdir[0] == 1 || lpermdir[0] == -1) && 36947 lpermdir[1] == 0 && lpermdir[2] == 0) 36948 { 36949 /* Set up parameters for search for singularity. */ 36950 36951 slimit[0] = *(ps1->et1 + ps1->ik1 - 1); 36952 slimit[1] = *(ps1->et1 + ps1->in1); 36953 slimit[2] = *(ps1->et2 + ps1->ik2 - 1); 36954 slimit[3] = *(ps1->et2 + ps1->in2); 36955 slimit[4] = *(ps2->et1 + ps2->ik1 - 1); 36956 slimit[5] = *(ps2->et1 + ps2->in1); 36957 slimit[6] = *(ps2->et2 + ps2->ik2 - 1); 36958 slimit[7] = *(ps2->et2 + ps2->in2); 36959 tref = MAX(MAX(slimit[1]-slimit[0],slimit[3]-slimit[2]), 36960 MAX(slimit[5]-slimit[4],slimit[7]-slimit[6])); 36961 36962 for (kj=0; kj<4; kj++) 36963 { 36964 start[kj] = DZERO; 36965 for (ki=1; ki<3; ki++) start[kj] += spar[ki*4+kj]; 36966 start[kj] /= (double)2; 36967 } 36968 36969 /* Search for singularity. */ 36970 36971 shsing(ps1, ps2, slimit, start, spos, &kstat); 36972 if (kstat < 0) goto error; 36973 36974 if (kstat == 1) 36975 { 36976 /* A singularity is found. Check if it is an 36977 intersection point. */ 36978 36979 s1421(ps1, 0, spos, &klfs, &klft, sval1, snorm1, &kstat); 36980 if (kstat < 0) goto error; 36981 36982 s1421(ps2, 0, spos+2, &klfs, &klft, sval2, snorm2, &kstat); 36983 if (kstat < 0) goto error; 36984 36985 tdist = s6dist(sval1, sval2, 3); 36986 if (tdist < aepsge) 36987 { 36988 /* A singular intersection point is found. Check if 36989 it is identical to any of the existing. */ 36990 36991 for (ki=0; ki<3; ki++) 36992 { 36993 for (kj=0; kj<4; kj++) 36994 if (DNEQUAL(spos[kj]+tref,spar[4*ki+kj]+tref)) break; 36995 if (kj == 4) break; 36996 } 36997 36998 if (ki > 0 && ki < 3) 36999 { 37000 /* Connect the in/out point to the singular, 37001 parallel point. */ 37002 37003 sh6tomain(uipt[lperm[0]],&kstat); 37004 sh6tomain(uipt[ki],&kstat); 37005 sh6idcon(&rintdat,&uipt[lperm[0]],&uipt[ki],&kstat); 37006 if (kstat < 0) goto error; 37007 37008 /* Newi Set in/out direction */ 37009 if (lpermdir[0] == 1) 37010 sh6setdir (uipt[lperm[0]], uipt[ki], &kstat); 37011 else 37012 sh6setdir (uipt[ki], uipt[lperm[0]], &kstat); 37013 37014 goto out; 37015 } 37016 37017 if (ki == 3) 37018 { 37019 /* The singular intersection point do not exist already. 37020 Create intersection point. */ 37021 37022 qsing = hp_newIntpt (4, spos, DZERO, 37023 SI_ORD, SI_UNDEF, SI_UNDEF, 37024 SI_UNDEF, SI_UNDEF, 37025 0, 0, nullp, nullp); 37026 if (qsing == SISL_NULL) goto err101; 37027 37028 /* Check if it lies on an edge. */ 37029 37030 for (kj=0; kj<4; kj++) 37031 if (DEQUAL(spos[kj]+tref,slimit[2*kj]+tref) || 37032 DEQUAL(spos[kj]+tref,slimit[2*kj+1]+tref)) 37033 break; 37034 37035 if (kj < 4) 37036 { 37037 /* Singular intersection point at an edge. 37038 Insert between the two parallel points. */ 37039 37040 sh6insert(&rintdat,uipt[lperm[1]],uipt[lperm[2]], 37041 &qsing, &kstat); 37042 if (kstat < 0) goto error; 37043 37044 /* Connect to in/out point. */ 37045 37046 sh6tomain(uipt[lperm[0]],&kstat); 37047 sh6tomain(qsing,&kstat); 37048 sh6idcon(&rintdat,&uipt[lperm[0]],&qsing,&kstat); 37049 if (kstat < 0) goto error; 37050 37051 /* Mark point as singular. */ 37052 37053 qsing -> iinter = SI_SING; 37054 37055 /* Newi Set in/out direction */ 37056 if (lpermdir[0] == 1) 37057 sh6setdir (uipt[lperm[0]], qsing, &kstat); 37058 else 37059 sh6setdir (qsing, uipt[lperm[0]], &kstat); 37060 37061 goto out; 37062 } 37063 else 37064 { 37065 /* Singular point in the inner. Connect to 37066 all edge points. First put into data structure. */ 37067 37068 sh6idnpt (&rintdat, &qsing, 1, &kstat); 37069 if (kstat < 0) 37070 goto error; 37071 37072 sh6tomain(uipt[lperm[0]],&kstat); 37073 sh6tomain(uipt[lperm[1]],&kstat); 37074 sh6tomain(uipt[lperm[2]],&kstat); 37075 sh6tomain(qsing,&kstat); 37076 sh6idcon(&rintdat,&uipt[lperm[0]],&qsing,&kstat); 37077 if (kstat < 0) goto error; 37078 sh6idcon(&rintdat,&uipt[lperm[1]],&qsing,&kstat); 37079 if (kstat < 0) goto error; 37080 sh6idcon(&rintdat,&uipt[lperm[1]],&qsing,&kstat); 37081 if (kstat < 0) goto error; 37082 37083 /* Mark point as singular. */ 37084 37085 qsing -> iinter = SI_SING; 37086 37087 /* Newi Set in/out direction */ 37088 if (lpermdir[0] == 1) 37089 sh6setdir (uipt[lperm[0]], qsing, &kstat); 37090 else 37091 sh6setdir (qsing, uipt[lperm[0]], &kstat); 37092 37093 goto out; 37094 } 37095 } 37096 } 37097 } 37098 /* else 37099 { 37100 Check if only one of the parallel point is connected 37101 to only one point and the other is connected to two, 37102 connect to the first parallel point. 37103 37104 if ((sh6nmbmain(uipt[lperm[1]],&kstat) + 37105 sh6nmbhelp(uipt[lperm[1]],&kstat) == 1) && 37106 (sh6nmbmain(uipt[lperm[2]],&kstat) + 37107 sh6nmbhelp(uipt[lperm[2]],&kstat) == 2)) 37108 { 37109 sh6tomain(uipt[lperm[0]],&kstat); 37110 sh6tomain(uipt[lperm[1]],&kstat); 37111 sh6idcon(&rintdat,&uipt[lperm[0]],&uipt[lperm[1]],&kstat); 37112 if (kstat < 0) goto error; 37113 37114 Newi Set in/out direction 37115 if (lpermdir[0] == 1) 37116 sh6setdir (uipt[lperm[0]], uipt[lperm[1]], &kstat); 37117 else 37118 sh6setdir (uipt[lperm[1]], uipt[lperm[0]], &kstat); 37119 37120 goto out; 37121 } 37122 else if ((sh6nmbmain(uipt[lperm[2]],&kstat) + 37123 sh6nmbhelp(uipt[lperm[2]],&kstat) == 1) && 37124 (sh6nmbmain(uipt[lperm[1]],&kstat) + 37125 sh6nmbhelp(uipt[lperm[1]],&kstat) == 2)) 37126 { 37127 sh6tomain(uipt[lperm[0]],&kstat); 37128 sh6tomain(uipt[lperm[2]],&kstat); 37129 sh6idcon(&rintdat,&uipt[lperm[0]],&uipt[lperm[2]],&kstat); 37130 if (kstat < 0) goto error; 37131 37132 Newi Set in/out direction 37133 if (lpermdir[0] == 1) 37134 sh6setdir (uipt[lperm[0]], uipt[lperm[2]], &kstat); 37135 else 37136 sh6setdir (uipt[lperm[2]], uipt[lperm[0]], &kstat); 37137 37138 Newi Set in/out direction 37139 if (lpermdir[0] == 1) 37140 sh6setdir (uipt[lperm[0]], uipt[lperm[2]], &kstat); 37141 else 37142 sh6setdir (uipt[lperm[2]], uipt[lperm[0]], &kstat); 37143 37144 goto out; 37145 } 37146 else 37147 { 37148 Try to march from the non-parallel point. 37149 Set parameter to enter marching. 37150 37151 kmarch = 1; 37152 } 37153 } */ 37154 } 37155 37156 if (kv == 3 && abs(lpermdir[2]) == 1) 37157 { 37158 /* There is three points, all of which pointing in or out. 37159 Prepare for a search for a singularity. */ 37160 37161 slimit[0] = *(ps1->et1 + ps1->ik1 - 1); 37162 slimit[1] = *(ps1->et1 + ps1->in1); 37163 slimit[2] = *(ps1->et2 + ps1->ik2 - 1); 37164 slimit[3] = *(ps1->et2 + ps1->in2); 37165 slimit[4] = *(ps2->et1 + ps2->ik1 - 1); 37166 slimit[5] = *(ps2->et1 + ps2->in1); 37167 slimit[6] = *(ps2->et2 + ps2->ik2 - 1); 37168 slimit[7] = *(ps2->et2 + ps2->in2); 37169 tref = MAX(MAX(slimit[1]-slimit[0],slimit[3]-slimit[2]), 37170 MAX(slimit[5]-slimit[4],slimit[7]-slimit[6])); 37171 37172 for (kj=0; kj<4; kj++) 37173 { 37174 start[kj] = DZERO; 37175 for (ki=0; ki<3; ki++) start[kj] += spar[ki*4+kj]; 37176 start[kj] /= (double)3; 37177 } 37178 37179 /* Search for singularity. */ 37180 37181 shsing(ps1, ps2, slimit, start, spos, &kstat); 37182 if (kstat < 0) goto error; 37183 37184 if (kstat == 1) 37185 { 37186 /* A singularity is found. Check if it is an 37187 intersection point. */ 37188 37189 s1421(ps1, 0, spos, &klfs, &klft, sval1, snorm1, &kstat); 37190 if (kstat < 0) goto error; 37191 37192 s1421(ps2, 0, spos+2, &klfs, &klft, sval2, snorm2, &kstat); 37193 if (kstat < 0) goto error; 37194 37195 tdist = s6dist(sval1, sval2, 3); 37196 if (tdist < aepsge) 37197 { 37198 /* A singular intersection point is found. Check if 37199 it is identical to any of the existing. */ 37200 37201 for (ki=0; ki<3; ki++) 37202 { 37203 for (kj=0; kj<4; kj++) 37204 if (DNEQUAL(spos[kj]+tref,spar[4*ki+kj]+tref)) break; 37205 if (kj == 4) break; 37206 } 37207 37208 if (ki < 3) 37209 { 37210 /* Something is wrong. Non of the existing 37211 points are classified as singular. Continue 37212 subdividing. */ 37213 } 37214 else 37215 { 37216 /* The singular intersection point do not exist already. 37217 Create intersection point. */ 37218 37219 qsing = hp_newIntpt (4, spos, DZERO, 37220 SI_ORD, SI_UNDEF, SI_UNDEF, 37221 SI_UNDEF, SI_UNDEF, 37222 0, 0, nullp, nullp); 37223 if (qsing == SISL_NULL) goto err101; 37224 37225 /* Connect to all edge points. First put into 37226 data structure. */ 37227 37228 sh6idnpt (&rintdat, &qsing, 1, &kstat); 37229 if (kstat < 0) 37230 goto error; 37231 37232 sh6tomain(uipt[lperm[0]],&kstat); 37233 sh6tomain(uipt[lperm[1]],&kstat); 37234 sh6tomain(uipt[lperm[2]],&kstat); 37235 sh6tomain(qsing,&kstat); 37236 sh6idcon(&rintdat,&uipt[lperm[0]],&qsing,&kstat); 37237 if (kstat < 0) goto error; 37238 sh6idcon(&rintdat,&uipt[lperm[1]],&qsing,&kstat); 37239 if (kstat < 0) goto error; 37240 sh6idcon(&rintdat,&uipt[lperm[1]],&qsing,&kstat); 37241 if (kstat < 0) goto error; 37242 37243 /* Mark point as singular. */ 37244 37245 qsing -> iinter = SI_SING; 37246 37247 /* Newi Set in/out direction */ 37248 if (lpermdir[0] == 1) 37249 sh6setdir (uipt[lperm[0]], qsing, &kstat); 37250 else 37251 sh6setdir (qsing, uipt[lperm[0]], &kstat); 37252 37253 goto out; 37254 } 37255 } 37256 } 37257 } 37258 37259 if (kv == 2 || lnumb[2] < 2 || kmarch == 1) 37260 { 37261 /* If we got two points, we always try marching as the second 37262 strategy. */ 37263 /* If we got more than two points, we march only when 37264 no more than one parallel point is given.*/ 37265 37266 s9surmarch (ps1, ps2, spar, lpermdir, kv, &sparout, 37267 &lpar, &kpoints, &kstat); 37268 if (kstat < 0) 37269 goto error; 37270 37271 /* Branch on the given result from s9surmarch. */ 37272 if (kstat == 0) 37273 /* The points are not connected, continue subdividing. */ 37274 *jstat = 1; 37275 37276 else if (kstat == 2) 37277 /* Only singulear points, set status ok. */ 37278 *jstat = 0; 37279 37280 else 37281 { 37282 if (kpoints > kv) 37283 { 37284 if ((uinewpt = newarray (kpoints - kv, SISLIntpt *)) 37285 == SISL_NULL) 37286 goto err101; 37287 for (kj = kv, ki = 0; kj < kpoints; kj++, ki++) 37288 { 37289 /* For each new point returned from s9surmarch, 37290 we create an intersection point. */ 37291 SISLIntpt *qt; 37292 double sintpar[4]; 37293 37294 sintpar[0] = sparout[4 * kj]; 37295 sintpar[1] = sparout[4 * kj + 1]; 37296 sintpar[2] = sparout[4 * kj + 2]; 37297 sintpar[3] = sparout[4 * kj + 3]; 37298 37299 uinewpt[ki] = qt = hp_newIntpt (4, sintpar, DZERO, 37300 SI_ORD, SI_UNDEF, SI_UNDEF, 37301 SI_UNDEF, SI_UNDEF, 37302 0, 0, nullp, nullp); 37303 37304 37305 if (qt == SISL_NULL) 37306 goto err101; 37307 37308 sh6idnpt (&rintdat, &qt, 1, &kstat); 37309 if (kstat < 0) 37310 goto error; 37311 37312 } 37313 } 37314 37315 /* Now we connect the points. */ 37316 *jstat = 0; 37317 37318 for (kj = 0; kj < kv; kj++) 37319 { 37320 ki = lpar[kj] - 1; 37321 37322 if (lpar[kj] > 0) 37323 { 37324 if (lpar[kj] > kv) 37325 { 37326 /* SISLPoint is to be connected to a new point */ 37327 37328 sh6tomain (uipt[lperm[kj]], &kstat); 37329 sh6tomain (uinewpt[ki - kv], &kstat); 37330 37331 sh6idcon (&rintdat, &uipt[lperm[kj]], 37332 &uinewpt[ki - kv], &kstat); 37333 if (kstat < 0) 37334 goto error; 37335 /* Newi (ujk) Set in/out direction */ 37336 if (lpermdir[kj] == 1) 37337 sh6setdir (uipt[lperm[kj]], 37338 uinewpt[ki - kv], &kstat); 37339 else if (lpermdir[kj] == -1) 37340 sh6setdir (uinewpt[ki - kv], 37341 uipt[lperm[kj]], &kstat); 37342 37343 if (kstat < 0) 37344 goto error; 37345 } 37346 else 37347 { 37348 /* SISLPoint is to be connected to an old point */ 37349 sh6tomain (uipt[lperm[kj]], &kstat); 37350 sh6tomain (uipt[lperm[ki]], &kstat); 37351 sh6idcon (&rintdat, &uipt[lperm[kj]], 37352 &uipt[lperm[ki]], &kstat); 37353 37354 /* Newi (ujk) Set in/out direction */ 37355 if (lpermdir[kj] == 1 || lpermdir[ki] == -1) 37356 sh6setdir (uipt[lperm[kj]], 37357 uipt[lperm[ki]], &kstat); 37358 else if (lpermdir[kj] == -1 || 37359 lpermdir[ki] == 1) 37360 sh6setdir (uipt[lperm[ki]], 37361 uipt[lperm[kj]], &kstat); 37362 if (kstat < 0) 37363 goto error; 37364 37365 } 37366 } 37367 } 37368 } 37369 } 37370 else 37371 /* No marching is to be done. */ 37372 *jstat = 1; 37373 } 37374 } 37375 37376 37377 goto out; 37378 37379 37380 37381 /* Error in sub rutines. */ 37382 37383 error:*jstat = kstat; 37384 s6err ("sh1762_s9edgsscon", *jstat, 0); 37385 goto out; 37386 37387 /* Error in memory allocation. */ 37388 37389 err101:*jstat = -101; 37390 s6err ("sh1762_s9edgsscon", *jstat, 0); 37391 goto out; 37392 37393 /* Error dimension. */ 37394 37395 err200:*jstat = -200; 37396 s6err ("sh1762_s9edgsscon", *jstat, 0); 37397 goto out; 37398 37399 out: 37400 if (uipt != SISL_NULL) 37401 freearray (uipt); 37402 if (edg != SISL_NULL) 37403 freearray (edg); 37404 if (ldir != SISL_NULL) 37405 freearray (ldir); 37406 if (sval1 != SISL_NULL) 37407 freearray (sval1); 37408 37409 37410 if (uinewpt != SISL_NULL) 37411 freearray (uinewpt); 37412 if (spar != SISL_NULL) 37413 freearray (spar); 37414 if (sparout != SISL_NULL) 37415 freearray (sparout); 37416 if (lpar != SISL_NULL) 37417 freearray (lpar); 37418 if (lperm != SISL_NULL) 37419 freearray (lperm); 37420 if (lpermdir != SISL_NULL) 37421 freearray (lpermdir); 37422 } 37423 37424 //=========================================================================== 37425 void sh1762_s9edgpscon (SISLEdge * pedge, double alevel, SISLSurf * ps, 37426 int isimple, SISLIntdat * rintdat, double aepsge, int *jstat) 37427 //=========================================================================== 37428 { 37429 int kstat,kstat1,kstat2; 37430 int *ldir = SISL_NULL; /* Local array containing one of the statusvalues for 37431 * each point: 37432 * 0 - The intersect.curve is parallel to one 37433 * parameter direction. 37434 * 1 - The intersect.curve has direction into the 37435 * domain. 37436 * -1 - The intersect.curve has direction out of the 37437 * domain. 37438 * 2 - The point is singulear. 37439 * 10 - The intersect.curve touch one corner of the 37440 * domain. 37441 * --------------------------------------------------- 37442 */ 37443 37444 unsigned char *edg = SISL_NULL; 37445 double *sval = SISL_NULL; 37446 SISLPtedge *qpt = SISL_NULL; 37447 SISLIntpt **uipt = SISL_NULL; 37448 SISLIntpt **uinewpt = SISL_NULL; 37449 37450 double *spar = SISL_NULL; /* Local array with parameter values used as 37451 input to s9conmarch. */ 37452 int *lperm = SISL_NULL; /* Local permutation array after sorting 37453 input points to s9conmarch.*/ 37454 int *lpermdir = SISL_NULL; /* Local array with status values used as 37455 input to s9conmarch. */ 37456 int lstatus[4]; /* Local array containing the possible status 37457 constants -1,1,0,2. */ 37458 int lnumb[4]; /* Local array containing the number of points 37459 with status lstatus. */ 37460 37461 double *sparout = SISL_NULL; /* Local array with parameter values used as 37462 output from s9conmarch.*/ 37463 int *lpar = SISL_NULL; /* Local array containing the connection information 37464 from s9conmarch.*/ 37465 int kpoints; /* Local integer containing number of points returned 37466 from s9conmarch.*/ 37467 int klist1, klist2; /* Indices for Intpoints. */ 37468 37469 if (ps->idim != 1) 37470 goto err200; 37471 37472 *jstat = 1; 37473 37474 if (pedge->ipoint > 1) 37475 { 37476 int kn1, kn, ki, kj, kv, kant, klfs, klft, kdir, kpar; 37477 /* UJK 18.09.90 multiplying; treating near singularities as singularities.*/ 37478 double ttol = (double) 1000000.0 * REL_COMP_RES; 37479 double tolpar = (double) 0.00001; 37480 37481 double *snorm; 37482 double tmax; 37483 double *nullp = SISL_NULL; 37484 kant = pedge->ipoint; 37485 37486 /* Allocate array of pointers to the points. */ 37487 37488 if ((uipt = newarray (kant, SISLIntpt *)) == SISL_NULL) 37489 goto err101; 37490 if ((edg = new0array (kant, unsigned char)) == SISL_NULL) 37491 goto err101; 37492 if ((ldir = new0array (kant, int)) == SISL_NULL) 37493 goto err101; 37494 if ((sval = newarray (4 * kant, double)) == SISL_NULL) 37495 goto err101; 37496 snorm = sval + 3 * kant; 37497 37498 37499 /* Update the arrays. */ 37500 37501 for (kn1 = kj = 0; kj < pedge->iedge; kj++) 37502 for (qpt = pedge->prpt[kj]; qpt != SISL_NULL; qpt = qpt->pnext) 37503 { 37504 for (ki = 0; ki < kn1; ki++) 37505 { 37506 if (qpt->ppt == uipt[ki]) 37507 break; 37508 } 37509 if (ki == kn1) 37510 uipt[kn1++] = qpt->ppt; 37511 37512 edg[ki] |= 1 << kj; 37513 } 37514 37515 /* NEWI (ujk) some tuning ?! */ 37516 if (kn1 == 2) 37517 tolpar = ttol; 37518 37519 37520 if (kn1 > 1) 37521 for (ki = 0; ki < kn1; ki++) 37522 { 37523 kn = 3 * ki; 37524 37525 klfs = klft = 0; 37526 s1421 (ps, 1, uipt[ki]->epar, &klfs, &klft, sval + kn, snorm + ki, &kstat); 37527 if (kstat < 0) 37528 goto error; 37529 else if (kstat > 0) 37530 { 37531 ldir[ki] = 2; 37532 continue; 37533 } 37534 37535 tmax = sqrt (sval[kn + 1] * sval[kn + 1] + sval[kn + 2] * sval[kn + 2]); 37536 if (tmax < ttol) 37537 { 37538 ldir[ki] = 2; 37539 continue; 37540 } 37541 37542 for (kpar = 1, kj = 0; kj < 4; kj++) 37543 if ((edg[ki] & 1 << kj) == 1 << kj) 37544 { 37545 switch (kj) 37546 { 37547 case 0: 37548 if (fabs (sval[kn + 1] / tmax) < tolpar) 37549 kdir = 0; 37550 else 37551 kdir = (sval[kn + 1] > DZERO ? 1 : -1); 37552 break; 37553 case 1: 37554 if (fabs (sval[kn + 2] / tmax) < tolpar) 37555 kdir = 0; 37556 else 37557 kdir = (sval[kn + 2] > DZERO ? 1 : -1); 37558 break; 37559 case 2: 37560 if (fabs (sval[kn + 1] / tmax) < tolpar) 37561 kdir = 0; 37562 else 37563 kdir = (sval[kn + 1] > DZERO ? -1 : 1); 37564 break; 37565 case 3: 37566 if (fabs (sval[kn + 2] / tmax) < tolpar) 37567 kdir = 0; 37568 else 37569 kdir = (sval[kn + 2] > DZERO ? -1 : 1); 37570 } 37571 37572 if (kdir == 0) 37573 kpar = 0; 37574 else if (ldir[ki] != kdir) 37575 { 37576 if (ldir[ki] == 0) 37577 ldir[ki] = kdir; 37578 else 37579 { 37580 ldir[ki] = 10; 37581 break; 37582 } 37583 } 37584 } 37585 if (kpar == 0 && ldir[ki] != 10) 37586 ldir[ki] = 0; 37587 } 37588 /* End of for ki=0 ..... */ 37589 37590 37591 /* When only two points, check if they are connected. */ 37592 if (kn1 == 2) 37593 { 37594 sh6getlist (uipt[0], uipt[1], &klist1, &klist2, &kstat); 37595 if (kstat == 0) 37596 kn1 = 0; 37597 } 37598 37599 /* Count all the points that are candidates for connection. */ 37600 for (kv = ki = 0; ki < kn1; ki++) 37601 if (ldir[ki] < 10) 37602 kv++; 37603 37604 37605 if (kv == 1 && kn1 > 1 ) 37606 { 37607 int i,j; 37608 37609 if (kn1 > 2) 37610 { 37611 *jstat = 0; 37612 for (i=0;i<kn1;i++) 37613 if (ldir[i] == 1 || ldir[i] == -1) 37614 *jstat = 1; 37615 goto out; 37616 } 37617 37618 37619 if (ldir[0] == 1 || ldir[0] == -1) 37620 { 37621 i = 0; 37622 j = 1; 37623 } 37624 else if (ldir[1] == 1 || ldir[1] == -1) 37625 { 37626 i = 1; 37627 j = 0; 37628 } 37629 else i = -1; 37630 37631 if (i >=0) 37632 { 37633 /* We have one point, and the direction is in/out. 37634 The other point is touching a corner it is probably 37635 an error and the point must be close to tangential.*/ 37636 if (ldir[i] == -1) 37637 { 37638 int k=j; 37639 j = i; 37640 i = k; 37641 } 37642 37643 sh6tomain (uipt[i], &kstat); 37644 sh6tomain (uipt[j], &kstat); 37645 37646 sh6idcon (&rintdat, &uipt[i], &uipt[j], &kstat); 37647 if (kstat < 0) 37648 goto error; 37649 sh6setdir (uipt[i], uipt[j], &kstat); 37650 if (kstat < 0) 37651 goto error; 37652 *jstat = 0; 37653 } 37654 } 37655 else if (kv < 2) 37656 /* Less than two points, it's a simple case. */ 37657 *jstat = 0; 37658 37659 else if (kv > 8) 37660 /* More than eight points, it's not a simple case. */ 37661 *jstat = 1; 37662 else 37663 /* We have two, three or four points, prepare a marching strategy 37664 for connection.*/ 37665 { 37666 lstatus[0] = 1; 37667 lstatus[1] = -1; 37668 lstatus[2] = 0; 37669 lstatus[3] = 2; 37670 37671 lnumb[0] = 0; 37672 lnumb[1] = 0; 37673 lnumb[2] = 0; 37674 lnumb[3] = 0; 37675 37676 if ((lperm = new0array (kv, int)) == SISL_NULL) 37677 goto err101; 37678 if ((lpermdir = new0array (kv, int)) == SISL_NULL) 37679 goto err101; 37680 if ((spar = newarray (2 * kv, double)) == SISL_NULL) 37681 goto err101; 37682 37683 for (kn = 0, kj = 0; kn < 4 && kj < kv; kn++) 37684 { 37685 /* We pass through the points four times, one for each 37686 possible statusvalue.*/ 37687 /* In this way they will be sorted : 111..-1-1-1..000..222.. */ 37688 37689 for (ki = 0; ki < kn1 && kj < kv; ki++) 37690 { 37691 37692 if (ldir[ki] == lstatus[kn]) 37693 { 37694 lnumb[kn] += 1; 37695 spar[2 * kj] = uipt[ki]->epar[0]; 37696 spar[2 * kj + 1] = uipt[ki]->epar[1]; 37697 lperm[kj] = ki; 37698 lpermdir[kj] = ldir[ki]; 37699 kj++; 37700 } 37701 } 37702 } 37703 37704 /* If the first point is a parallel point, change status. */ 37705 if (lpermdir[0] == 0) 37706 lpermdir[0] = 11; 37707 37708 /* UJK, aug. 92 */ 37709 if (kv == 3) 37710 { 37711 /* When three points, check if they are connected. */ 37712 37713 sh6getlist (uipt[lperm[0]], uipt[lperm[1]], 37714 &klist1, &klist2, &kstat); 37715 if (kstat < 0) goto error; 37716 sh6getlist (uipt[lperm[0]], uipt[lperm[2]], 37717 &klist1, &klist2, &kstat1); 37718 if (kstat1 < 0) goto error; 37719 sh6getlist (uipt[lperm[1]], uipt[lperm[2]], 37720 &klist1, &klist2, &kstat2); 37721 if (kstat2 < 0) goto error; 37722 37723 if (kstat + kstat1 + kstat2 <= 1) 37724 { 37725 *jstat=0; 37726 goto out; 37727 } 37728 } 37729 37730 if (kv == 3 && lpermdir[2] == 2) 37731 { 37732 /* When three points, one singular, check if they are connected. */ 37733 37734 sh6getlist (uipt[lperm[0]], uipt[lperm[2]], 37735 &klist1, &klist2, &kstat); 37736 sh6getlist (uipt[lperm[1]], uipt[lperm[2]], 37737 &klist1, &klist2, &kstat1); 37738 37739 if (kstat == 0 && kstat1 == 0) 37740 { 37741 *jstat=0; 37742 goto out; 37743 } 37744 else if (kstat1 == 0 && 37745 abs(lpermdir[0]) == 1 && 37746 lpermdir[1] == 0 && 37747 lpermdir[2] == 2) 37748 { 37749 /* Sing point is connected to parallell, 37750 connect singular point to in(out) point. */ 37751 sh6tomain (uipt[lperm[0]], &kstat); 37752 sh6tomain (uipt[lperm[2]], &kstat); 37753 37754 sh6idcon (&rintdat, &uipt[lperm[0]], 37755 &uipt[lperm[2]], &kstat); 37756 if (kstat < 0) 37757 goto error; 37758 37759 /* Set in/out direction */ 37760 if (lpermdir[0] == 1) 37761 sh6setdir (uipt[lperm[0]], 37762 uipt[lperm[2]], &kstat); 37763 else 37764 sh6setdir (uipt[lperm[2]], 37765 uipt[lperm[0]], &kstat); 37766 37767 if (kstat < 0) 37768 goto error; 37769 37770 /* Set status JUNCTION point. */ 37771 uipt[lperm[2]]->iinter = SI_SING; 37772 37773 37774 *jstat=0; 37775 goto out; 37776 } 37777 37778 37779 } 37780 37781 37782 /* UJK 18.09.90 Connecting whenever we have two points and 37783 at least one of them is moving in or out. */ 37784 if (kv == 2 && (abs (lpermdir[0]) == 1)) 37785 /* if (kv==2 && 37786 ((lpermdir[0]*lpermdir[1] == -1) || 37787 (abs(lpermdir[0])==1 && lpermdir[1] == 0))) */ 37788 { 37789 /* We have only two points and there has to be a curve, 37790 connect. */ 37791 sh6tomain (uipt[lperm[0]], &kstat); 37792 sh6tomain (uipt[lperm[1]], &kstat); 37793 37794 sh6idcon (&rintdat, &uipt[lperm[0]], &uipt[lperm[1]], &kstat); 37795 if (kstat < 0) 37796 goto error; 37797 37798 /* Newi (ujk) Set in/out direction */ 37799 if (lpermdir[0] == 1) 37800 sh6setdir (uipt[lperm[0]], 37801 uipt[lperm[1]], &kstat); 37802 else 37803 sh6setdir (uipt[lperm[1]], 37804 uipt[lperm[0]], &kstat); 37805 37806 if (kstat < 0) 37807 goto error; 37808 37809 /* ALA && UJK 19.09.90 Set status JUNCTION point. */ 37810 if (lpermdir[1] == 2) 37811 uipt[lperm[1]]->iinter = SI_SING; 37812 37813 /* UJK,aug 93, Problems in sh1d_div, simple case may result 37814 in connecting to edge pts that is singular in the original 37815 problem, create one extra, internal pt if possible. */ 37816 if (DEQUAL(uipt[lperm[0]]->epar[0],uipt[lperm[1]]->epar[0]) || 37817 DEQUAL(uipt[lperm[0]]->epar[1],uipt[lperm[1]]->epar[1])) 37818 { 37819 SISLObject *obj=SISL_NULL; 37820 SISLIntpt *pint=SISL_NULL; 37821 double start; 37822 double *result; 37823 double coor[2]; 37824 if ((obj = newObject(SISLCURVE))== SISL_NULL) goto err101; 37825 if (fabs(uipt[lperm[0]]->epar[0]-uipt[lperm[1]]->epar[0]) > 37826 fabs(uipt[lperm[0]]->epar[1]-uipt[lperm[1]]->epar[1])) 37827 { 37828 coor[0] = (uipt[lperm[0]]->epar[0]+uipt[lperm[1]]->epar[0])/(double)2.0; 37829 result = coor+1; 37830 s1437(ps,coor[0],&(obj->c1),&kstat); 37831 if (kstat < 0) goto error; 37832 } 37833 else 37834 { 37835 coor[1] = (uipt[lperm[0]]->epar[1]+uipt[lperm[1]]->epar[1])/(double)2.0; 37836 result = coor; 37837 s1436(ps,coor[1],&(obj->c1),&kstat); 37838 if (kstat < 0) goto error; 37839 } 37840 start = s1792(obj->c1->et,obj->c1->ik,obj->c1->in); 37841 37842 sh6ptobj(&alevel, obj, aepsge, &start, result, &kstat); 37843 if (kstat < 0) goto error; 37844 if (kstat == 1) 37845 { 37846 pint = hp_newIntpt (2, coor, DZERO, 37847 SI_ORD, SI_UNDEF, SI_UNDEF, 37848 SI_UNDEF, SI_UNDEF, 37849 0, 0, SISL_NULL, SISL_NULL); 37850 37851 37852 if (pint == SISL_NULL) 37853 goto err101; 37854 37855 sh6insert (&rintdat, uipt[lperm[0]], uipt[lperm[1]], 37856 &pint,&kstat); 37857 if (kstat < 0) 37858 goto error; 37859 37860 37861 } 37862 if (obj) freeObject(obj); 37863 37864 } 37865 /* ______E N D aug.93________ */ 37866 37867 *jstat = 0; 37868 } 37869 37870 else if (kv > 4 && lpermdir[kv - 1] != -1) 37871 /* More than four points, some with status /= +-1; 37872 , it's not a simple case. */ 37873 *jstat = 1; 37874 37875 else if (kv == 3 && 37876 lpermdir[0] == 1 && 37877 lpermdir[1] == -1 && 37878 lpermdir[2] == 0) 37879 /* Three points, one in, one out, one parallel, connect in-out, 37880 delete parallel.. */ 37881 { 37882 37883 sh6tomain (uipt[lperm[0]], &kstat); 37884 sh6tomain (uipt[lperm[1]], &kstat); 37885 37886 sh6idcon (&rintdat, &uipt[lperm[0]], &uipt[lperm[1]], &kstat); 37887 if (kstat < 0) 37888 goto error; 37889 sh6setdir (uipt[lperm[0]], 37890 uipt[lperm[1]], &kstat); 37891 if (kstat < 0) 37892 goto error; 37893 37894 /* UJK, Aug.92, can't delete the parallel point 37895 if it's in the corner. */ 37896 37897 for (kn1 = kj = 0; kj < pedge->iedge; kj++) 37898 if (edg[lperm[2]] & (1<<kj)) kn1++; 37899 37900 if (kn1 < 2) 37901 { 37902 sh6idkpt (&rintdat, &uipt[lperm[2]], 1, &kstat); 37903 if (kstat < 0) 37904 goto error; 37905 } 37906 37907 *jstat = 0; 37908 } 37909 /* ALA UJK 31.10.90 Some special analysis when simple case 37910 and two nondirectional points. */ 37911 else if (kv == 2 && isimple > 0) 37912 { 37913 if (edg[lperm[0]] & edg[lperm[1]]) 37914 { 37915 /* The two points are on the same edge. */ 37916 sh6getlist (uipt[lperm[0]], uipt[lperm[1]], &klist1, &klist2, &kstat); 37917 if (kstat == 0) 37918 /* The points are connected, ok. */ 37919 *jstat = 0; 37920 else 37921 /* We must subdivide further. */ 37922 *jstat = 1; 37923 } 37924 else 37925 { 37926 /* The points are not on the same edge, connect. */ 37927 37928 sh6tomain (uipt[lperm[0]], &kstat); 37929 sh6tomain (uipt[lperm[1]], &kstat); 37930 37931 sh6idcon (&rintdat, &uipt[lperm[0]], &uipt[lperm[1]], &kstat); 37932 if (kstat < 0) 37933 goto error; 37934 /* Set status JUNCTION point. */ 37935 if (lpermdir[0] == 2) 37936 uipt[lperm[0]]->iinter = SI_SING; 37937 if (lpermdir[1] == 2) 37938 uipt[lperm[1]]->iinter = SI_SING; 37939 37940 *jstat = 0; 37941 } 37942 } 37943 37944 37945 /* end 31.10.90 */ 37946 37947 /* UJK 18.09.90 Marching singular cases is VERY expensiv and leads 37948 to nothing. (Number of points is here more than 2)*/ 37949 else if (lnumb[3] >= 2) 37950 *jstat = 1; 37951 /*end 18.09.90 */ 37952 37953 else if (kv == 2 || (isimple > 0 && (lnumb[2] < 2))) 37954 { 37955 /* If we got two points, we always try marching as the second 37956 strategy. */ 37957 /* If we got more than two points, we march only when the 37958 input parameter isimple is set and the no more than one 37959 parallel point is given.*/ 37960 37961 s9conmarch (ps, alevel, spar, lpermdir, kv, &sparout, 37962 &lpar, &kpoints, &kstat); 37963 if (kstat < 0) 37964 goto error; 37965 37966 /* Branch on the given result from s9conmarch. */ 37967 if (kstat == 0) 37968 /* The points are not connected, continue subdividing. */ 37969 *jstat = 1; 37970 37971 else if (kstat == 2) 37972 /* Only singulear points, set status ok. */ 37973 *jstat = 0; 37974 37975 else 37976 { 37977 if (kpoints > kv) 37978 { 37979 if ((uinewpt = newarray (kpoints - kv, SISLIntpt *)) 37980 == SISL_NULL) 37981 goto err101; 37982 for (kj = kv, ki = 0; kj < kpoints; kj++, ki++) 37983 { 37984 /* For each new point returned from s9conmarch, 37985 we create an intersection point. */ 37986 SISLIntpt *qt; 37987 double sintpar[2]; 37988 37989 sintpar[0] = sparout[2 * kj]; 37990 sintpar[1] = sparout[2 * kj + 1]; 37991 37992 uinewpt[ki] = qt = hp_newIntpt (2, sintpar, DZERO, 37993 SI_ORD, SI_UNDEF, SI_UNDEF, 37994 SI_UNDEF, SI_UNDEF, 37995 0, 0, nullp, nullp); 37996 37997 37998 if (qt == SISL_NULL) 37999 goto err101; 38000 38001 sh6idnpt (&rintdat, &qt, 1, &kstat); 38002 if (kstat < 0) 38003 goto error; 38004 38005 } 38006 } 38007 38008 /* Now we connect the points. */ 38009 *jstat = 0; 38010 38011 for (kj = 0; kj < kv; kj++) 38012 { 38013 ki = lpar[kj] - 1; 38014 38015 if (lpar[kj] > 0) 38016 { 38017 if (lpar[kj] > kv) 38018 { 38019 /* SISLPoint is to be connected to a new point */ 38020 sh6tomain (uipt[lperm[kj]], &kstat); 38021 sh6tomain (uinewpt[ki - kv], &kstat); 38022 38023 sh6idcon (&rintdat, &uipt[lperm[kj]], 38024 &uinewpt[ki - kv], &kstat); 38025 if (kstat < 0) 38026 goto error; 38027 38028 /* Newi (ujk) Set in/out direction */ 38029 if (lpermdir[kj] == 1) 38030 sh6setdir (uipt[lperm[kj]], 38031 uinewpt[ki - kv], &kstat); 38032 else if (lpermdir[kj] == -1) 38033 sh6setdir (uinewpt[ki - kv], 38034 uipt[lperm[kj]], &kstat); 38035 38036 if (kstat < 0) 38037 goto error; 38038 } 38039 else 38040 { 38041 /* SISLPoint is to be connected to an old point */ 38042 sh6tomain (uipt[lperm[kj]], &kstat); 38043 sh6tomain (uipt[lperm[ki]], &kstat); 38044 sh6idcon (&rintdat, &uipt[lperm[kj]], 38045 &uipt[lperm[ki]], &kstat); 38046 if (kstat < 0) 38047 goto error; 38048 38049 38050 /* Newi (ujk) Set in/out direction */ 38051 if (lpermdir[kj] == 1 || lpermdir[ki] == -1) 38052 sh6setdir (uipt[lperm[kj]], 38053 uipt[lperm[ki]], &kstat); 38054 else if (lpermdir[kj] == -1 || 38055 lpermdir[ki] == 1) 38056 sh6setdir (uipt[lperm[ki]], 38057 uipt[lperm[kj]], &kstat); 38058 if (kstat < 0) 38059 goto error; 38060 } 38061 } 38062 } 38063 } 38064 } 38065 else 38066 /* The input parameter isimple is not set, no marching 38067 is to be done. */ 38068 *jstat = 1; 38069 } 38070 } 38071 38072 38073 goto out; 38074 38075 /* Error in sub rutines. */ 38076 38077 error:*jstat = kstat; 38078 s6err ("sh1762_s9edgpscon", *jstat, 0); 38079 goto out; 38080 38081 /* Error in memory allocation. */ 38082 38083 err101:*jstat = -101; 38084 s6err ("sh1762_s9edgpscon", *jstat, 0); 38085 goto out; 38086 38087 /* Error dimension. */ 38088 38089 err200:*jstat = -200; 38090 s6err ("sh1762_s9edgpscon", *jstat, 0); 38091 goto out; 38092 38093 out: 38094 if (uipt != SISL_NULL) 38095 freearray (uipt); 38096 if (edg != SISL_NULL) 38097 freearray (edg); 38098 if (ldir != SISL_NULL) 38099 freearray (ldir); 38100 if (sval != SISL_NULL) 38101 freearray (sval); 38102 38103 if (uinewpt != SISL_NULL) 38104 freearray (uinewpt); 38105 if (spar != SISL_NULL) 38106 freearray (spar); 38107 if (sparout != SISL_NULL) 38108 freearray (sparout); 38109 if (lpar != SISL_NULL) 38110 freearray (lpar); 38111 if (lperm != SISL_NULL) 38112 freearray (lperm); 38113 if (lpermdir != SISL_NULL) 38114 freearray (lpermdir); 38115 } 38116 38117 //=========================================================================== 38118 void sh1762_s9simple (SISLObject * po1, SISLObject * po2, SISLEdge * vedge[], 38119 int *jstat) 38120 //=========================================================================== 38121 { 38122 int kstat; 38123 int kk1, kk2; 38124 int kn1, kn2; 38125 int kdim, knum; 38126 int klin1 = 0, klin2 = 0; 38127 double *et1, *et2; 38128 double tstart1, tstart2, tend1, tend2; 38129 double tvolorg, tvol, tvolfac; 38130 SISLIntpt **up = SISL_NULL; 38131 38132 kdim = po1->s1->idim; 38133 if (kdim != po2->s1->idim) 38134 goto err106; 38135 38136 38137 /* Init to no simpel case. */ 38138 *jstat = 0; 38139 38140 /* Count number of different edge-intersection points. */ 38141 /* sh1762_s9edgpoint (vedge, &up, &knum, &kstat); */ 38142 sh6edgpoint (vedge, &up, &knum, &kstat); 38143 if (kstat < 0) 38144 goto error; 38145 38146 /* No point on edge, continue subdividing. */ 38147 if (knum == 0) 38148 goto out; 38149 38150 /* We test if one of the two objects is liniar. */ 38151 if (po1->s1->pdir != SISL_NULL) 38152 if (po1->s1->pdir->igtpi == 0 && po1->s1->pdir->aang <= ANGULAR_TOLERANCE) 38153 klin1 = 1; 38154 38155 if (po2->s1->pdir != SISL_NULL) 38156 if (po2->s1->pdir->igtpi == 0 && po2->s1->pdir->aang <= ANGULAR_TOLERANCE) 38157 klin2 = 1; 38158 /* UJK, This is a coincidence or simple case test ? */ 38159 /* Both objects are linear, stop subdividing. */ 38160 /* if (klin1 == 1 && klin2 == 1) 38161 { 38162 *jstat = 1; 38163 goto out; 38164 } */ 38165 38166 /* Set different percent factor depending on number of edge points. */ 38167 if (knum == 1) 38168 tvolfac = (double) 0.0001; 38169 else 38170 tvolfac = (double) 0.00390625; 38171 38172 /* Get attributes from surface no 1. */ 38173 tstart1 = po1->s1->et1[po1->s1->ik1 - 1]; 38174 tend1 = po1->s1->et1[po1->s1->in1]; 38175 tstart2 = po1->s1->et2[po1->s1->ik2 - 1]; 38176 tend2 = po1->s1->et2[po1->s1->in2]; 38177 38178 et1 = po1->o1->s1->et1; 38179 et2 = po1->o1->s1->et2; 38180 kk1 = po1->o1->s1->ik1; 38181 kk2 = po1->o1->s1->ik2; 38182 kn1 = po1->o1->s1->in1; 38183 kn2 = po1->o1->s1->in2; 38184 38185 tvolorg = (et1[kn1] - et1[kk1 - 1]) * (et2[kn2] - et2[kk2 - 1]); 38186 tvol = (tend1 - tstart1) * (tend2 - tstart2); 38187 38188 /* Get attributes from surface no 1. */ 38189 tstart1 = po2->s1->et1[po2->s1->ik1 - 1]; 38190 tend1 = po2->s1->et1[po2->s1->in1]; 38191 tstart2 = po2->s1->et2[po2->s1->ik2 - 1]; 38192 tend2 = po2->s1->et2[po2->s1->in2]; 38193 38194 et1 = po2->o1->s1->et1; 38195 et2 = po2->o1->s1->et2; 38196 kk1 = po2->o1->s1->ik1; 38197 kk2 = po2->o1->s1->ik2; 38198 kn1 = po2->o1->s1->in1; 38199 kn2 = po2->o1->s1->in2; 38200 38201 tvolorg = tvolorg * (et1[kn1] - et1[kk1 - 1]) * (et2[kn2] - et2[kk2 - 1]); 38202 tvol = tvol * (tend1 - tstart1) * (tend2 - tstart2); 38203 38204 if (tvol <= tvolorg * tvolfac) 38205 *jstat = 1; 38206 38207 goto out; 38208 38209 /* Error in input. Dimensions of curves conflicting. */ 38210 38211 err106:*jstat = -106; 38212 s6err ("sh1762_s9simple", *jstat, 0); 38213 goto out; 38214 38215 /* Error in sub rutines. */ 38216 38217 error:*jstat = kstat; 38218 s6err ("sh1762_s9simple", *jstat, 0); 38219 goto out; 38220 38221 out:if (up != SISL_NULL) 38222 freearray (up); 38223 } 38224 38225 //=========================================================================== 38226 void sh1762_s9reex (SISLObject * po1, SISLObject * po2, SISLEdge * vedge[], 38227 double aepsge, SISLIntdat * pintdat, int *jstat) 38228 //=========================================================================== 38229 { 38230 int kstat; 38231 SISLIntpt **up = SISL_NULL; 38232 38233 *jstat = 0; 38234 38235 if (po1->iobj == SISLSURFACE && po2->iobj == SISLSURFACE) 38236 { 38237 int knum = 0; 38238 38239 if (vedge[0]->ipoint + vedge[1]->ipoint > 1) 38240 { 38241 /* The edges might be corrupt caused by killpoint, 38242 check existance of edgepoints. */ 38243 38244 int kn1, kn, ki, kj; 38245 SISLPtedge *qpt; 38246 38247 kn1 = pintdat->ipoint; 38248 38249 /* Loop for both objects*/ 38250 for (kn = 0; kn < 2; kn++) 38251 if (vedge[kn] != SISL_NULL) 38252 /* Loop for objects edges*/ 38253 for (kj = 0; kj < vedge[kn]->iedge; kj++) 38254 /* Loop for all points on edge*/ 38255 for (qpt = vedge[kn]->prpt[kj]; qpt != SISL_NULL; qpt = qpt->pnext) 38256 { 38257 /* Loop for all points in intersection data*/ 38258 for (ki = 0; ki < kn1; ki++) 38259 if (qpt->ppt == pintdat->vpoint[ki]) 38260 break; 38261 38262 /* SISLPoint not found, quit! */ 38263 if (ki == kn1) 38264 goto out; 38265 38266 } 38267 38268 /* sh1762_s9edgpoint (vedge, &up, &knum, &kstat); */ 38269 sh6edgpoint (vedge, &up, &knum, &kstat); 38270 if (kstat < 0) 38271 goto error; 38272 } 38273 38274 if (knum > 1) 38275 { 38276 int ki, kj; 38277 int klist1, klist2; 38278 double *spar; 38279 38280 /* We have to examine if any intersection points 38281 point to an internal or an other edge point. */ 38282 38283 for (ki = 0; ki < knum; ki++) 38284 if (sh6nmbmain (up[ki], &kstat) > 0) 38285 { 38286 for (kj = 0; kj < knum; kj++) 38287 { 38288 sh6getlist (up[ki], up[kj], &klist1, &klist2, &kstat); 38289 if (kstat == 0) 38290 goto out; 38291 } 38292 38293 for (kj = 0; kj < up[ki]->no_of_curves; kj++) 38294 { 38295 spar = up[ki]->pnext[kj]->epar; 38296 38297 if (spar[0] > po1->s1->et1[po1->s1->ik1 - 1] && 38298 spar[0] < po1->s1->et1[po1->s1->in1] && 38299 spar[1] > po1->s1->et2[po1->s1->ik2 - 1] && 38300 spar[1] < po1->s1->et2[po1->s1->in2] && 38301 spar[2] > po2->s1->et1[po2->s1->ik1 - 1] && 38302 spar[2] < po2->s1->et1[po2->s1->in1] && 38303 spar[3] > po2->s1->et2[po2->s1->ik2 - 1] && 38304 spar[3] < po2->s1->et2[po2->s1->in2]) 38305 goto out; 38306 } 38307 38308 } 38309 38310 38311 sh1762_s9edgsscon (vedge, po1->s1, po2->s1, pintdat, 0, 38312 aepsge, &kstat); 38313 if (kstat < 0) 38314 goto error; 38315 38316 /* Test if any connections is done in sh1762_s9edgsscon. */ 38317 38318 if (kstat == 0) *jstat = 1; 38319 } 38320 } 38321 else if ((po1->iobj == SISLPOINT && 38322 po2->iobj == SISLSURFACE && 38323 po1->p1->idim == 1) || 38324 (po1->iobj == SISLSURFACE && 38325 po2->iobj == SISLPOINT && 38326 po2->p1->idim == 1)) 38327 { 38328 int knum = 0; 38329 38330 if (vedge[0] != SISL_NULL) 38331 knum = vedge[0]->ipoint; 38332 if (vedge[1] != SISL_NULL) 38333 knum += vedge[1]->ipoint; 38334 38335 if (knum > 1) 38336 { 38337 /* The edges might be corrupt caused by killpoint, 38338 check existance of edgepoints. */ 38339 38340 int kn1, kn, ki, kj; 38341 SISLPtedge *qpt; 38342 38343 kn1 = pintdat->ipoint; 38344 38345 /* Loop for both objects*/ 38346 for (kn = 0; kn < 2; kn++) 38347 if (vedge[kn] != SISL_NULL) 38348 /* Loop for objects edges*/ 38349 for (kj = 0; kj < vedge[kn]->iedge; kj++) 38350 /* Loop for all points on edge*/ 38351 for (qpt = vedge[kn]->prpt[kj]; qpt != SISL_NULL; qpt = qpt->pnext) 38352 { 38353 /* Loop for all points in intersection data*/ 38354 for (ki = 0; ki < kn1; ki++) 38355 if (qpt->ppt == pintdat->vpoint[ki]) 38356 break; 38357 38358 /* SISLPoint not found, quit! */ 38359 if (ki == kn1) 38360 goto out; 38361 38362 } 38363 38364 /* sh1762_s9edgpoint (vedge, &up, &knum, &kstat); */ 38365 sh6edgpoint (vedge, &up, &knum, &kstat); 38366 if (kstat < 0) 38367 goto error; 38368 } 38369 38370 if (knum > 1) 38371 { 38372 int ki, kj; 38373 int klist1, klist2; 38374 double *spar; 38375 SISLSurf *qs1; 38376 38377 /* We have to examine if any intersection points 38378 point to an internal or an other edge point. */ 38379 38380 if (po1->iobj == SISLSURFACE) 38381 qs1 = po1->s1; 38382 else 38383 qs1 = po2->s1; 38384 38385 for (ki = 0; ki < knum; ki++) 38386 if (sh6nmbmain (up[ki], &kstat) > 0) 38387 { 38388 for (kj = 0; kj < knum; kj++) 38389 { 38390 sh6getlist (up[ki], up[kj], &klist1, &klist2, &kstat); 38391 if (kstat == 0) 38392 goto out; 38393 } 38394 38395 for (kj = 0; kj < up[ki]->no_of_curves; kj++) 38396 { 38397 spar = up[ki]->pnext[kj]->epar; 38398 38399 /* ALA and UJK 19.09.90, To treat the problem of 38400 junction points, we have introduced equality 38401 in this test. */ 38402 if (spar[0] >= qs1->et1[qs1->ik1 - 1] && 38403 spar[0] <= qs1->et1[qs1->in1] && 38404 spar[1] >= qs1->et2[qs1->ik2 - 1] && 38405 spar[1] <= qs1->et2[qs1->in2]) 38406 goto out; 38407 } 38408 38409 } 38410 38411 38412 sh1762_s9edgpscon (vedge[(po1->iobj == SISLSURFACE ? 0 : 1)], 38413 (po1->iobj == SISLSURFACE ? po2 : po1)->p1->ecoef[0], 38414 qs1, 1, pintdat, aepsge, &kstat); 38415 if (kstat < 0) 38416 goto error; 38417 38418 /* Test if any connections is done in sh1762_s9edgpscon. */ 38419 38420 if (kstat == 0) *jstat = 1; 38421 } 38422 } 38423 38424 goto out; 38425 38426 /* Error in subroutines. */ 38427 38428 error:*jstat = kstat; 38429 s6err ("sh1762_s9reex", *jstat, 0); 38430 goto out; 38431 38432 out:if (up != SISL_NULL) 38433 freearray (up); 38434 } 38435 38436 //=========================================================================== 38437 void sh1762_s9ptiter (SISLObject * po1, SISLObject * po2, double aepsge, 38438 SISLIntdat ** pintdat, SISLEdge *vedge[], int *jstat) 38439 //=========================================================================== 38440 { 38441 int kstat = 0; 38442 int kturn; /* Indicates if the order of the objects is changed. */ 38443 int kdim; /* Dimension of geometry space. */ 38444 int kcrv; /* Index of curve in array of edge intersections. */ 38445 double tptdist1; /* Distance between point and first endpoint of curve. */ 38446 double tptdist2; /* Distance between point and second endpoint of curve. */ 38447 double tcoefd1,tcoefd2; /* Distance between vertices of curve. */ 38448 double tstart,tend; /* Endparameters of curve used in iteration. */ 38449 double tref; /* Referance value in equality test. */ 38450 double tpar,tres; /* Start- and endparameter of intersection point. */ 38451 double *sc1; /* Pointer to coefficient of curve. */ 38452 double *sc2; /* Pointer to coefficient of curve. */ 38453 double sdiff1[3]; /* Vector between point and endpoint of object. */ 38454 double sdiff2[3]; /* Vector between endpoint of object and closest inner 38455 vertex. */ 38456 double *nullp = SISL_NULL; 38457 SISLPoint *qpt; /* Pointer to the point in the intersection. */ 38458 SISLObject *qobj2; /* Pointer to the other object in the intersection. */ 38459 SISLCurve *qcrv; /* Pointer to the curve in the intersection. */ 38460 SISLIntpt *qt = SISL_NULL; /* Pointer to intersection point. */ 38461 38462 /* Find the order of the objects. */ 38463 38464 if (po1->iobj == SISLPOINT) 38465 { 38466 qpt = po1->p1; 38467 qobj2 = po2; 38468 kturn = 0; 38469 } 38470 else if (po2->iobj == SISLPOINT) 38471 { 38472 qpt = po2->p1; 38473 qobj2 = po1; 38474 kturn = 1; 38475 } 38476 else 38477 goto err122; 38478 38479 /* Find dimension of geometry space. */ 38480 38481 kdim = qpt->idim; 38482 38483 if (qobj2->iobj == SISLCURVE) 38484 { 38485 /* Curve object intersection. Compute distances between point and 38486 endpoints of curve, and between endpoints of curve and closest 38487 vertex. */ 38488 38489 kcrv = 1 - kturn; 38490 qcrv = qobj2->c1; 38491 sc1 = qcrv->ecoef; 38492 sc2 = qcrv->ecoef + kdim*(qcrv->in - 1); 38493 38494 if (qcrv->in == 2) 38495 { 38496 /* No intersection is possible. */ 38497 38498 *jstat = 0; 38499 goto out; 38500 } 38501 38502 tptdist1 = s6dist(qpt->ecoef,sc1,kdim); 38503 tptdist2 = s6dist(qpt->ecoef,sc2,kdim); 38504 tcoefd1 = s6dist(sc1,sc1+kdim,kdim); 38505 tcoefd2 = s6dist(sc2,sc2-kdim,kdim); 38506 38507 if (tptdist1 > (double)1.5*tcoefd1 && tptdist2 > (double)1.5*tcoefd2) 38508 { 38509 /* The point is not close to an endpoint of the curve. 38510 No intersection. NB! It may be necessary to make this 38511 test less strict when we have gained some experience 38512 with this routine. */ 38513 38514 *jstat = 0; 38515 goto out; 38516 } 38517 38518 if (tptdist1 < tptdist2 && tptdist1 <= (double)1.5*tcoefd1) 38519 { 38520 s6diff(qpt->ecoef,sc1,kdim,sdiff1); 38521 s6diff(sc1+kdim,sc1,kdim,sdiff2); 38522 } 38523 else 38524 { 38525 s6diff(qpt->ecoef,sc2,kdim,sdiff1); 38526 s6diff(sc2-kdim,sc2,kdim,sdiff2); 38527 } 38528 38529 /* Check if the point lies on the same side of the closest endpoint 38530 of the curve as the curve itself. */ 38531 38532 if (s6scpr(sdiff1,sdiff2,kdim) < DZERO) 38533 { 38534 /* No intersection. */ 38535 38536 *jstat = 0; 38537 goto out; 38538 } 38539 38540 /* Iterate to find the intersection point. */ 38541 38542 tstart = qcrv->et[qcrv->ik - 1]; 38543 tend = qcrv->et[qcrv->in]; 38544 tref = tend - tstart; 38545 38546 if (tptdist1 < tptdist2 && tptdist1 <= (double)1.5*tcoefd1) 38547 { 38548 tpar = tstart; 38549 38550 /* Check if there exists an intersection in the start of the 38551 curve. */ 38552 38553 if (vedge[kcrv]->prpt[0] != SISL_NULL) 38554 { 38555 /* No iteration is to be performed. */ 38556 38557 *jstat = 0; 38558 goto out; 38559 } 38560 } 38561 else 38562 { 38563 tpar = tend; 38564 38565 /* Check if there exists an intersection in the end of the 38566 curve. */ 38567 38568 if (vedge[kcrv]->prpt[1] != SISL_NULL) 38569 { 38570 /* No iteration is to be performed. */ 38571 38572 *jstat = 0; 38573 goto out; 38574 } 38575 } 38576 38577 s1771 (qpt, qcrv, aepsge, 38578 tstart, tend, tpar, &tres, &kstat); 38579 if (kstat < 0) 38580 goto error; 38581 38582 if (kstat == 1) 38583 /*Intersection point found. Control edges. */ 38584 if (DEQUAL (tres+tref, tstart+tref) || DEQUAL (tres+tref, tend+tref)) 38585 kstat = 0; 38586 38587 if (kstat == 1) /* Intersection point found. */ 38588 { 38589 *jstat = 1; /* Mark intersection found. */ 38590 38591 /* Making intersection point. */ 38592 qt = hp_newIntpt (SISLCURVE, &tres, DZERO, SI_ORD, 38593 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 38594 0, 0, nullp, nullp); 38595 38596 if (qt == SISL_NULL) 38597 goto err101; 38598 38599 /* Uppdating pintdat. */ 38600 sh6idnpt (pintdat, &qt, 1, &kstat); 38601 if (kstat < 0) 38602 goto error; 38603 } 38604 } 38605 else 38606 { 38607 /* The other object is a surface. For the time being, set no 38608 intersection. This part of the routine will be implemented 38609 later. */ 38610 38611 *jstat = 0; 38612 goto out; 38613 } 38614 38615 goto out; 38616 38617 /* Error in space allocation. */ 38618 38619 err101 : *jstat = -101; 38620 goto out; 38621 38622 /* None of the objects is a point. */ 38623 38624 err122 : *jstat = -122; 38625 goto out; 38626 38627 /* Error in lower level routine. */ 38628 38629 error : *jstat = kstat; 38630 goto out; 38631 38632 38633 out: 38634 return; 38635 } 38636 38637 //=========================================================================== 38638 void sh6tomain(SISLIntpt *pt,int *jstat) 38639 //=========================================================================== 38640 { 38641 int ki; /* Loop variable. */ 38642 int num; 38643 int kstat; 38644 38645 *jstat=0; 38646 38647 if(pt == SISL_NULL) goto err1; 38648 38649 if(sh6ishelp(pt)) /* If pt is a help point. */ 38650 { 38651 pt->iinter = -pt->iinter; /* Convert status to main point. */ 38652 38653 /* Go through all neighbours and keep invariant: 38654 not more than one mainpoint connected to a help point. */ 38655 for(ki=0; ki<pt->no_of_curves; ki++) 38656 { 38657 if(sh6ishelp(pt->pnext[ki])) 38658 { 38659 /* UJK, change all NON-terminators to main */ 38660 /* num=sh6nmbmain(pt->pnext[ki],&kstat); */ 38661 num = pt->pnext[ki]->no_of_curves; 38662 if(num > 1) sh6tomain(pt->pnext[ki],&kstat); 38663 } 38664 } 38665 38666 } 38667 else 38668 { 38669 *jstat=1; 38670 } 38671 38672 goto out; 38673 38674 38675 err1: 38676 /* Error in input. pt is null. */ 38677 38678 *jstat = -1; 38679 s6err("sh6tomain",*jstat,0); 38680 goto out; 38681 38682 38683 out : 38684 return; 38685 } 38686 38687 38688 //=========================================================================== 38689 void s6fndintvl(double *et,int ik,int in,int *ileft, 38690 double ax1,double ax2,int mu_max,int *jstat) 38691 //=========================================================================== 38692 { 38693 int kpos=0; /* The position of the error. */ 38694 int kstat=0; /* Local status */ 38695 int kleft_1=*ileft; /* Local version of ileft to avoid the pointer. */ 38696 int kleft_2=*ileft; /* Local version of ileft to avoid the pointer. */ 38697 int mu = 0; /* Knot mltiplicity. */ 38698 double tmp; 38699 double tval; 38700 /* _____________________________________________________________________ */ 38701 *jstat = 0; 38702 38703 /* Sort position */ 38704 if (ax1 > ax2) 38705 { 38706 tmp = ax1; 38707 ax1 = ax2; 38708 ax2 = tmp; 38709 } 38710 38711 38712 /* Find knot navigators */ 38713 s1219(et,ik,in,&kleft_1,ax1,&kstat); 38714 if (kstat < 0) goto error; 38715 38716 tval = et[kleft_1+1]; 38717 while (tval < ax2 && tval < et[in]) 38718 { 38719 mu = s6knotmult(et,ik,in,&kleft_2,tval, &kstat); 38720 if (mu > mu_max) 38721 { 38722 *jstat = 1; 38723 *ileft = kleft_2; 38724 break; 38725 } 38726 tval = et[kleft_2 +1]; 38727 } 38728 38729 /* Successful computations. */ 38730 goto out; 38731 38732 38733 /* Error */ 38734 error: *jstat = kstat; 38735 s6err("s6fndintvl",*jstat,kpos); 38736 goto out; 38737 38738 out: return; 38739 } 38740 38741 //=========================================================================== 38742 int sh6getprev(SISLIntpt *pt1,SISLIntpt *pt2) 38743 //=========================================================================== 38744 { 38745 int ncurv; /* number of curves pt1 is connected to */ 38746 int index; /* index number for pnext array */ 38747 38748 index = -1; 38749 38750 if(pt1 == SISL_NULL || pt2 == SISL_NULL) goto out; 38751 38752 ncurv = pt1->no_of_curves; /* note ncurv can be zero */ 38753 38754 index=0; 38755 while(index < ncurv && pt1->pnext[index] != pt2) index++; 38756 if(index == ncurv) index = -1; /* no index found */ 38757 38758 goto out; 38759 38760 out : 38761 return index; 38762 } 38763 38764 38765 //=========================================================================== 38766 void sh6getlist(SISLIntpt *pt1,SISLIntpt *pt2,int *index1,int *index2,int *jstat) 38767 //=========================================================================== 38768 { 38769 *index1 = -1; 38770 *index2 = -1; 38771 38772 *jstat=0; 38773 38774 /* Find "next" link from pt1 to pt2. */ 38775 38776 *index1 = sh6getprev(pt1,pt2); 38777 *index2 = sh6getprev(pt2,pt1); 38778 38779 if(*index1 >= 0 && *index2 < 0) goto err1; 38780 if(*index2 >= 0 && *index1 < 0) goto err1; 38781 38782 if(*index1 < 0 && *index2 < 0) *jstat=1; 38783 38784 38785 goto out; 38786 38787 err1: 38788 /* Error -- bad data structure. */ 38789 38790 *jstat = -1; 38791 s6err("sh6getlist",*jstat,0); 38792 goto out; 38793 38794 out : 38795 return; 38796 } 38797 38798 38799 //=========================================================================== 38800 void sh6getother(SISLIntpt *pt,SISLIntpt *pt1,SISLIntpt **pt2,int *jstat) 38801 //=========================================================================== 38802 { 38803 int kstat; /* Local status variable. */ 38804 int index,index1; /* Indices for pt and pt1. */ 38805 int num; /* count number of pointers */ 38806 int i; /* Loop variable. */ 38807 38808 *pt2 = SISL_NULL; 38809 *jstat = 0; 38810 38811 sh6getlist(pt,pt1,&index1,&index,&kstat); 38812 if(kstat < 0) goto error; 38813 if(kstat == 1) goto err1; 38814 38815 if(sh6ismain(pt)) /* pt is main point. */ 38816 { 38817 if(!sh6ismain(pt1)) goto err1; 38818 num=0; 38819 /* UJK, don't pass singular point ! */ 38820 if (pt->iinter == SI_SING) 38821 { 38822 *pt2 = SISL_NULL; 38823 *jstat = 2; 38824 goto out; 38825 } 38826 38827 for(i=0; i < pt->no_of_curves; i++) 38828 { 38829 if(i != index1 && sh6ismain(pt->pnext[i])) 38830 { 38831 *pt2 = pt->pnext[i]; 38832 num++; 38833 } 38834 } 38835 38836 if(num == 0) *jstat = 1; /* pt is an end point. */ 38837 else if(num > 1) /* pt is a junction point. */ 38838 { 38839 *pt2 = SISL_NULL; 38840 *jstat = 2; 38841 } 38842 } 38843 else /* pt is help point. */ 38844 { 38845 num=0; 38846 38847 for(i=0; i < pt->no_of_curves; i++) 38848 { 38849 if(i != index1) 38850 { 38851 *pt2 = pt->pnext[i]; 38852 num++; 38853 } 38854 } 38855 38856 if(num > 1) goto err2; /* Error in data structure. */ 38857 if(num == 0) *jstat = 1; /* pt is an end point. */ 38858 } 38859 38860 goto out; 38861 38862 38863 /* Error. pt1 and pt2 are not linked. */ 38864 38865 err1: *jstat = -1; 38866 s6err("sh6getother",*jstat,0); 38867 goto out; 38868 38869 /* Error in sub function. */ 38870 38871 /* Error in data structure. */ 38872 38873 err2: *jstat = -2; 38874 s6err("sh6getother",*jstat,0); 38875 goto out; 38876 38877 /* Error in sub function. */ 38878 38879 error: *jstat = kstat; 38880 s6err("sh6getother",*jstat,0); 38881 goto out; 38882 38883 out: 38884 return; 38885 } 38886 38887 38888 //=========================================================================== 38889 void sh6getnhbrs(SISLIntpt *pt,SISLIntpt **pt1,SISLIntpt **pt2,int *jstat) 38890 //=========================================================================== 38891 { 38892 int num; /* count number of pointers */ 38893 int i; /* Loop variable. */ 38894 38895 *pt1 = SISL_NULL; 38896 *pt2 = SISL_NULL; 38897 *jstat = 0; 38898 38899 if(sh6ismain(pt)) /* pt is main point. */ 38900 { 38901 num=0; 38902 38903 for(i=0; i < pt->no_of_curves; i++) 38904 { 38905 if(sh6ismain(pt->pnext[i])) 38906 { 38907 if(num == 0) *pt1 = pt->pnext[i]; 38908 else *pt2 = pt->pnext[i]; 38909 num++; 38910 } 38911 } 38912 38913 if(num == 0) *jstat = 3; /* pt is an isolated point. */ 38914 else if(num == 1) *jstat = 1; /* pt is an end point. */ 38915 else if(num > 2) /* pt is a junction point. */ 38916 { 38917 *pt1 = SISL_NULL; 38918 *pt2 = SISL_NULL; 38919 *jstat = 2; 38920 } 38921 } 38922 else /* pt is help point. */ 38923 { 38924 num=pt->no_of_curves; 38925 38926 if(num == 0) *jstat = 3; /* pt is an isolated point. */ 38927 else 38928 { 38929 *pt1=pt->pnext[0]; 38930 if(num == 1) *jstat = 1; /* pt is an end point. */ 38931 else 38932 { 38933 *pt2=pt->pnext[1]; 38934 /* UJK; Oh, yeah ?, don't discriminate help points. */ 38935 /* if(num > 2) goto err1; Error in data structure. */ 38936 if (num > 2) 38937 { 38938 *pt1 = SISL_NULL; 38939 *pt2 = SISL_NULL; 38940 *jstat = 2; 38941 } 38942 } 38943 } 38944 } 38945 38946 goto out; 38947 38948 38949 /* Error in data structure. */ 38950 /* 38951 err1: *jstat = -1; 38952 s6err("sh6getnhbrs",*jstat,0); 38953 goto out; */ 38954 38955 out: 38956 return; 38957 } 38958 38959 //=========================================================================== 38960 int sh6ismain(SISLIntpt *pt) 38961 //=========================================================================== 38962 { 38963 int flag = 0; 38964 38965 if(pt != SISL_NULL && pt->iinter > 0) flag = 1; 38966 38967 38968 goto out; 38969 38970 38971 38972 out : 38973 return flag; 38974 } 38975 38976 //=========================================================================== 38977 SISLIntpt* sh6getnext(SISLIntpt *pt,int index) 38978 //=========================================================================== 38979 { 38980 38981 SISLIntpt *nextpt = SISL_NULL; 38982 38983 /* check if index is within range */ 38984 38985 if(pt != SISL_NULL && 38986 index >= 0 && 38987 index < pt->no_of_curves) nextpt = pt->pnext[index]; 38988 38989 goto out; 38990 38991 38992 out : 38993 return nextpt; 38994 } 38995 38996 //=========================================================================== 38997 int sh6ishelp(SISLIntpt *pt) 38998 //=========================================================================== 38999 { 39000 int flag = 0; 39001 39002 if(pt != SISL_NULL && pt->iinter < 0) flag = 1; 39003 39004 39005 goto out; 39006 39007 39008 39009 out : 39010 return flag; 39011 } 39012 39013 //=========================================================================== 39014 SISLIntpt * sh6getmain (SISLIntpt * pt) 39015 //=========================================================================== 39016 { 39017 int ki; /* Loop control */ 39018 int kstat; /* Local status */ 39019 int more = TRUE; /* Loop control */ 39020 SISLIntpt *mainpt = SISL_NULL; 39021 SISLIntpt *pt1 = SISL_NULL; 39022 SISLIntpt *pt2 = SISL_NULL; 39023 SISLIntpt *prev = SISL_NULL; 39024 SISLIntpt *pcurr = SISL_NULL; 39025 SISLIntpt *pnext = SISL_NULL; 39026 /* ------------------------------------------------------------- */ 39027 39028 39029 if (!sh6ishelp (pt)) 39030 goto out; 39031 39032 for (ki = 0; ki < pt->no_of_curves; ki++) 39033 { 39034 if (sh6ismain (pt1 = sh6getnext (pt, ki))) 39035 { 39036 mainpt = pt1; 39037 break; 39038 } 39039 } 39040 39041 if (!mainpt) 39042 { 39043 /* No close neighbour is main, check along list 39044 if not meeting point. */ 39045 sh6getnhbrs (pt, &pt1, &pt2, &kstat); 39046 if (kstat == 1) 39047 { 39048 /* Terminator, go towards other end */ 39049 prev = pt; 39050 pcurr = pt1; 39051 more = TRUE; 39052 39053 while ((!mainpt) && more) 39054 { 39055 sh6getother (pcurr, prev, &pnext, &kstat); 39056 if (kstat < 0) 39057 goto error; 39058 39059 if (pnext && (pnext != pt)) 39060 { 39061 if (sh6ismain (pnext)) 39062 mainpt = pnext; 39063 else 39064 { 39065 prev = pcurr; 39066 pcurr = pnext; 39067 pnext = SISL_NULL; 39068 } 39069 } 39070 else 39071 more = FALSE; 39072 39073 } 39074 } 39075 39076 else if (kstat == 0) 39077 { 39078 /* Two neighbours, search both directions */ 39079 for (ki = 0, prev = pt, pcurr = pt1, more = TRUE; (!mainpt) && (ki < 2); 39080 ki++, prev = pt, pcurr = pt2, more = TRUE) 39081 39082 while ((!mainpt) && more) 39083 { 39084 sh6getother (pcurr, prev, &pnext, &kstat); 39085 if (kstat < 0) 39086 goto error; 39087 39088 if (pnext && (pnext != pt)) 39089 { 39090 if (sh6ismain (pnext)) 39091 mainpt = pnext; 39092 else 39093 { 39094 prev = pcurr; 39095 pcurr = pnext; 39096 pnext = SISL_NULL; 39097 } 39098 } 39099 else 39100 more = FALSE; 39101 39102 } 39103 } 39104 } 39105 39106 goto out; 39107 39108 /* ------------------------------------------------------------- */ 39109 error:mainpt = SISL_NULL; 39110 s6err ("sh6getmain", kstat, 0); 39111 goto out; 39112 39113 39114 39115 out: 39116 return mainpt; 39117 } 39118 39119 //=========================================================================== 39120 void sh6idalledg (SISLObject * pob1, SISLObject * pob2, SISLIntdat * pintdat, 39121 SISLEdge * wedge[], int *jstat) 39122 //=========================================================================== 39123 { 39124 int kpos = 0; /* Position of error. */ 39125 int kstat = 0; /* Local error status. */ 39126 int ki,kj, kn; /* Counters. */ 39127 int kj1, kn1; /* Counters. */ 39128 int kndir; /* Number of par. dir. */ 39129 int kedg, kedg1; /* Number of edges. */ 39130 int kpar; /* Parameter number. */ 39131 int kleft1 = 0; /* Index of knot. */ 39132 int ln[4]; /* Number of vertices in each par. dir. */ 39133 int lk[4]; /* Order in each par. dir. */ 39134 double tpar; /* Parameter value at edge. */ 39135 double tparmain; /* Parameter of main point. */ 39136 double tparhelp; /* Parameter of help point. */ 39137 double *st[4]; /* Pointer to knot vector in each par. dir. */ 39138 SISLObject *qob1, *qob2; /* Help pointer to object. */ 39139 SISLObject *qob11, *qob21; /* Help pointer to object. */ 39140 SISLPtedge *pte = SISL_NULL; 39141 SISLPtedge *prev = SISL_NULL; 39142 SISLPtedge *pte1 = SISL_NULL; 39143 SISLIntpt *pmain; 39144 int notfound; 39145 39146 /* Set up information about the knot vector in each parameter direction. */ 39147 39148 if (pob1->iobj == SISLCURVE) 39149 { 39150 ln[0] = pob1->c1->in; 39151 lk[0] = pob1->c1->ik; 39152 st[0] = pob1->c1->et; 39153 } 39154 else if (pob1->iobj == SISLSURFACE) 39155 { 39156 ln[0] = pob1->s1->in1; 39157 lk[0] = pob1->s1->ik1; 39158 st[0] = pob1->s1->et1; 39159 ln[1] = pob1->s1->in2; 39160 lk[1] = pob1->s1->ik2; 39161 st[1] = pob1->s1->et2; 39162 } 39163 39164 if (pob2->iobj == SISLCURVE) 39165 { 39166 ln[pob1->iobj] = pob2->c1->in; 39167 lk[pob1->iobj] = pob2->c1->ik; 39168 st[pob1->iobj] = pob2->c1->et; 39169 } 39170 else if (pob2->iobj == SISLSURFACE) 39171 { 39172 ln[pob1->iobj] = pob2->s1->in1; 39173 lk[pob1->iobj] = pob2->s1->ik1; 39174 st[pob1->iobj] = pob2->s1->et1; 39175 ln[pob1->iobj+1] = pob2->s1->in2; 39176 lk[pob1->iobj+1] = pob2->s1->ik2; 39177 st[pob1->iobj+1] = pob2->s1->et2; 39178 } 39179 39180 for (kn = 0, qob1 = pob1, qob2 = pob2; kn < 2; kn++, qob1 = pob2, qob2 = pob1) 39181 { 39182 kedg = (qob1->iobj == SISLPOINT ? 0 : (qob1->iobj == SISLCURVE ? 2 : 4)); 39183 39184 if (kedg) 39185 wedge[kn]->ipoint = 0; 39186 39187 for (kj = 0; kj < kedg; kj++) 39188 { 39189 if (qob1->iobj == SISLCURVE) 39190 { 39191 tpar = (kj == 0 ? qob1->c1->et[qob1->c1->ik - 1] : 39192 qob1->c1->et[qob1->c1->in]); 39193 kpar = 1; 39194 } 39195 else if (kj == 0) 39196 { 39197 tpar = qob1->s1->et2[qob1->s1->ik2 - 1]; 39198 kpar = 2; 39199 } 39200 else if (kj == 1) 39201 { 39202 tpar = qob1->s1->et1[qob1->s1->in1]; 39203 kpar = 1; 39204 } 39205 else if (kj == 2) 39206 { 39207 tpar = qob1->s1->et2[qob1->s1->in2]; 39208 kpar = 2; 39209 } 39210 else 39211 { 39212 tpar = qob1->s1->et1[qob1->s1->ik1 - 1]; 39213 kpar = 1; 39214 } 39215 39216 s6idedg ((kn == 0 ? qob1 : qob2), (kn == 0 ? qob2 : qob1), 39217 kn + 1, kpar, tpar, pintdat, 39218 &(wedge[kn]->prpt[kj]), &(wedge[kn]->ipoint), &kstat); 39219 if (kstat < 0) 39220 goto error; 39221 } 39222 } 39223 39224 /* UJK newi; remove helppoints if main point is present */ 39225 for (kn = 0, qob1 = pob1, qob2 = pob2; kn < 2; kn++, qob1 = pob2, qob2 = pob1) 39226 { 39227 kedg = (qob1->iobj == SISLPOINT ? 0 : (qob1->iobj == SISLCURVE ? 2 : 4)); 39228 39229 for (kj = 0; kj < kedg; kj++) 39230 { 39231 for (pte = wedge[kn]->prpt[kj], prev = pte; 39232 pte != SISL_NULL;) 39233 { 39234 notfound = TRUE; 39235 39236 if ((pmain = sh6getmain (pte->ppt))) 39237 { 39238 /* pte is a help point and pmain is the 39239 main point connected to it */ 39240 39241 /* Check if the help point and main point lie 39242 in different knot intervals in any parameter 39243 direction. In that case, keep the help point. */ 39244 39245 for (kndir=pob1->iobj+pob2->iobj, ki=0; 39246 ki<kndir; ki++) 39247 { 39248 tparmain = pmain->epar[ki]; 39249 tparhelp = pte->ppt->epar[ki]; 39250 39251 /* Find position of parameter value in 39252 to the knot vector. */ 39253 39254 /* __________________________________ */ 39255 /* UJK, sept 93, this did not work 39256 for left hand help pts. */ 39257 /*s1219(st[ki],lk[ki],ln[ki],&kleft1,tparmain,&kstat); 39258 if (kstat < 0) goto error; 39259 39260 s1219(st[ki],lk[ki],ln[ki],&kleft2,tparhelp,&kstat); 39261 if (kstat < 0) goto error; 39262 39263 if (kleft1 != kleft2) break;*/ 39264 39265 s6fndintvl(st[ki],lk[ki],ln[ki],&kleft1, 39266 tparmain,tparhelp,0,&kstat); 39267 if (kstat < 0) goto error; 39268 39269 if (kstat) break; 39270 39271 /* UJK, sept 93, END */ 39272 /* __________________________________ */ 39273 } 39274 39275 if (ki == kndir) 39276 { 39277 /* Search for pmain */ 39278 for (kn1 = 0, qob11 = pob1, qob21 = pob2; 39279 kn1 < 2 && notfound; 39280 kn1++, qob11 = pob2, qob21 = pob1) 39281 { 39282 kedg1 = (qob11->iobj == SISLPOINT ? 39283 0 : (qob11->iobj == SISLCURVE ? 2 : 4)); 39284 39285 for (kj1 = 0; kj1 < kedg1 && notfound; kj1++) 39286 { 39287 for (pte1 = wedge[kn1]->prpt[kj1]; 39288 pte1 != SISL_NULL && notfound; 39289 pte1 = pte1->pnext) 39290 if (pte1->ppt == pmain) 39291 notfound = FALSE; 39292 } 39293 } 39294 } 39295 } 39296 39297 if (notfound == FALSE) 39298 { 39299 /* Main point is present, remove help point. */ 39300 if (prev == pte) 39301 { 39302 wedge[kn]->prpt[kj] = pte->pnext; 39303 freePtedge (pte); 39304 pte = wedge[kn]->prpt[kj]; 39305 prev = pte; 39306 wedge[kn]->ipoint--; 39307 } 39308 else 39309 { 39310 prev->pnext = pte->pnext; 39311 freePtedge (pte); 39312 pte = prev->pnext; 39313 wedge[kn]->ipoint--; 39314 } 39315 } 39316 if (notfound == TRUE) 39317 { 39318 sh6tomain(pte->ppt, &kstat); 39319 prev = pte; 39320 pte = pte->pnext; 39321 } 39322 39323 } 39324 } 39325 } 39326 39327 39328 *jstat = 0; 39329 39330 goto out; 39331 39332 /* Error in lower level routine. */ 39333 39334 error:*jstat = kstat; 39335 s6err ("sh6idalledg", *jstat, kpos); 39336 goto out; 39337 39338 out:; 39339 } 39340 39341 //=========================================================================== 39342 void freePtedge(SISLPtedge *p1) 39343 //=========================================================================== 39344 { 39345 /* Free the space that p1 occupies. */ 39346 39347 freearray(p1); 39348 39349 return; 39350 } 39351 39352 //=========================================================================== 39353 void freeEdge(SISLEdge *pedge) 39354 //=========================================================================== 39355 { 39356 39357 SISLPtedge *p1,*p2; /* Pointers to traverse lists of Ptedge-elements.*/ 39358 SISLPtedge *(*pel); /* Pointer to an array element. */ 39359 int ki; /* Counter. */ 39360 39361 /* First free the space occupied by the lists pointed at by 39362 the array prpt. */ 39363 39364 pel = pedge -> prpt; 39365 for (ki=0; ki<pedge->iedge; ki++) 39366 { 39367 39368 /* Traverse the list connected to edge nr ki and free the elements. */ 39369 39370 p1 = *pel; 39371 while (p1 != SISL_NULL) 39372 { 39373 p2 = p1 -> pnext; 39374 freePtedge(p1); 39375 p1 = p2; 39376 } 39377 pel++; 39378 } 39379 39380 /* Free the space occupied by the prpt array. */ 39381 39382 freearray(pedge -> prpt); 39383 39384 /* Free the space occupied by the instance. */ 39385 39386 freearray(pedge); 39387 39388 return; 39389 } 39390 39391 39392 //=========================================================================== 39393 void s1435(SISLSurf *ps1,int iedge,SISLCurve **rcedge,double *cpar,int *jstat) 39394 //=========================================================================== 39395 { 39396 int kstat = 0; /* Local status parameter. */ 39397 int kpos = 0; /* Position of error. */ 39398 double tstart1,tend1; /* Endpoints of parameter interval in first 39399 direction. */ 39400 double tstart2,tend2; /* Endpoints of parameter interval in second 39401 direction. */ 39402 double tpar; /* Parameter value of curve in constant parameter 39403 direction. */ 39404 39405 /* Fetch endpoints of parameter intervals. */ 39406 39407 tstart1 = *(ps1->et1 + ps1->ik1 - 1); 39408 tend1 = *(ps1->et1 + ps1->in1); 39409 tstart2 = *(ps1->et2 + ps1->ik2 - 1); 39410 tend2 = *(ps1->et2 + ps1->in2); 39411 39412 /* Find constant parameter of edge. */ 39413 39414 if (iedge == 0) tpar = tstart2; 39415 else if (iedge == 1) tpar = tend1; 39416 else if (iedge == 2) tpar = tend2; 39417 else if (iedge == 3) tpar = tstart1; 39418 39419 if (iedge == 0 || iedge == 2) 39420 { 39421 39422 /* Pick curve with constant second parameter. */ 39423 39424 s1436(ps1,tpar,rcedge,&kstat); 39425 if (kstat < 0) goto error; 39426 } 39427 else if (iedge == 1 || iedge == 3) 39428 { 39429 39430 /* Pick curve with constant first parameter. */ 39431 39432 s1437(ps1,tpar,rcedge,&kstat); 39433 if (kstat < 0) goto error; 39434 } 39435 39436 /* SISLCurve picked. */ 39437 39438 *cpar = tpar; 39439 *jstat = 0; 39440 goto out; 39441 39442 /* Error in lower level routine. */ 39443 39444 error : *jstat = kstat; 39445 s6err("s1435",*jstat,kpos); 39446 goto out; 39447 39448 out: return; 39449 } 39450 39451 39452 //=========================================================================== 39453 SISLPtedge *newPtedge (SISLIntpt * ppt) 39454 //=========================================================================== 39455 { 39456 SISLPtedge *pnew; /* Local pointer to the instance to create. */ 39457 39458 /* Allocate space for the instance. */ 39459 39460 pnew = newarray (1, SISLPtedge); 39461 if (pnew == SISL_NULL) 39462 goto err101; 39463 39464 /* Initialize instance. */ 39465 39466 pnew->ppt = ppt; 39467 pnew->pnext = SISL_NULL; 39468 39469 /* Task done. */ 39470 39471 goto out; 39472 39473 /* Error in space allocation. Return zero. */ 39474 39475 err101:pnew = SISL_NULL; 39476 goto out; 39477 39478 out:return (pnew); 39479 } 39480 39481 39482 //=========================================================================== 39483 void s6idedg(SISLObject *po1,SISLObject *po2,int iobj,int ipar,double apar, 39484 SISLIntdat *pintdat,SISLPtedge **rptedge,int *jnum,int *jstat) 39485 //=========================================================================== 39486 { 39487 int kpos=0; /* Position of error. */ 39488 int kpar=0; /* Numper of parameter direction second obj.*/ 39489 int ki,kj; /* Counters */ 39490 double sstart[4],send[4]; /* Parameter boarders on the other obj. */ 39491 SISLPtedge *pte = SISL_NULL; /* Pointers to new ptedge. */ 39492 39493 /* Initiate to emty list. */ 39494 39495 *rptedge = SISL_NULL; 39496 *jstat = 0; 39497 39498 /* We have to be sure that we have an intdat structure. */ 39499 39500 if (pintdat == SISL_NULL) goto out; 39501 39502 /* Uppdate parameter boarder. */ 39503 39504 if (po1->iobj == SISLCURVE) 39505 { 39506 if (iobj == 1) 39507 { 39508 sstart[0] = apar; 39509 send[0] = apar; 39510 } 39511 else 39512 { 39513 sstart[0] = po1->c1->et[po1->c1->ik - 1]; 39514 send[0] = po1->c1->et[po1->c1->in]; 39515 } 39516 kpar = 1; 39517 } 39518 else if (po1->iobj == SISLSURFACE) 39519 { 39520 if (iobj == 1 && ipar == 1) 39521 { 39522 sstart[0] = apar; 39523 send[0] = apar; 39524 } 39525 else 39526 { 39527 sstart[0] = po1->s1->et1[po1->s1->ik1 - 1]; 39528 send[0] = po1->s1->et1[po1->s1->in1]; 39529 } 39530 if (iobj == 1 && ipar == 2) 39531 { 39532 sstart[1] = apar; 39533 send[1] = apar; 39534 } 39535 else 39536 { 39537 sstart[1] = po1->s1->et2[po1->s1->ik2 - 1]; 39538 send[1] = po1->s1->et2[po1->s1->in2]; 39539 } 39540 kpar = 2; 39541 } 39542 39543 39544 if (po2->iobj == SISLCURVE) 39545 { 39546 if (iobj == 2) 39547 { 39548 sstart[kpar] = apar; 39549 send[kpar] = apar; 39550 } 39551 else 39552 { 39553 sstart[kpar] = po2->c1->et[po2->c1->ik - 1]; 39554 send[kpar] = po2->c1->et[po2->c1->in]; 39555 } 39556 } 39557 else if (po2->iobj == SISLSURFACE) 39558 { 39559 if (iobj == 2 && ipar == 1) 39560 { 39561 sstart[kpar] = apar; 39562 send[kpar] = apar; 39563 } 39564 else 39565 { 39566 sstart[kpar] = po2->s1->et1[po2->s1->ik1 - 1]; 39567 send[kpar] = po2->s1->et1[po2->s1->in1]; 39568 } 39569 if (iobj == 2 && ipar == 2) 39570 { 39571 sstart[kpar+1] = apar; 39572 send[kpar+1] = apar; 39573 } 39574 else 39575 { 39576 sstart[kpar+1] = po2->s1->et2[po2->s1->ik2 - 1]; 39577 send[kpar+1] = po2->s1->et2[po2->s1->in2]; 39578 } 39579 } 39580 39581 /* We have to go trough all intersection points to search for edges. */ 39582 39583 for (ki=0; ki<pintdat->ipoint; ki++) 39584 { 39585 for (kj=0; kj<pintdat->vpoint[ki]->ipar; kj++) 39586 if ((DEQUAL(sstart[kj],pintdat->vpoint[ki]->epar[kj]) || 39587 sstart[kj] < pintdat->vpoint[ki]->epar[kj]) && 39588 (DEQUAL(send[kj],pintdat->vpoint[ki]->epar[kj]) || 39589 send[kj] > pintdat->vpoint[ki]->epar[kj])); 39590 else 39591 goto end; 39592 39593 if (pte == SISL_NULL) 39594 { 39595 pte = newPtedge(pintdat->vpoint[ki]); 39596 if (pte == SISL_NULL) goto err101; 39597 39598 (*rptedge) = pte; 39599 39600 (*jnum)++; 39601 } 39602 else 39603 { 39604 pte->pnext = newPtedge(pintdat->vpoint[ki]); 39605 if (pte->pnext == SISL_NULL) goto err101; 39606 39607 pte = pte->pnext; 39608 39609 (*jnum)++; 39610 } 39611 end:; 39612 } 39613 39614 goto out; 39615 39616 /* Error in space allocation. */ 39617 39618 err101: 39619 *jstat = -101; 39620 s6err("s6idedg",*jstat,kpos); 39621 goto out; 39622 39623 out: ; 39624 } 39625 39626 39627 //=========================================================================== 39628 int s6knotmult(double et[],int ik,int in,int *ileft,double ax,int *jstat) 39629 //=========================================================================== 39630 { 39631 int kpos=0; /* The position of the error. */ 39632 int kstat; /* Local status variable */ 39633 int kmult=0; /* Multiplicity of knot */ 39634 int ki; /* Loop variable */ 39635 39636 /* Localize knot interval */ 39637 39638 s1219(et,ik,in,ileft,ax,&kstat); 39639 if (kstat<0) goto error; 39640 39641 if (et[*ileft] == ax) 39642 { 39643 kmult = 1; 39644 ki = *ileft-1; 39645 for (ki=(*ileft)-1; 0 <= ki; ki--) 39646 if (et[ki] == ax) kmult++; 39647 } 39648 if (et[in] == ax) 39649 { 39650 for (ki=in ; ki<in+ik;ki++) 39651 if (et[ki] == ax) kmult++; 39652 } 39653 39654 *jstat = 0; 39655 goto out; 39656 39657 /* Error in lower level function */ 39658 39659 error: *jstat = kstat; 39660 s6err("s6knotmult",*jstat,kpos); 39661 goto out; 39662 39663 out: 39664 return(kmult); 39665 } 39666 39667 39668 //=========================================================================== 39669 void test_cyclic_knots(double et[],int in,int ik,int *jstat) 39670 //=========================================================================== 39671 { 39672 int kleft; /* Pointer into knot interval */ 39673 int kmult1; /* Multiplicity of start parameter value */ 39674 int kmult2; /* Multiplicity of end parameter value */ 39675 int ki; /* Control variable in loop */ 39676 int kpos = 1; /* Position of error */ 39677 int kant; /* Number of knots before start parameter value */ 39678 int kcyclic; /* Flag telling if cyclic basis */ 39679 int kstat; /* Local status variable */ 39680 39681 double tperiode; /* Periode of basis */ 39682 39683 /* Find multiplicity of et[ik-1] and et[in] */ 39684 39685 kleft = ik-1; 39686 39687 kmult1 = s6knotmult(et,ik,in,&kleft,et[ik-1],&kstat); 39688 if(kstat<0) goto error; 39689 39690 kleft = in; 39691 39692 kmult2 = s6knotmult(et,ik,in,&kleft,et[in],&kstat); 39693 if(kstat<0) goto error; 39694 39695 if (kmult1 != kmult2 || kmult1 == ik) goto noncyclic; 39696 39697 kant = ik - kmult1; 39698 tperiode = et[in] -et[ik-1]; 39699 39700 /* Test that the first kant knots are repetitions of the knots in-kant,...,in-1 */ 39701 39702 for (ki=0, kcyclic=1; ki<kant ; ki++) 39703 if (DNEQUAL((et[ki]+tperiode),et[in-kant+ki])) kcyclic = 0; 39704 39705 /* Test that the last kant knots are repetions of knots ik,..,ik+kant-1 */ 39706 39707 for (ki=0; ki<kant ; ki++) 39708 if (DNEQUAL((et[ik+ki]+tperiode),et[in+kmult1+ki])) kcyclic = 0; 39709 39710 if (kcyclic == 0) goto noncyclic; 39711 39712 /* The basis should have at least kant+ik degrees of freedom to allow for 39713 a proper cyclic curve with ik degrees of real freadom since kant vertices 39714 are repeated */ 39715 39716 if (in<ik+kant) goto missing_freedom; 39717 39718 /* Cyclic with enough degrees of freedom */ 39719 39720 *jstat = 2; 39721 goto out; 39722 39723 /* Cyclic with less than ik+kant degrees of freedom */ 39724 missing_freedom: 39725 39726 *jstat = 1; 39727 goto out; 39728 39729 /* Noncyclic basis */ 39730 noncyclic: 39731 39732 *jstat = 0; 39733 goto out; 39734 39735 error: 39736 *jstat = kstat; 39737 s6err("test_cyclic_knots",*jstat,kpos); 39738 goto out; 39739 39740 out: 39741 39742 return; 39743 39744 } 39745 39746 //=========================================================================== 39747 double s1325(double aradiu,double angle) 39748 //=========================================================================== 39749 { 39750 double tcos,tsin; /* Dummy variables */ 39751 double ta,tb,tc,tl; /* Dummy variables */ 39752 double tconst = (double)1.85530139760811990992528773586425; 39753 /* Constant used in the calculation */ 39754 39755 39756 39757 tcos = cos(angle); 39758 tsin = sin(angle); 39759 39760 /* Calculate length of tangents 39761 * tconst = (3-2sqrt(2))**1/3 + (3+2sqrt(2))**1/3 - 0.5 */ 39762 39763 ta = (double)0.6*tconst - (double)0.9*tcos; 39764 tb = ((double)0.4*tconst+(double)1.8)*tsin; 39765 tc = ((double)0.4*tconst+(double)1.0) 39766 * tcos - (double)0.4*tconst - (double)1.0; 39767 tl = aradiu*(-tb+sqrt(tb*tb-4*ta*tc))/((double)2.0*ta); 39768 39769 return(tl); 39770 } 39771 39772 //=========================================================================== 39773 void s1359(double egeo[],double aepsge,int idim,int inbinf, 39774 int ipar,double epar[],SISLCurve **rcurve,int *jstat) 39775 //=========================================================================== 39776 { 39777 int kn; /* Number of vertices */ 39778 int kk = 4; /* Order of b-spline basis */ 39779 int knt; /* Number of knots produced so far */ 39780 int kvert; /* Pointer to first free variable in vertex array */ 39781 int kpos =1; /* Position of error */ 39782 int kstat; /* Local status variable */ 39783 int ki,kj; /* Running variables in loop */ 39784 int kv1,kv2,kv3; /* Running variables in loop */ 39785 int kincre; /* Number of doubles for each point in egeo */ 39786 int kcycpos; /* Indicator telling if cyclic or open geometry */ 39787 double *sprevp; /* Pointer to position at start of current segment */ 39788 double *sprevt; /* Pointer to tangent at start of current segment */ 39789 double *sprevc; /* Pointer to curvature at start of current segment */ 39790 double *sprevr; /* Pointer to radius of curvature start current segment*/ 39791 double snprevt[3]; /* Nomralized version of sprevc */ 39792 double *scurp; /* Pointer to position at end of current segment */ 39793 double *scurt; /* Pointer to tangent at end of current segment */ 39794 double *scurc; /* Pointer to curvature at end of current segment */ 39795 double *scurr; /* Pointer to radius of curvature end current segment*/ 39796 double sncurt[3]; /* Normalized version of scurc */ 39797 double tcos; /* Description of angle */ 39798 double tl1,tl2; /* Tangent lengths */ 39799 double tangle; /* Arcus cosinus if tcos */ 39800 double tdist; /* Distance between start and end of current segment */ 39801 double tpar; /* Parameter value at end of segment */ 39802 double *st = SISL_NULL; /* Pointer to knot vector */ 39803 double *scoef=SISL_NULL; /* Pointer to vertices */ 39804 double tmpval=aepsge;/* Maximal difference in x, y and z coordinate */ 39805 double max_dist; 39806 /* Allocate space for knots and vertices */ 39807 39808 if (idim != 2 && idim != 3) goto err105; 39809 39810 /* No. of points given must be > 1 since it makes no sence to interpolate 39811 over 0 or 1 point, so check inbinf.*/ 39812 39813 if (inbinf < 2) goto err181; 39814 39815 39816 if (idim==2) 39817 kincre = 7; 39818 else 39819 kincre = 10; 39820 39821 39822 /* To make sure that we don't make a too long jump in parametrization, find 39823 maximal difference in x, y and z coordinate. */ 39824 39825 if (ipar==0) 39826 { 39827 double tmin,tmax,*sp; 39828 39829 for (kj=0 ; kj<idim ; kj++) 39830 { 39831 tmin = *(egeo+kj); 39832 tmax = tmin; 39833 for (ki=0,sp=egeo+kj ; ki < inbinf ; ki++,sp+=kincre) 39834 { 39835 tmin = MIN(tmin,*sp); 39836 tmax = MAX(tmax,*sp); 39837 } 39838 tmpval = MAX(tmpval,(tmax-tmin)); 39839 } 39840 } 39841 39842 kn = 3*(inbinf-1) + 1; 39843 scoef = newarray(idim*kn,DOUBLE); 39844 if (scoef == SISL_NULL) goto err101; 39845 39846 st = newarray(kk+kn,DOUBLE); 39847 if (st == SISL_NULL) goto err101; 39848 39849 /* Make four first knots */ 39850 if (ipar==0) 39851 { 39852 epar[0] = DZERO; 39853 } 39854 39855 st[0] = epar[0]; 39856 st[1] = epar[0]; 39857 st[2] = epar[0]; 39858 st[3] = epar[0]; 39859 39860 /* Make first vertex */ 39861 memcopy(scoef,egeo,idim,DOUBLE); 39862 39863 39864 /* Set pointers to start point, tangent, curvature and radius of curvature 39865 */ 39866 39867 sprevp = egeo; 39868 sprevt = sprevp + idim; 39869 sprevc = sprevt + idim; 39870 sprevr = sprevc + idim; 39871 39872 /* Normalize curvature vector at start */ 39873 39874 (void)s6norm(sprevt,idim,snprevt,&kstat); 39875 39876 for (ki=1,knt=4,kvert=idim;ki<inbinf;ki++) 39877 { 39878 39879 /* For each pair of adjacent points in egeo make an Hermit segment */ 39880 39881 /* Set pointers position, tangent, curvature and radius of end of 39882 current segment segment */ 39883 39884 scurp = sprevp + kincre; 39885 scurt = sprevt + kincre; 39886 scurc = sprevc + kincre; 39887 scurr = sprevr + kincre; 39888 39889 /* Normalize curvature vector at end of segment */ 39890 39891 (void)s6norm(scurt,idim,sncurt,&kstat); 39892 39893 /* Make cosine of angle between tangent vectors by making the scalar 39894 product of the normalized versions of the two vectors */ 39895 39896 tcos = s6scpr(snprevt,sncurt,idim); 39897 39898 /* Find the actual angle by making the arcus tangens of this value */ 39899 39900 if (tcos >= DZERO) 39901 tcos = MIN((double)1.0,tcos); 39902 else 39903 tcos = MAX((double)-1.0,tcos); 39904 39905 tangle = fabs(acos(tcos)); 39906 39907 if (tangle < ANGULAR_TOLERANCE) tangle = DZERO; 39908 39909 tdist = s6dist(sprevp,scurp,idim); 39910 39911 /* Make tangent length of start of segment */ 39912 39913 39914 /* UJK and VSK 24.10.90 */ 39915 /* if (DEQUAL(tangle,DZERO) || *sprevr < (double)-1.0) */ 39916 if (DEQUAL(tangle,DZERO) || *sprevr < DZERO) 39917 { 39918 /* Parallel tangents or infinit radius of curvature use 1/3 of 39919 the distance between the points as tangent length */ 39920 tl1 = tdist/(double)3.0; 39921 } 39922 else 39923 { 39924 /* Base tangent length on radius of curvature and opening angle */ 39925 tl1 = s1325(*sprevr,tangle); 39926 } 39927 39928 /* Make tangent length of end of segment */ 39929 39930 if (DEQUAL(tangle,DZERO) || *scurr < DZERO) 39931 { 39932 /* Parallel tangents or infinit radius of curvature use 1/3 of 39933 the distance between the points as tangent length */ 39934 tl2 = tdist/(double)3.0; 39935 } 39936 else 39937 { 39938 /* Base tangent length on radius of curvature and opening angle */ 39939 tl2 = s1325(*scurr,tangle); 39940 } 39941 39942 /* Make sure that the tangent does not explode due to numeric errors, 39943 and make a controlled tangent when the radius is zero or almost zero*/ 39944 39945 /* ALA 28.10.93 An improved control was nessesary*/ 39946 39947 if (tangle < 0.1) max_dist = (double)0.35*tdist; 39948 else if (tangle < 0.35) max_dist = (double)0.40*tdist; 39949 else if (tangle < 0.75) max_dist = (double)0.50*tdist; 39950 else max_dist = (double)0.70*tdist; 39951 39952 if ( tl1 > max_dist) tl1 = max_dist; 39953 if ( tl2 > max_dist) tl2 = max_dist; 39954 39955 /* We want to have a parametrization that is as close as possible to an 39956 arc length parametrization */ 39957 39958 39959 if (ipar==0) 39960 { 39961 /* Make parametrization of segment by making an average of arc of a 39962 circle with radius sprevr and scurr spanning an angle tangle. 39963 If one or both radius infinit use the distance between the points 39964 */ 39965 39966 if (DNEQUAL(*sprevr,(double)-1.0) && 39967 DNEQUAL(*scurr,(double)-1.0)) 39968 { 39969 tpar = (double)0.5*tangle*(*sprevr+*scurr); 39970 } 39971 else if (DNEQUAL(*sprevr,(double)-1.0) && 39972 DEQUAL(*scurr,(double)-1.0)) 39973 { 39974 tpar = (double)0.5*(*sprevr*tangle + tdist); 39975 } 39976 else if (DEQUAL(*sprevr,(double)-1.0) && 39977 DNEQUAL(*scurr,(double)-1.0)) 39978 { 39979 tpar = (double)0.5*(tdist + tangle*(*scurr)); 39980 } 39981 else 39982 { 39983 tpar = tdist; 39984 } 39985 39986 tpar = MAX(tpar,tdist); 39987 tpar = MAX(tpar,aepsge); 39988 39989 /* Make sure that we don't make a parameter inteval greater than 39990 the maximal length of a SISLbox around the input points */ 39991 39992 /* tpar = MIN(tpar,tmpval); 39993 BOH:220793: Start change */ 39994 39995 if (tangle <= PIHALF) 39996 tpar = MIN(tpar, ((double)1.1*tdist)); 39997 else 39998 tpar = MIN(tpar,tmpval); 39999 40000 /* BOH: End change. */ 40001 40002 if (DEQUAL((epar[ki-1]+tpar),epar[ki-1])) 40003 { 40004 tpar = fabs(epar[ki-1])*(double)0.1; 40005 } 40006 40007 if (DEQUAL(tpar,DZERO)) 40008 { 40009 tpar = (double)1.0; 40010 } 40011 40012 epar[ki] = epar[ki-1] + tpar; 40013 40014 } 40015 40016 /* Make 3 new knots */ 40017 st[knt] = epar[ki]; 40018 st[knt+1] = epar[ki]; 40019 st[knt+2] = epar[ki]; 40020 40021 /* Make 3 new vertices of segment */ 40022 40023 for (kj=0,kv1=kvert,kv2=kv1+idim,kv3=kv2+idim ; kj<idim ; 40024 kj++,kv1++,kv2++,kv3++) 40025 { 40026 scoef[kv1] = sprevp[kj] + tl1*sprevt[kj]; 40027 scoef[kv2] = scurp[kj] - tl2*scurt[kj]; 40028 scoef[kv3] = scurp[kj]; 40029 } 40030 40031 /* Update pointers */ 40032 sprevp = scurp; 40033 sprevt = scurt; 40034 sprevc = scurc; 40035 sprevr = scurr; 40036 for (kj=0;kj<idim;kj++) snprevt[kj] = sncurt[kj]; 40037 40038 /* Only update number of vertices if epar[ki-1] != epar[ki] */ 40039 40040 if (DNEQUAL(epar[ki-1],epar[ki])) 40041 { 40042 kvert+=(3*idim); 40043 knt+=3; 40044 } 40045 } 40046 40047 /* VSK, 07.94. Moved this statement before inserting the last knot. 40048 Update number of vertices */ 40049 40050 kn = kvert/idim; 40051 40052 /* Insert last knot */ 40053 40054 st[kn+kk-1] = st[kn+kk-2]; 40055 40056 /* Test if cyclic curve */ 40057 40058 for (ki=0, kcycpos=1 ; ki<idim ; ki++) 40059 if (egeo[ki] != egeo[(inbinf-1)*kincre+ki]) kcycpos=0; 40060 40061 if (kcycpos ==1) 40062 { 40063 st[0] -= (st[kn] - st[kn-1]); 40064 st[kn+kk-1] += (st[kk] - st[kk-1]); 40065 } 40066 40067 40068 /* Make the curve */ 40069 40070 kpos = 1; 40071 *rcurve = SISL_NULL; 40072 *rcurve = newCurve(kn,kk,st,scoef,1,idim,1); 40073 if (*rcurve == SISL_NULL) goto err101; 40074 40075 /* Periodicity flag */ 40076 if (kcycpos) 40077 { 40078 test_cyclic_knots(st,kn,kk,&kstat); 40079 if (kstat<0) goto error; 40080 if (kstat == 2) (*rcurve)->cuopen = SISL_CRV_PERIODIC; 40081 } 40082 *jstat = 0; 40083 goto out; 40084 40085 /* Error in space allocation. */ 40086 40087 err101: *jstat = -101; 40088 s6err("s1359",*jstat,kpos); 40089 goto out; 40090 40091 /* Error in lower level. */ 40092 40093 error: *jstat = kstat; 40094 s6err("s1359",*jstat,kpos); 40095 goto out; 40096 40097 /* Error in input, negative relative tolerance given */ 40098 40099 err105: *jstat = -105; 40100 s6err("s1359",*jstat,kpos); 40101 goto out; 40102 40103 /* Error in input, to few points given(inbinf < 2. */ 40104 40105 err181: *jstat = -181; 40106 s6err("s1359",*jstat,kpos); 40107 goto out; 40108 40109 /* Free allocated arrays */ 40110 out: 40111 40112 40113 if (st != SISL_NULL) freearray(st); 40114 if (scoef != SISL_NULL) freearray(scoef); 40115 40116 40117 return; 40118 } 40119 40120 //=========================================================================== 40121 void s1421(SISLSurf *ps1,int ider,double epar[],int *ilfs,int *ilft, 40122 double eder[],double enorm[],int *jstat) 40123 //=========================================================================== 40124 { 40125 int kstat=0; /* Local status variable. */ 40126 int kpos=0; /* The position of error. */ 40127 int kn1,kn2; /* The number of B-splines accociated with the knot 40128 vectors st1 and st2. */ 40129 int kk1,kk2; /* The polynomial order of the surface in the two 40130 directions. */ 40131 int kdim; /* The dimension of the space in which the surface 40132 lies. Equivalently, the number of components 40133 of each B-spline coefficient. */ 40134 int kleft2,kleft1; /* Local versions of ilfs and ilft which are 40135 used in order to avoid the pointers. */ 40136 int ki,kj,kih,kjh; /* Control variables in for loops and for stepping 40137 through arrays. */ 40138 int kh,kl,kl1,kl2; /* Control variables in for loops and for stepping 40139 through arrays. */ 40140 double *st1,*st2; /* The knot vectors of the surface. These have 40141 length [kn1+kk1] and [kn2+kk2], 40142 respectively. */ 40143 double *scoef; /* The B-spline coefficients of the surface. 40144 This is an array of dimension [kn2*kn1*kdim]. */ 40145 double tt; /* Dummy variable used for holding an array element 40146 in a for loop. */ 40147 double *ebder=SISL_NULL; /* Pointer to an array of dimension 40148 [max(kk1*(ider+1),kk2*(ider+1))] which will 40149 contain the values and ider first derivatives of 40150 the kk1 (kk2) nonzero B-splines at epar[0] (epar[1]). 40151 These are stored in the following order: 40152 First the value, 1. derivative etc. of the 40153 first nonzero B-spline, then the same for the 40154 second nonzero B-spline and so on. */ 40155 40156 double *ew=SISL_NULL; /* Pointer to an array of dimension [kk1*(ider+1)*kdim] 40157 which will be used to store the result of the first 40158 matrix multiplication in (2) above. This array is 40159 initialized to all zeros. */ 40160 double *sder=SISL_NULL; /* Pointer to array used for storage of points, if 40161 non rational sder points to eder, if rational sder 40162 has to be allocated to make room for the homogenous 40163 coordinate */ 40164 40165 double sdum1[49]; /* Arraye used for ebder */ 40166 double sdum2[147]; /* Array used for ew */ 40167 int knumb1; /* Necessary size of ebder */ 40168 int knumb2; /* Necessary size of ew */ 40169 40170 int tot,temp; /* Temporary variables. */ 40171 int kinc; /* For controlling kih. */ 40172 40173 kleft1 = *ilfs; 40174 kleft2 = *ilft; 40175 40176 /* Copy surface to local parameters. */ 40177 40178 kn1 = ps1 -> in1; 40179 kn2 = ps1 -> in2; 40180 kk1 = ps1 -> ik1; 40181 kk2 = ps1 -> ik2; 40182 st1 = ps1 -> et1; 40183 st2 = ps1 -> et2; 40184 kdim = ps1 -> idim; 40185 if (ps1->ikind == 2 || ps1->ikind == 4) 40186 { 40187 scoef = ps1 -> rcoef; 40188 kdim +=1; 40189 if((sder=newarray(kdim*(ider+1)*(ider+2)/2,DOUBLE)) == SISL_NULL) 40190 goto err101; 40191 } 40192 else 40193 { 40194 scoef = ps1 -> ecoef; 40195 sder = eder; 40196 } 40197 40198 /* Check the input. */ 40199 40200 if (kdim < 1) goto err102; 40201 if (kk1 < 1) goto err115; 40202 if (kn1 < kk1 || kn2 < kk2) goto err116; 40203 if (ider < 0) goto err178; 40204 if (st1[kk1-1] == st1[kk1] || st1[kn1-1] == st1[kn1]) goto err117; 40205 if (st2[kk2-1] == st2[kk2] || st2[kn2-1] == st2[kn2]) goto err117; 40206 40207 /* Allocate space for B-spline values and derivatives and one work array. */ 40208 40209 knumb1 = max(kk1*(ider+1),kk2*(ider+1)); 40210 40211 /* ONly allocate ebder if sdum1 too small */ 40212 40213 if (knumb1>49) 40214 { 40215 if((ebder = newarray(knumb1,double)) == SISL_NULL) goto err101; 40216 } 40217 else 40218 { 40219 ebder = &sdum1[0]; 40220 for (ki=0;ki<knumb1;ki++) 40221 ebder[ki] = DZERO; 40222 } 40223 40224 if (ebder == SISL_NULL) goto err101; 40225 40226 /* Only allocate ew if sdum2 too small */ 40227 40228 knumb2 = (kk1*(ider+1)*kdim); 40229 if (knumb2>147) 40230 { 40231 if((ew=new0array(knumb2,double)) == SISL_NULL) goto err101; 40232 } 40233 else 40234 { 40235 ew = &sdum2[0]; 40236 for (ki=0;ki<knumb2;ki++) 40237 sdum2[ki] = DZERO; 40238 } 40239 40240 if (ew == SISL_NULL) goto err101; 40241 40242 /* Set all the elements of sder to 0. */ 40243 40244 for (ki=0; ki<kdim*(ider+1)*(ider+2)/2; ki++) sder[ki] = DZERO; 40245 40246 /* Compute the values and derivatives of the nonzero B-splines in the 40247 second parameter direction. */ 40248 40249 s1220(st2,kk2,kn2,&kleft2,epar[1],ider,ebder,&kstat); 40250 40251 if (kstat < 0) goto error; 40252 40253 /* Update ilfs (ilft was updated above, in s1220). */ 40254 40255 s1219(st1,kk1,kn1,&kleft1,epar[0],&kstat); 40256 40257 if (kstat < 0) goto error; 40258 40259 /* Compute the first matrix product in (2) above. */ 40260 40261 /* ki steps through the appropriate kk2 rows of B-spline coefficients 40262 while kih steps through the B-spline value and derivatives for the 40263 B-spline given by ki. */ 40264 40265 kih = 0; 40266 for (ki=kleft2-kk2+1; ki<=kleft2; ki++) 40267 { 40268 /* kj counts through the ider+1 derivatives to be computed. 40269 kjh steps through ew once for each ki to accumulate the contribution 40270 from the different B-splines. 40271 kl1 points to the first component of the first B-spline coefficient 40272 in row no. ki of the B-spline coefficient matrix that multiplies 40273 a nonzero B-spline in the first parameter direction. 40274 */ 40275 40276 kjh = 0; kl1 = ki*kdim*kn1 + kdim*(kleft1-kk1+1); 40277 for (kj=0; kj<=ider; kj++) 40278 { 40279 40280 /* The value of the B-spline derivative is stored in tt while 40281 kl2 steps through the kdim components of all the B-spline 40282 coefficients that multiplies nonzero B-splines along st1. 40283 */ 40284 40285 tt = ebder[kih++]; kl2 = kl1; 40286 for (kl=0; kl<kdim*kk1; kl++,kjh++,kl2++) 40287 { 40288 ew[kjh] += scoef[kl2]*tt; 40289 } 40290 } 40291 } 40292 40293 /* Compute the values and derivatives of the nonzero B-splines in the 40294 first parameter direction. */ 40295 40296 s1220(st1,kk1,kn1,&kleft1,epar[0],ider,ebder,&kstat); 40297 40298 if (kstat < 0) goto error; 40299 40300 /* Compute the remaining matrix product. */ 40301 40302 /* kh steps through the ider+1 derivatives in the first parameter direction 40303 (the rows of ew if we image it as a kk1x(ider+1) matrix with each element 40304 a kdim dimensional vector) while kl1 steps through the elements of ew 40305 (again considering each element to have kdim components). 40306 */ 40307 40308 kl1 = 0; 40309 for (kh=0; kh<=ider; kh++) 40310 { 40311 /* ki steps through the kk1 columns of ew (corresponding to the columns 40312 of scoef that multiply nonzero B-splines along st1), while kih 40313 steps through the B-spline values and derivatives for the nonzero 40314 B-splines along st1 (stored in ebder). 40315 */ 40316 40317 kinc = 0; 40318 for (ki=0; ki<kk1; ki++,kinc+=(ider+1)) 40319 { 40320 40321 kih = kinc; 40322 40323 /* kj counts through the ider+1 derivatives in the first 40324 parameter direction (corresponding to the columns of sder). 40325 kjh points to the row of sder corresponding to derivatives of 40326 order kh in the second parameter direction (if sder is 40327 considered a matrix with elements consisting of vectors with 40328 kdim components). 40329 */ 40330 40331 for (kj=0; kj<=ider-kh; kj++) 40332 { 40333 /* Find index for sder (a triangular matrix). */ 40334 40335 tot = kj + kh; 40336 40337 temp = ((tot * (tot+1)) >> 1) + kh; 40338 40339 kjh = temp * kdim; 40340 40341 /* Pick out the current element of ebder. 40342 kl2 steps through the kdim components of the (kh,ki) 40343 element of ew. 40344 */ 40345 40346 tt = ebder[kih++]; 40347 kl2 = kl1; 40348 for (kl=0; kl<kdim; kl++,kjh++,kl2++) 40349 { 40350 sder[kjh] += ew[kl2]*tt; 40351 } 40352 } 40353 kl1 += kdim; 40354 } 40355 } 40356 40357 /* Free memory. */ 40358 40359 /* If rational surface calculate the derivatives based on derivatives in 40360 homogenous coordinates */ 40361 40362 if (ps1->ikind == 2 || ps1->ikind == 4) 40363 { 40364 s6strider(sder,ps1->idim,ider,eder,&kstat); 40365 if (kstat<0) goto error; 40366 if(sder != SISL_NULL) freearray(sder); 40367 } 40368 40369 /* Only free ew and ebder if the were allocated by newarray */ 40370 40371 if (knumb1 > 49 && ebder != SISL_NULL) 40372 freearray(ebder); 40373 if (knumb2 > 147 && ew != SISL_NULL) 40374 freearray(ew); 40375 40376 /* Make cross products of tangents, if idim==3 and derivative >0 */ 40377 40378 if (ider>0 && ps1->idim ==3) 40379 { 40380 double tlen1,tlen2,tnorm,tang=(double)0.0; 40381 40382 s6crss(eder+ps1->idim,eder+2*ps1->idim,enorm); 40383 40384 /* Make length of tangents and normal */ 40385 40386 tlen1 = s6length(eder+ps1->idim,ps1->idim,&kstat); 40387 tlen2 = s6length(eder+2*ps1->idim,ps1->idim,&kstat); 40388 tnorm = s6length(enorm,ps1->idim,&kstat); 40389 40390 /* Calculate angle between tangents */ 40391 40392 if (tlen1 != DZERO && tlen2 != DZERO && tnorm != DZERO) 40393 tang = tnorm/(tlen1*tlen2); 40394 40395 if (tang == DZERO) *jstat = 2; 40396 else if (tang <= ANGULAR_TOLERANCE) *jstat = 1; 40397 else *jstat = 0; 40398 goto out; 40399 } 40400 40401 /* Successful computations. */ 40402 40403 *jstat = 0; 40404 goto out; 40405 40406 /* Not enough memory. */ 40407 err101: *jstat = -101; 40408 s6err("s1421",*jstat,kpos); 40409 goto out; 40410 40411 /* kdim less than 1. */ 40412 err102: *jstat = -102; 40413 s6err("s1421",*jstat,kpos); 40414 goto out; 40415 40416 /* Polynomial order less than 1. */ 40417 err115: *jstat = -115; 40418 s6err("s1421",*jstat,kpos); 40419 goto out; 40420 40421 /* Fewer B-splines than the order. */ 40422 err116: *jstat = -116; 40423 s6err("s1421",*jstat,kpos); 40424 goto out; 40425 40426 /* Error in knot vector. 40427 (The first or last interval of one of the knot vectors is empty.) */ 40428 err117: *jstat = -117; 40429 s6err("s1421",*jstat,kpos); 40430 goto out; 40431 40432 /* Illegal derivative requested. */ 40433 err178: *jstat = -178; 40434 s6err("s1221",*jstat,kpos); 40435 goto out; 40436 40437 /* Error in lower level routine. */ 40438 40439 error: *jstat = kstat; 40440 s6err("s1421",*jstat,kpos); 40441 goto out; 40442 40443 out: 40444 *ilfs = kleft1; 40445 *ilft = kleft2; 40446 return; 40447 } 40448 40449 //=========================================================================== 40450 void s1851(SISLSurf *ps1,double epoint[],double enorm[],int idim, 40451 double aepsco,double aepsge,int *jpt,double **gpar, 40452 int *jcrv,SISLIntcurve ***wcurve,int *jstat) 40453 //=========================================================================== 40454 { 40455 int kstat = 0; /* Local status variable. */ 40456 int kpos = 0; /* Position of error. */ 40457 int i; 40458 int trackflag = 0; 40459 int jtrack; 40460 SISLTrack **wtrack=SISL_NULL; 40461 int jsurf = 0; 40462 SISLIntsurf **wsurf=SISL_NULL; 40463 int *pretop=SISL_NULL; 40464 40465 sh1851(ps1, epoint, enorm, idim, aepsco, aepsge,trackflag, &jtrack, 40466 &wtrack,jpt, gpar,&pretop,jcrv,wcurve,&jsurf,&wsurf,&kstat); 40467 if(kstat < 0) goto error; 40468 40469 if(pretop != SISL_NULL) freearray(pretop); 40470 40471 for(i=0; i<jsurf; i++) 40472 freeIntsurf(wsurf[i]); 40473 if(wsurf != SISL_NULL) freearray(wsurf); 40474 40475 if(jsurf > 0) 40476 *jstat=10; 40477 else 40478 *jstat = 0; 40479 goto out; 40480 40481 /* Error in lower level routine. */ 40482 40483 error : 40484 *jstat = kstat; 40485 s6err("s1851",*jstat,kpos); 40486 goto out; 40487 40488 out: 40489 return; 40490 } 40491 40492 //=========================================================================== 40493 void s1859(SISLSurf *ps1,SISLSurf *ps2,double aepsco,double aepsge, 40494 int *jpt,double **gpar1,double **gpar2,int *jcrv, 40495 SISLIntcurve ***wcurve,int *jstat) 40496 //=========================================================================== 40497 { 40498 int kstat = 0; /* Local status variable. */ 40499 int kpos = 0; /* Position of error. */ 40500 int i; 40501 40502 int trackflag = 0; 40503 int jtrack; 40504 SISLTrack **wtrack=SISL_NULL; 40505 int *pretop=SISL_NULL; 40506 int jsurf; 40507 SISLIntsurf **wsurf=SISL_NULL; 40508 40509 sh1859 (ps1, ps2, aepsco, aepsge, trackflag, &jtrack, &wtrack, jpt, gpar1, 40510 gpar2, &pretop, jcrv, wcurve,&jsurf,&wsurf,&kstat); 40511 if(kstat < 0) goto error; 40512 40513 if(pretop != SISL_NULL) freearray(pretop); 40514 40515 for(i=0; i<jsurf; i++) 40516 freeIntsurf(wsurf[i]); 40517 if(wsurf != SISL_NULL) freearray(wsurf); 40518 40519 if(jsurf > 0) 40520 *jstat=10; 40521 else 40522 *jstat = 0; 40523 goto out; 40524 40525 /* Error in lower level routine. */ 40526 40527 error : 40528 *jstat = kstat; 40529 s6err("s1859",*jstat,kpos); 40530 goto out; 40531 40532 out: 40533 40534 /* 40535 * Exit s1859. 40536 * ----------- 40537 */ 40538 40539 return; 40540 } 40541 40542 //=========================================================================== 40543 void s1770(SISLCurve *pcurve1,SISLCurve *pcurve2,double aepsge, 40544 double astart1,double astart2,double aend1,double aend2, 40545 double anext1,double anext2,double *cpos1,double *cpos2,int *jstat) 40546 //=========================================================================== 40547 { 40548 int kstat = 0; /* Local status variable. */ 40549 int kpos = 0; /* Position of error. */ 40550 int kleft1=0,kleft2=0; /* Variables used in the evaluator. */ 40551 int kder=1; /* Order of derivatives to be calulated */ 40552 int kdim; /* Dimension of space the curves lie in */ 40553 int knbit; /* Number of iterations */ 40554 int kdir; /* Changing direction. */ 40555 double tdelta1,tdelta2; /* Parameter interval of the curves. */ 40556 double tdist; /* Distance between position and origo. */ 40557 double td[2],t1[2],tdn[2];/* Distances between old and new parameter 40558 value in the two parameter directions. */ 40559 double tprev; /* Previous difference between the curves. */ 40560 double *sval1=SISL_NULL; /* Value ,first and second derivatie on curve 1*/ 40561 double *sval2; /* Value ,first and second derivatie on curve 1*/ 40562 double *sdiff; /* Difference between the curves */ 40563 40564 /* Test input. */ 40565 40566 if (pcurve1->idim != pcurve2->idim) goto err106; 40567 40568 kdim = pcurve1 -> idim; 40569 if (kdim == 2) 40570 { 40571 s1770_2D(pcurve1,pcurve2,aepsge,astart1,astart2, 40572 aend1,aend2,anext1,anext2,cpos1,cpos2,jstat); 40573 goto out; 40574 } 40575 40576 /* Fetch endpoints and the intervals of parameter interval of curves. */ 40577 40578 tdelta1 = pcurve1->et[pcurve1->in] - pcurve1->et[pcurve1->ik - 1]; 40579 tdelta2 = pcurve2->et[pcurve2->in] - pcurve2->et[pcurve2->ik - 1]; 40580 40581 /* Allocate local used memory */ 40582 40583 sval1 = newarray((2*kder+5)*kdim,double); 40584 if (sval1 == SISL_NULL) goto err101; 40585 40586 sval2 = sval1 + (kder+2)*kdim; 40587 sdiff = sval2 + (kder+2)*kdim; 40588 40589 /* Initiate variables. */ 40590 40591 tprev = (double)HUGE; 40592 40593 /* Evaluate 0-1.st derivatives of both curves */ 40594 40595 s1221(pcurve1,kder,anext1,&kleft1,sval1,&kstat); 40596 if (kstat < 0) goto error; 40597 40598 s1221(pcurve2,kder,anext2,&kleft2,sval2,&kstat); 40599 if (kstat < 0) goto error; 40600 40601 /* Compute the distanse vector and value and the new step. */ 40602 40603 s1770_s9dir(&tdist,td,td+1,sdiff,sval1,sval2,kdim); 40604 40605 /* Correct if we are not inside the parameter intervall. */ 40606 40607 t1[0] = td[0]; 40608 t1[1] = td[1]; 40609 s1770_s9corr(t1,anext1,anext2,astart1,aend1,astart2,aend2); 40610 40611 /* Iterate to find the intersection point. */ 40612 40613 for (knbit = 0; knbit < 30; knbit++) 40614 { 40615 /* Evaluate 0-1.st derivatives of both curves */ 40616 40617 s1221(pcurve1,kder,anext1+t1[0],&kleft1,sval1,&kstat); 40618 if (kstat < 0) goto error; 40619 40620 s1221(pcurve2,kder,anext2+t1[1],&kleft2,sval2,&kstat); 40621 if (kstat < 0) goto error; 40622 40623 40624 /* Compute the distanse vector and value and the new step. */ 40625 40626 s1770_s9dir(&tdist,tdn,tdn+1,sdiff,sval1,sval2,kdim); 40627 40628 /* Check if the direction of the step have change. */ 40629 40630 kdir = (s6scpr(td,tdn,2) >= DZERO); /* 0 if changed. */ 40631 40632 /* Ordinary converging. */ 40633 40634 if (tdist < tprev*(double)0.9 || kdir) 40635 { 40636 anext1 += t1[0]; 40637 anext2 += t1[1]; 40638 40639 td[0] = tdn[0]; 40640 td[1] = tdn[1]; 40641 40642 /* Correct if we are not inside the parameter intervall. */ 40643 40644 t1[0] = td[0]; 40645 t1[1] = td[1]; 40646 s1770_s9corr(t1,anext1,anext2,astart1,aend1,astart2,aend2); 40647 40648 if ( (fabs(t1[0]/tdelta1) <= REL_COMP_RES) && 40649 (fabs(t1[1]/tdelta2) <= REL_COMP_RES) ) break; 40650 40651 tprev = tdist; 40652 } 40653 40654 /* Not converging, corrigate and try again. */ 40655 40656 else 40657 { 40658 t1[0] /= (double)2; 40659 t1[1] /= (double)2; 40660 /* knbit--; */ 40661 } 40662 } 40663 40664 /* Iteration stopped, test if point founds found is within resolution */ 40665 40666 if (tdist <= aepsge) 40667 *jstat = 1; 40668 else 40669 *jstat = 2; 40670 40671 *cpos1 = anext1; 40672 *cpos2 = anext2; 40673 40674 /* Iteration completed. */ 40675 40676 40677 goto out; 40678 40679 /* Error in allocation */ 40680 40681 err101: *jstat = -101; 40682 s6err("s1770",*jstat,kpos); 40683 goto out; 40684 40685 /* Error in input. Conflicting dimensions. */ 40686 40687 err106: *jstat = -106; 40688 s6err("s1770",*jstat,kpos); 40689 goto out; 40690 40691 /* Error in lower level routine. */ 40692 40693 error : *jstat = kstat; 40694 s6err("s1770",*jstat,kpos); 40695 goto out; 40696 40697 out: if (sval1 != SISL_NULL) freearray(sval1); 40698 } 40699 40700 //=========================================================================== 40701 void s1220(double *et,int ik,int in,int *ileft, 40702 double ax,int ider,double ebder[],int *jstat) 40703 //=========================================================================== 40704 { 40705 int kstat=0; /* Local status variable. */ 40706 int kpos=0; /* The position of the error. */ 40707 int kdeg; /* Convenience variable which is set to ik-1. */ 40708 int kleft; /* Local version of ileft in order to avoid 40709 the pointer. */ 40710 int ki,kj,ks; /* Control variables in for loops and for stepping 40711 through arrays. */ 40712 int ki1,ki2,kjh; /* Control variables in for loops and for stepping 40713 through arrays. */ 40714 int kder; /* Local version of ider. All derivatives of order 40715 higher than ik-1 are zero so 40716 kder=min(ik-1,ider). */ 40717 double td1,td2; /* These variables are used to store the inverse of 40718 the number that divides B(i,k-1) and B(i+1,k-1) 40719 in (2) above. */ 40720 double tw1,tw2; /* These variabels are used to store the factors 40721 multiplying B(i,k-1) and B(i+1,k-1) in (1) 40722 above. */ 40723 double ts1,ts2; /* These variables are similar to td1 and td2 except 40724 that they will also contain the appropriate 40725 integer factor stemming from (2). */ 40726 double tt,tth; /* Auxiliary variables used to avoid unnecessary 40727 look ups in the knot vector. */ 40728 /* Check the input. */ 40729 40730 if (ider < 0) goto err178; 40731 40732 /* Find the right value of ileft and check input. */ 40733 40734 s1219(et,ik,in,ileft,ax,&kstat); 40735 40736 if (kstat < 0) goto error; 40737 40738 /* Initialize. */ 40739 40740 kleft = *ileft; 40741 kdeg = ik - 1; 40742 kder = min(ik-1,ider); 40743 40744 /* The fact that kder can be less than ider causes some problems. 40745 If kder < ider we know that ebder in the end should be a (kder+1)xik 40746 matrix augmented with ider-kder rows of zeros at the bottom. 40747 Since we store the matrix column by column, care must be taken to 40748 access the entries correctly. 40749 In the comments below ebder will usually be considered to be a 40750 (kder+1)xik matrix. 40751 ki2 is set to point to the last element of ebder (the lower right entry 40752 of the matrix, cf. above), and this element is set to one 40753 (this is the lower right corner of the (kder+1)*ik part of ebder). */ 40754 40755 ki2 = (ik-1)*(ider+1) + kder; 40756 ebder[ki2] = (double)1.0; 40757 40758 if (ik == 1) 40759 { 40760 /* VSK. Constant. Task is done. */ 40761 40762 *jstat = 0; 40763 goto out; 40764 } 40765 40766 /* Get ready for the main iteration loop where (1) and/or (2) are applied 40767 each time. In these iterations ki1 will run through the entries of ebder 40768 to be computed, starting at the upper left corner and running down the 40769 rows. 40770 ki2 will follow ki1 but be one row ahead of ki1 to take care of the second 40771 term in (1) and (2). 40772 Note that when accessing the entries of ebder the convention is 40773 used that the pointer to the entry has to be incremented first. 40774 ki1 is therefore initialized to point to the element before the first 40775 element to be computed in the first iteration (the second but 40776 last diagonal element of ebder). 40777 If (ider == ik-1) then we first have to copy up the last row and 40778 initialize ki1 to point to the entry above the second but last diagonal 40779 element of ebder. */ 40780 40781 ki1 = ki2 - ider - 2; 40782 if (kder == kdeg) 40783 { 40784 ebder[ki2-1] = (double)1.0; 40785 ki1 -= 1; 40786 } 40787 40788 /* ki2 should be one row ahead of ki1 and each row has ider+1 entries. */ 40789 40790 ki2 = ki1 + ider + 1; 40791 40792 /* Iterate and apply (1) and/or (2) each time. ks counts the degree of the 40793 B-splines whose values and derivaties are to be computed in this 40794 iteration. */ 40795 40796 for(ks=1; ks<ik; ks++) 40797 { 40798 40799 /* In (1) and (2) the denominators that divide B(i,k-1) and B(i+1,k-1) 40800 are on the form (t(i+k-1)-t(i)). Below kj is used as the (i) index 40801 and kjh as the (i+k-1) index. It is the alternative form (3) of 40802 (1) that is used below and tw2 is used as 1-w(i+1) and tw1 as 40803 w(i). 40804 For the first nonzero B-spline of degree ks, the first term in 40805 (1) and (2) is zero. 40806 kj is initialized to point to the first knot that gives a contribution 40807 during this iteration and kjh to point to `t(kj+ks)=t(kleft+1)'. 40808 If (t(kjh)-t(kj)) <= 0.0 there must be an error in the knot vector. */ 40809 40810 kj = kleft - ks + 1; 40811 kjh = kleft + 1; 40812 tt = et[kjh++]; 40813 tth = tt - et[kj]; 40814 if (tth <= (double)0.0) goto err112; 40815 td2 = (double)1.0/tth; 40816 tw2 = (tt-ax)*td2; 40817 40818 ebder[++ki1] = tw2*ebder[++ki2]; 40819 40820 /* Check to see if there is either copying or differentiation to do. */ 40821 40822 if (ks >= kdeg-kder && kder > 0) 40823 { 40824 /* Copy the first element of the row up to the previous 40825 unless it is the last iteration. */ 40826 40827 if (ks < kdeg) 40828 ebder[ki1-1] = ebder[ki1]; 40829 40830 /* Apply (2) to the rest of this column. Remember that this 40831 is the first nonzero column of ebder so the first term in (2) 40832 is zero. */ 40833 40834 ts2 = ks*td2; 40835 for (ki=0; ki<ks-kdeg+kder; ki++) 40836 ebder[++ki1] = -ts2*ebder[++ki2]; 40837 40838 /* Step to the top of the next column (the last time ebder 40839 is full and there is no stepping to do (unless kder <ider). */ 40840 40841 ki1 += ider - kder + kdeg - ks; 40842 ki2 = ki1 + ider + 1; 40843 } 40844 else 40845 { 40846 40847 /* If there was no copying or differentiation to be done 40848 we just step to the top of the next column. This step is zero 40849 if there are no derivatives to be computed. */ 40850 40851 ki1 += ider; 40852 ki2 += ider; 40853 } 40854 40855 /* Loop through the ks-1 middle columns of ebder. */ 40856 40857 for (kj=kleft-ks+2; kj<=kleft; kj++) 40858 { 40859 40860 /* Compute the denominators and weights (w(i+1)) to be used. 40861 See the comments above for more details. */ 40862 40863 tt = et[kjh++]; 40864 tth = tt - et[kj]; 40865 if (tth <= (double)0.0) goto err112; 40866 td1 = td2; td2 = (double)1.0/tth; 40867 tw1 = (double)1.0 - tw2; tw2 = (tt-ax)*td2; 40868 40869 ki1 += 1; 40870 ebder[ki1] = tw1*ebder[ki1] + tw2*ebder[++ki2]; 40871 40872 /* Check if there is copying and differentiation to be done. */ 40873 40874 if (ks >= kdeg-kder && kder > 0) 40875 { 40876 40877 /* Copy unless it is the last iteration. */ 40878 40879 if (ks < kdeg) 40880 ebder[ki1-1] = ebder[ki1]; 40881 40882 /* Do the differentiation. */ 40883 40884 ts1 = ts2; ts2 = ks*td2; 40885 for (ki=0; ki<ks-kdeg+kder; ki++) 40886 { 40887 ki1 += 1; 40888 ebder[ki1] = ts1*ebder[ki1] - ts2*ebder[++ki2]; 40889 } 40890 40891 /* Jump to the next column. */ 40892 40893 ki1 += ider - kder + kdeg - ks; 40894 ki2 = ki1 + ider + 1; 40895 } 40896 else 40897 { 40898 40899 /* Jump to the next column. */ 40900 40901 ki1 += ider; 40902 ki2 += ider; 40903 } 40904 } 40905 40906 /* Compute the last column of ebder. Remember that now the last term 40907 in (1) and (2) is zero, so there is no new td2 or tw2 to compute. */ 40908 40909 td1 = td2; 40910 tw1 = (double)1.0 - tw2; 40911 40912 ki1 += 1; 40913 ebder[ki1] = tw1*ebder[ki1]; 40914 40915 /* Check if there is copying or differentiation to do. */ 40916 40917 if (ks >= kdeg-kder && kder > 0) 40918 { 40919 40920 /* Copy. */ 40921 40922 if (ks < kdeg) 40923 ebder[ki1-1] = ebder[ki1]; 40924 40925 /* Differentiate. */ 40926 40927 ts1 = ts2; 40928 for (ki=0; ki<ks-kdeg+kder; ki++) 40929 { 40930 ki1 += 1; 40931 ebder[ki1] = ts1*ebder[ki1]; 40932 } 40933 40934 /* Move ki1 back to the first nonzero element of the last column. 40935 Each column now has ks-kdeg+kder+2 nonzero elements. */ 40936 40937 ki1 -= ks - kdeg + kder + 1; 40938 } 40939 40940 /* Move ki1 from the first element of the last column to the element 40941 prior to the first nonzero element in the first column. 40942 ki2 is as usual one column ahead of ki1. */ 40943 40944 ki1 -= (ks+1)*(ider+1) + 1; 40945 ki2 = ki1 + ider + 1; 40946 } 40947 40948 /* Set the remaining derivatives to zero. */ 40949 40950 for (ki=kder+1; ki<=ider; ki++) 40951 { 40952 ki1 = ki; 40953 for (kj=0; kj<ik; kj++) 40954 { 40955 ebder[ki1] = (double)0.0; 40956 ki1 += ider + 1; 40957 } 40958 } 40959 40960 /* Successful computations. */ 40961 40962 *jstat = 0; 40963 goto out; 40964 40965 40966 /* Error in knot vector. 40967 (The first or last interval of the knot vector is empty 40968 or it is decreasing or has to high multiplicity.) */ 40969 err112: *jstat = -112; 40970 s6err("s1220",*jstat,kpos); 40971 goto out; 40972 40973 /* Illegal derivative requested. */ 40974 err178: *jstat = -178; 40975 s6err("s1220",*jstat,kpos); 40976 goto out; 40977 40978 /* Error in lower level routine. */ 40979 40980 error: *jstat = kstat; 40981 s6err("s1220",*jstat,kpos); 40982 goto out; 40983 40984 out: return; 40985 } 40986 40987 //=========================================================================== 40988 void s1219(double *et,int ik,int in,int *ileft,double ax,int *jstat) 40989 //=========================================================================== 40990 { 40991 int kpos=0; /* The position of the error. */ 40992 int kleft; /* Local version of ileft to avoid the pointer. */ 40993 40994 /* Check the input. */ 40995 40996 if (ik < 1) goto err110; 40997 40998 if (in < ik) goto err111; 40999 41000 if (et[ik-1] == et[ik] || et[in-1] == et[in]) goto err112; 41001 41002 /* Make sure that kleft is in the legal range. */ 41003 41004 kleft = min(max(ik-1,*ileft),in-1); 41005 41006 /* Check if the current value of kleft is acceptable. */ 41007 41008 if (et[kleft] <= ax && ax < et[kleft+1]) ; 41009 41010 /* Check if ax is outside (et[ik-1],et[in]). */ 41011 41012 else if (ax >= et[in-1]) 41013 kleft = in - 1; 41014 else if (ax <= et[ik-1]) 41015 kleft = ik - 1; 41016 41017 /* Check if it is sufficient to increase or decrease kleft by one. */ 41018 41019 else if (et[kleft+1] <= ax && ax < et[kleft+2]) 41020 kleft += 1; 41021 else if (kleft > 0 && et[kleft-1] <= ax && ax < et[kleft]) 41022 kleft -= 1; 41023 41024 /* Last resort - a binary search. */ 41025 else 41026 { 41027 41028 /* kmin and kmax gives the upper and lower limits on the possible values 41029 of kleft. */ 41030 41031 int kmin,kmax; 41032 41033 kmin = ik - 1; kmax = in - 1; 41034 kleft = (kmin+kmax)/2; 41035 41036 while (ax < et[kleft] || et[kleft+1] <= ax) 41037 { 41038 if (ax < et[kleft]) 41039 kmax = kleft; 41040 else 41041 kmin = kleft; 41042 41043 kleft = (kmin+kmax)/2; 41044 } 41045 } 41046 41047 *ileft = kleft; 41048 41049 /* Successful computations. */ 41050 41051 *jstat = 0; 41052 goto out; 41053 41054 /* Polynomial order less than 1. */ 41055 err110: *jstat = -110; 41056 s6err("s1219",*jstat,kpos); 41057 goto out; 41058 41059 /* Fewer B-splines than the order. */ 41060 err111: *jstat = -111; 41061 s6err("s1219",*jstat,kpos); 41062 goto out; 41063 41064 /* Error in knot vector. 41065 (The first or last interval of the knot vector is empty.) */ 41066 err112: *jstat = -112; 41067 s6err("s1219",*jstat,kpos); 41068 goto out; 41069 41070 out: return; 41071 } 41072 41073 //=========================================================================== 41074 void s6strider(double eder[],int idim,int ider,double gder[],int *jstat) 41075 //=========================================================================== 41076 { 41077 int kpos=0; /* Position of error. */ 41078 double w0; /* The denominator. */ 41079 int ki; /* Count through dimensions. */ 41080 int idu; /* Count through derivatives in u. */ 41081 int idv; /* Count through derivatives in v. */ 41082 int *binom=SISL_NULL; /* Array for binomial coefficients. */ 41083 int *binomu=SISL_NULL; /* Pointer to binomial coefficients in u. */ 41084 int *binomv=SISL_NULL; /* Pointer to binomial coefficients in v. */ 41085 double *sum1=SISL_NULL; /* Leibnitz expansion in u */ 41086 double *sum2=SISL_NULL; /* Leibnitz expansion in u and v. */ 41087 double sumdum1[4]; /* Fixed space for sum1. */ 41088 double sumdum2[4]; /* Fixed space for sum2. */ 41089 int idimp1; /* idim + 1. */ 41090 int iw; /* Pointer to a weight. */ 41091 int igder; /* Pointer to already calculated derivs. */ 41092 int i,iu,iv,j,k; /* Counters. */ 41093 int iderp1; /* ider + 1. */ 41094 int igrow; /* (ider+1) * idim. */ 41095 int iwrow; /* (ider+1) * idimp1. */ 41096 int iutemp,ivtemp; /* Used to find next weight in the sum. */ 41097 int tot,temp1; /* Temporary variables. */ 41098 int bidum[10]; /* Array for storing binomial coeffs. */ 41099 double temp; /* Temporary multiple. */ 41100 41101 if (ider<0) goto err178; 41102 if (idim<1) goto err102; 41103 41104 *jstat = 0; 41105 41106 /* Find denominator. */ 41107 41108 w0 = eder[idim]; 41109 if (DEQUAL(w0,DZERO)) w0 = (double)1.0; 41110 41111 /* If we're only asked for position, we'll do it 41112 now and exit for the sake of speed. */ 41113 41114 if(ider == 0) 41115 { 41116 for(ki=0; ki<idim; ki++) 41117 gder[ki] = eder[ki] / w0; 41118 41119 goto out; 41120 } 41121 41122 /* Set up some constants. */ 41123 41124 idimp1 = idim + 1; 41125 iderp1 = ider + 1; 41126 igrow = iderp1 * idim; 41127 iwrow = igrow + iderp1; /* = iderp1 * idimp1 */ 41128 41129 /* Set up binomial coefficients. 41130 Use new array only when ider > 3. */ 41131 41132 if (ider > 3) 41133 { 41134 binom = newarray((iderp1*(iderp1+1)) >> 1, INT); 41135 if(binom == SISL_NULL) goto err179; 41136 } 41137 else 41138 { 41139 binom = bidum; 41140 } 41141 41142 for(j=0,k=0; j<=ider; j++,k+=j) 41143 { 41144 /* Calculate the new row of binomial coefficients. */ 41145 41146 binom[k] = 1; 41147 41148 for(i=k+1; i<k+j; i++) 41149 { 41150 binom[i] = binom[i-j-1] + binom[i-j]; 41151 } 41152 41153 binom[k+j] = 1; 41154 } 41155 41156 /* Set up space for sum1 and sum2 if necessary. 41157 Use new arrays only when idim > 4. */ 41158 41159 if (idim > 4) 41160 { 41161 sum1 = newarray(idim, DOUBLE); 41162 if(sum1 == SISL_NULL) goto err179; 41163 sum2 = newarray(idim, DOUBLE); 41164 if(sum2 == SISL_NULL) goto err179; 41165 } 41166 else 41167 { 41168 sum1=sumdum1; 41169 sum2=sumdum2; 41170 } 41171 41172 /* Loop through derivatives in u and v. */ 41173 41174 for(idv=0,binomv=binom; idv<=ider; idv++,binomv+=idv) 41175 { 41176 for(idu=0,binomu=binom; idu<=ider-idv; idu++,binomu+=idu) 41177 { 41178 if(idu == 0 && idv == 0) 41179 { 41180 /* Position is a special case. */ 41181 41182 for(ki=0; ki<idim; ki++) 41183 gder[ki] = eder[ki] / w0; 41184 } 41185 else 41186 { 41187 /* Calculate indices in eder and gder. */ 41188 41189 tot = idu + idv; 41190 temp1 = ((tot * (tot+1)) >> 1) + idv; 41191 41192 j = temp1 * idim; 41193 k = j + temp1; 41194 41195 /* Calculating each coefficient of the (idu,idv)'th 41196 derivative of the rational surface (in gder). 41197 41198 This requires calculating the Liebnitz sum from 41199 the subarray of gder (0,..,idu, 0,...,idv) and 41200 the subarray of eder (0,..,idu, 0,...,idv). */ 41201 41202 /* Calculate the Leibnitz sum. */ 41203 41204 for(ki=0; ki<idim; ki++) 41205 sum2[ki] = (double)0.0; 41206 41207 for(iv=0; iv<=idv; iv++) 41208 { 41209 for(ki=0; ki<idim; ki++) 41210 sum1[ki] = (double)0.0; 41211 ivtemp = idv-iv; 41212 41213 for(iu=0; iu<=idu; iu++) 41214 { 41215 tot = iu + iv; 41216 temp1 = ((tot * (tot+1)) >> 1) + iv; 41217 41218 igder = temp1 * idim; 41219 iutemp = idu-iu; 41220 41221 tot = iutemp + ivtemp; 41222 temp1 = ((tot * (tot+1)) >> 1) + ivtemp; 41223 41224 iw = temp1 * idimp1 + idim; 41225 41226 /* Add the next Leibnitz term unless we 41227 have reached the last one (the unknown). */ 41228 41229 if(iu<idu || iv<idv) 41230 { 41231 /* If iu=0 or iu=idu, the u binomial 41232 coefficient is 1 so don't multiply. */ 41233 41234 if(iu>0 && iu<idu) 41235 { 41236 temp = (double)binomu[iu] * eder[iw]; 41237 for(ki=0; ki<idim; ki++,igder++) 41238 sum1[ki] += temp * gder[igder]; 41239 } 41240 else 41241 for(ki=0; ki<idim; ki++,igder++) 41242 sum1[ki] += eder[iw] * gder[igder]; 41243 } 41244 } 41245 41246 /* If iv=0 or iv=idv, the v binomial 41247 coefficient is 1 so don't multiply. */ 41248 41249 if(iv>0 && iv<idv) 41250 for(ki=0; ki<idim; ki++) 41251 sum2[ki] += (double)binomv[iv] * sum1[ki]; 41252 else 41253 for(ki=0; ki<idim; ki++) 41254 sum2[ki] += sum1[ki]; 41255 } 41256 for(ki=0; ki<idim; ki++,j++,k++) 41257 gder[j] = (eder[k] - sum2[ki]) / w0; 41258 } 41259 } 41260 } 41261 41262 /* Free arrays. */ 41263 41264 if (ider > 3 && binom != SISL_NULL) 41265 freearray(binom); 41266 41267 if (idim > 4) 41268 { 41269 if(sum1 != SISL_NULL) freearray(sum1); 41270 if(sum2 != SISL_NULL) freearray(sum2); 41271 } 41272 41273 /* Done. */ 41274 41275 goto out; 41276 41277 /* idim less than 1. */ 41278 41279 err102: 41280 *jstat = -102; 41281 s6err("s6strider",*jstat,kpos); 41282 goto out; 41283 41284 /* Derivative negative */ 41285 41286 err178: 41287 *jstat = -178; 41288 s6err("s6strider",*jstat,kpos); 41289 goto out; 41290 41291 /* Not enough memory */ 41292 41293 err179: 41294 *jstat = -179; 41295 s6err("s6strider",*jstat,kpos); 41296 goto out; 41297 41298 out: 41299 return; 41300 } 41301 41302 //=========================================================================== 41303 double s6length(double e1[],int idim,int *jstat) 41304 //=========================================================================== 41305 { 41306 register int ki; /* Running variable in loop */ 41307 register double tsum=DZERO; /* Dummy variables in summing loop */ 41308 41309 /* If the dimension is 1 the length of the vector is the same as the 41310 * absolute value of the number */ 41311 41312 if (idim == 1) 41313 tsum = fabs(e1[0]); 41314 else 41315 { 41316 for (ki=0;ki<idim;ki++) 41317 tsum += (e1[ki]*e1[ki]); 41318 41319 tsum = sqrt(tsum); 41320 } 41321 41322 if (DNEQUAL(tsum,DZERO)) 41323 goto mes01; 41324 41325 /* Length of vector is zero */ 41326 41327 *jstat = 0; 41328 goto out; 41329 41330 /* Length of vector different from zero */ 41331 41332 mes01: *jstat = 1; 41333 goto out; 41334 41335 out: return(tsum); 41336 } 41337 41338 //=========================================================================== 41339 double s6scpr(double e1[],double e2[],int idim) 41340 //=========================================================================== 41341 { 41342 register int ki; 41343 register double tsum=DZERO; 41344 41345 for (ki=0;ki<idim;ki++) 41346 tsum += e1[ki]*e2[ki]; 41347 41348 return(tsum); 41349 } 41350 41351 //=========================================================================== 41352 void s6err(const char *rut,int jstat,int ipos) 41353 //=========================================================================== 41354 { 41355 (void)fprintf(stderr,"\nError status : %d",jstat); 41356 (void)fprintf(stderr," Call from routine : %s",rut); 41357 (void)fprintf(stderr," Position : %d\n",ipos); 41358 } 41359 41360 //=========================================================================== 41361 SISLCurve *newCurve (int in, int ik, double *et, double *ecoef, 41362 int ikind, int idim, int icopy) 41363 //=========================================================================== 41364 { 41365 SISLCurve *qnew; /* Local pointer to new curve. */ 41366 int i, j, J, jj, k; /* loop variables */ 41367 int k1,k2; /* Superflous knots in the ends. */ 41368 int kdim; /* Dimension of space (also including potential 41369 homogenous coordinate */ 41370 double *st = SISL_NULL; /* Copy of knotvector. */ 41371 double *rcoef = SISL_NULL; /* Copy of vertices in rational case. */ 41372 double *scoef = SISL_NULL; /* Copy of vertices. */ 41373 41374 41375 /* Allocate space for curve. */ 41376 41377 if ((qnew = newarray (1, SISLCurve)) == SISL_NULL) 41378 goto err101; 41379 41380 if (ikind == 2 || ikind == 4) 41381 kdim = idim + 1; 41382 else 41383 kdim = idim; 41384 41385 /* Count superflous knots in the start. */ 41386 41387 for (k1=0; k1<in; k1++) 41388 if (et[ik-1] < et[ik+k1]) break; 41389 41390 /* Count superflous knots in the end. */ 41391 41392 for (k2=0; k2<in; k2++) 41393 if (et[in] > et[in-1-k2]) break; 41394 41395 /* Reduce knots and vertices according to k1 and k2. */ 41396 41397 if (k1 > 0) 41398 { 41399 memcopy(ecoef,ecoef+k1*kdim,(in-k1)*kdim,DOUBLE); 41400 memcopy(et,et+k1,in+ik-k1,DOUBLE); 41401 } 41402 in -= (k1+k2); 41403 41404 /* Check if the curve is still valid. Otherwise return zero. */ 41405 41406 if (in < ik) goto err101; 41407 41408 if (icopy == 1) 41409 { 41410 41411 /* Copy input arrays. First allocate space for new arrays. */ 41412 41413 if ((st = newarray (in +ik, DOUBLE)) == SISL_NULL || 41414 (scoef = newarray (in *kdim, DOUBLE)) == SISL_NULL) 41415 goto err101; 41416 41417 /* Copy contents of arrays. */ 41418 41419 memcopy (st, et, in +ik, double); 41420 memcopy (scoef, ecoef, in *kdim, double); 41421 } 41422 else 41423 { 41424 st = et; 41425 scoef = ecoef; 41426 } 41427 41428 /* Initialize new curve. */ 41429 41430 qnew->in = in; 41431 qnew->ik = ik; 41432 qnew->ikind = ikind; 41433 qnew->idim = idim; 41434 qnew->icopy = icopy; 41435 qnew->et = st; 41436 qnew->pdir = SISL_NULL; 41437 qnew->pbox = SISL_NULL; 41438 41439 if (ikind == 2 || ikind == 4) 41440 { 41441 /* Calculate the weighted control points if the object is rational */ 41442 rcoef = newarray (in *idim, DOUBLE); 41443 if (rcoef == SISL_NULL) 41444 goto err101; 41445 for (i = 0, j = 0, J = 0, k = idim; i < in; i++, k += kdim) 41446 { 41447 for (jj = 0; jj < idim; jj++, j++, J++) 41448 { 41449 rcoef[J] = scoef[j] / scoef[k]; 41450 } 41451 j++; 41452 } 41453 qnew->ecoef = rcoef; 41454 qnew->rcoef = scoef; 41455 } 41456 else 41457 { 41458 qnew->ecoef = scoef; 41459 qnew->rcoef = SISL_NULL; 41460 } 41461 41462 41463 /* UJK, 92.03.27 Default value must be set for cuopen */ 41464 qnew->cuopen = SISL_CRV_OPEN; 41465 41466 /* Task done. */ 41467 goto out; 41468 41469 /* Error in space allocation. Return zero. */ 41470 41471 err101:if (qnew != SISL_NULL) 41472 { freearray (qnew); qnew = SISL_NULL;} 41473 if (st != SISL_NULL) 41474 freearray (st); 41475 if (rcoef != SISL_NULL) 41476 freearray (rcoef); 41477 if (scoef != SISL_NULL) 41478 freearray (scoef); 41479 goto out; 41480 41481 out:return (qnew); 41482 } 41483 41484 //=========================================================================== 41485 SISLSurf * 41486 newSurf (int in1, int in2, int ik1, int ik2, double *et1, double *et2, 41487 double *ecoef, int ikind, int idim, int icopy) 41488 //=========================================================================== 41489 { 41490 SISLSurf *qnew; /* Local pointer to new surface. */ 41491 int i, j, J, jj, k; /* loop variables */ 41492 int k1, k2; /* Superfluous knots at the ends. */ 41493 int kdim; /* Dimension indicator. */ 41494 double *st1 = SISL_NULL, *st2 = SISL_NULL; /* Copy of knotvectors. */ 41495 double *rcoef = SISL_NULL; /* Copy of vertices in rational case. */ 41496 double *scoef = SISL_NULL; /* Copy of vertices. */ 41497 double *ucoef = SISL_NULL; /* Utility coefficient array. */ 41498 41499 /* Allocate space for surface. */ 41500 41501 if ((qnew = newarray (1, SISLSurf)) == SISL_NULL) 41502 goto err101; 41503 41504 if (ikind == 2 || ikind == 4) 41505 kdim = idim + 1; 41506 else 41507 kdim = idim; 41508 41509 /* Count superfluous knots at ends, first in u parameter directions. */ 41510 41511 if (ik1 == 0) 41512 { 41513 k1 = k2 = 0; 41514 } 41515 else 41516 { 41517 /* Count superfluous knots in the start. */ 41518 41519 for (k1 = 0; k1 < in1; k1++) 41520 if (et1[ik1 - 1] < et1[ik1 + k1]) break; 41521 41522 /* Count superfluous knots in the end. */ 41523 41524 for (k2 = 0; k2 < in1; k2++) 41525 if (et1[in1] > et1[in1 - 1 - k2]) break; 41526 } 41527 41528 /* Reduce knots and vertices according to k1 and k2. */ 41529 41530 if (k1 > 0 || k2 > 0) 41531 { 41532 ucoef = newarray(in1*in2*kdim, DOUBLE); 41533 s6chpar(ecoef, in1, in2, kdim, ucoef); 41534 } 41535 if (k1 > 0) 41536 { 41537 memcopy(ucoef, ucoef + k1*in2*kdim, (in1 - k1)*in2*kdim, DOUBLE); 41538 memcopy(et1, et1 + k1, in1 + ik1 - k1, DOUBLE); 41539 } 41540 in1 -= (k1 + k2); 41541 if (k1 > 0 || k2 > 0) 41542 { 41543 s6chpar(ucoef, in2, in1, kdim, ecoef); 41544 if (ucoef != SISL_NULL) freearray(ucoef); 41545 } 41546 41547 /* Count superfluous knots at ends in v parameter directions. */ 41548 41549 if (ik2 == 0) 41550 { 41551 k1 = k2 = 0; 41552 } 41553 else 41554 { 41555 /* Count superfluous knots in the start. */ 41556 41557 for (k1 = 0; k1 < in2; k1++) 41558 if (et2[ik2 - 1] < et2[ik2 + k1]) break; 41559 41560 /* Count superfluous knots in the end. */ 41561 41562 for (k2 = 0; k2 < in2; k2++) 41563 if (et2[in2] > et2[in2 - 1 - k2]) break; 41564 } 41565 /* Reduce knots and vertices according to k1 and k2. */ 41566 41567 if (k1 > 0) 41568 { 41569 memcopy(ecoef, ecoef + k1*in1*kdim, (in2 - k1)*in1*kdim, DOUBLE); 41570 memcopy(et2, et2 + k1, in2 + ik2 - k1, DOUBLE); 41571 } 41572 in2 -= (k1 + k2); 41573 41574 if (icopy == 1) 41575 { 41576 41577 /* Copy input arrays. First allocate space for new arrays. */ 41578 41579 st1 = newarray (in1 + ik1, DOUBLE); 41580 st2 = newarray (in2 + ik2, DOUBLE); 41581 scoef = newarray (in1 * in2 * kdim, DOUBLE); 41582 if (st1 == SISL_NULL || st2 == SISL_NULL || scoef == SISL_NULL) 41583 goto err101; 41584 41585 /* Copy contents of arrays. */ 41586 memcopy (st1, et1, in1 + ik1, double); 41587 memcopy (st2, et2, in2 + ik2, double); 41588 memcopy (scoef, ecoef, in1 * in2 * kdim, double); 41589 } 41590 else 41591 { 41592 st1 = et1; 41593 st2 = et2; 41594 scoef = ecoef; 41595 } 41596 41597 /* Initialize new surface. */ 41598 41599 qnew->in1 = in1; 41600 qnew->in2 = in2; 41601 qnew->ik1 = ik1; 41602 qnew->ik2 = ik2; 41603 qnew->ikind = ikind; 41604 qnew->idim = idim; 41605 qnew->icopy = icopy; 41606 qnew->et1 = st1; 41607 qnew->et2 = st2; 41608 qnew->pdir = SISL_NULL; 41609 qnew->pbox = SISL_NULL; 41610 41611 if (ikind == 2 || ikind == 4) 41612 { 41613 /* Calculate the weighted control points if the object is rational */ 41614 rcoef = newarray (in1 * in2 * idim, DOUBLE); 41615 if (rcoef == SISL_NULL) 41616 goto err101; 41617 for (i = 0, j = 0, J = 0, k = idim; i < in1 * in2; i++, k += kdim) 41618 { 41619 for (jj = 0; jj < idim; jj++, j++, J++) 41620 { 41621 rcoef[J] = scoef[j] / scoef[k]; 41622 } 41623 j++; 41624 } 41625 qnew->ecoef = rcoef; 41626 qnew->rcoef = scoef; 41627 } 41628 else 41629 { 41630 qnew->ecoef = scoef; 41631 qnew->rcoef = SISL_NULL; 41632 } 41633 41634 /* UJK, 92.05.05 Default value must be set for cuopen */ 41635 qnew->cuopen_1 = SISL_SURF_OPEN; 41636 qnew->cuopen_2 = SISL_SURF_OPEN; 41637 41638 /* Task done. */ 41639 41640 goto out; 41641 41642 /* Error in space allocation. Return zero. */ 41643 41644 err101:if (qnew != SISL_NULL) 41645 freearray (qnew); 41646 if (st1 != SISL_NULL) 41647 freearray (st1); 41648 if (st2 != SISL_NULL) 41649 freearray (st2); 41650 if (rcoef != SISL_NULL) 41651 freearray (rcoef); 41652 if (scoef != SISL_NULL) 41653 freearray (scoef); 41654 goto out; 41655 41656 out:return (qnew); 41657 } 41658 41659 //=========================================================================== 41660 void s6chpar(double ecoef1[],int in1,int in2,int idim,double ecoef2[]) 41661 //=========================================================================== 41662 { 41663 register int ki,kj,kk; /* Counters. */ 41664 41665 for (ki=0; ki<in1; ki++) 41666 for (kj=0; kj<in2; kj++) 41667 for (kk=0; kk<idim; kk++) 41668 ecoef2[(ki*in2+kj)*idim+kk] = ecoef1[(kj*in1+ki)*idim+kk]; 41669 } 41670 41671 //=========================================================================== 41672 SISLObject *newObject (int iobj) 41673 //=========================================================================== 41674 { 41675 SISLObject *qnew; /* Local pointer to new object. */ 41676 41677 qnew = newarray (1, SISLObject); 41678 if (qnew == SISL_NULL) 41679 goto out; 41680 41681 qnew->iobj = iobj; 41682 41683 qnew->p1 = SISL_NULL; 41684 qnew->c1 = SISL_NULL; 41685 qnew->s1 = SISL_NULL; 41686 qnew->o1 = SISL_NULL; 41687 qnew->edg[0] = SISL_NULL; 41688 qnew->edg[1] = SISL_NULL; 41689 qnew->edg[2] = SISL_NULL; 41690 qnew->edg[3] = SISL_NULL; 41691 qnew->psimple = SISL_NULL; 41692 41693 /* Task done. */ 41694 41695 out:return qnew; 41696 } 41697 41698 //=========================================================================== 41699 void freeCurve(SISLCurve *pcurve) 41700 //=========================================================================== 41701 { 41702 int ki; /* Counter. */ 41703 41704 41705 if ( pcurve->icopy != 0 ) 41706 { 41707 41708 /* Free arrays. */ 41709 41710 freearray(pcurve->et); 41711 freearray(pcurve->ecoef); 41712 if ( pcurve->rcoef != SISL_NULL ) freearray(pcurve->rcoef); 41713 } 41714 else if ( pcurve->ikind == 2 || pcurve->ikind == 4 ) 41715 { 41716 /* VSK, 940902. The array pcurve->ecoef is ALWAYS allocated in the 41717 constructor for rationals and must be free'ed. */ 41718 41719 freearray(pcurve->ecoef); 41720 } 41721 41722 if ( pcurve->pdir ) 41723 { 41724 41725 /* Free direction structure. */ 41726 41727 if ( pcurve->pdir->ecoef ) freearray(pcurve->pdir->ecoef); 41728 if ( pcurve->pdir->esmooth != SISL_NULL ) freearray(pcurve->pdir->esmooth); 41729 freearray(pcurve->pdir); 41730 } 41731 41732 if ( pcurve->pbox ) 41733 { 41734 41735 /* Free surrounded SISLbox structure. */ 41736 41737 if ( pcurve->pbox->emax ) freearray(pcurve->pbox->emax); 41738 if ( pcurve->pbox->emin ) freearray(pcurve->pbox->emin); 41739 41740 for ( ki=0; ki < 3; ki++ ) 41741 { 41742 if ( pcurve->pbox->e2max[ki] ) freearray(pcurve->pbox->e2max[ki]); 41743 if ( pcurve->pbox->e2min[ki] ) freearray(pcurve->pbox->e2min[ki]); 41744 } 41745 freearray(pcurve->pbox); 41746 } 41747 41748 /* Free instance of curve. */ 41749 41750 freearray(pcurve); 41751 41752 return; 41753 } 41754 41755 //=========================================================================== 41756 void freeSurf(SISLSurf *psurf) 41757 //=========================================================================== 41758 { 41759 int ki; /* Counter. */ 41760 41761 41762 if ( psurf->icopy != 0 ) 41763 { 41764 41765 /* Free arrays. */ 41766 41767 freearray(psurf->et1); 41768 freearray(psurf->et2); 41769 freearray(psurf->ecoef); 41770 if ( psurf->rcoef != SISL_NULL ) freearray(psurf->rcoef); 41771 } 41772 else if ( psurf->ikind == 2 || psurf->ikind == 4 ) 41773 { 41774 /* VSK, 940902. The array pcurve->ecoef is ALWAYS allocated in the 41775 constructor for rationals and must be free'ed. */ 41776 41777 freearray(psurf->ecoef); 41778 } 41779 41780 41781 if ( psurf->pdir ) 41782 { 41783 41784 /* Free direction structure. */ 41785 41786 if ( psurf->pdir->ecoef ) freearray(psurf->pdir->ecoef); 41787 if ( psurf->pdir->esmooth != SISL_NULL ) freearray(psurf->pdir->esmooth); 41788 freearray(psurf->pdir); 41789 } 41790 41791 if ( psurf->pbox ) 41792 { 41793 41794 /* Free surrounded SISLbox structure. */ 41795 41796 if ( psurf->pbox->emax ) freearray(psurf->pbox->emax); 41797 if ( psurf->pbox->emin ) freearray(psurf->pbox->emin); 41798 41799 for ( ki=0; ki < 3; ki++ ) 41800 { 41801 if ( psurf->pbox->e2max[ki] ) freearray(psurf->pbox->e2max[ki]); 41802 if ( psurf->pbox->e2min[ki] ) freearray(psurf->pbox->e2min[ki]); 41803 } 41804 freearray(psurf->pbox); 41805 } 41806 41807 /* Free instance of surface. */ 41808 41809 freearray(psurf); 41810 41811 return; 41812 } 41813 41814 //=========================================================================== 41815 void freeIntcrvlist(SISLIntcurve **viclist, int icrv) 41816 //=========================================================================== 41817 { 41818 /* 41819 * Local declarations 41820 * ------------------ 41821 */ 41822 41823 int ki; 41824 41825 /* 41826 * Free each SISLIntcurve from bottom of the list and u to the top. 41827 * ------------------------------------------------------------ 41828 */ 41829 41830 if (viclist) 41831 { 41832 for ( ki = icrv - 1; ki >= 0; ki --) 41833 { 41834 if (viclist[ki]) 41835 { 41836 freeIntcurve(viclist[ki]); 41837 viclist[ki] = SISL_NULL; 41838 } 41839 } 41840 freearray(viclist); 41841 viclist = SISL_NULL; 41842 } 41843 } 41844 41845 //=========================================================================== 41846 void freeIntcurve(SISLIntcurve *pintc) 41847 //=========================================================================== 41848 { 41849 /* Free whatever is allocated */ 41850 41851 if (pintc) 41852 { 41853 if (pintc->epar1) freearray(pintc->epar1); 41854 if (pintc->epar2) freearray(pintc->epar2); 41855 if (pintc->pgeom) freeCurve(pintc->pgeom); 41856 if (pintc->ppar1) freeCurve(pintc->ppar1); 41857 if (pintc->ppar2) freeCurve(pintc->ppar2); 41858 freearray(pintc); 41859 } 41860 return; 41861 } 41862 41863 //=========================================================================== 41864 void s1770_s9corr(double gdn[],double acoef1,double acoef2, 41865 double astart1,double aend1,double astart2,double aend2) 41866 //=========================================================================== 41867 { 41868 if (acoef1 + gdn[0] < astart1) 41869 gdn[0] = astart1 - acoef1; 41870 else if (acoef1 + gdn[0] > aend1) 41871 gdn[0] = aend1 - acoef1; 41872 41873 if (acoef2 + gdn[1] < astart2) 41874 gdn[1] = astart2 - acoef2; 41875 else if (acoef2 + gdn[1] > aend2) 41876 gdn[1] = aend2 - acoef2; 41877 } 41878 41879 //=========================================================================== 41880 void s1770_s9dir(double *cdist,double *cdiff1,double *cdiff2, 41881 double gdiff[],double eval1[],double eval2[],int idim) 41882 //=========================================================================== 41883 { 41884 int kstat; /* Local status variable. */ 41885 register double tdet; /* Determinant */ 41886 register double t1,t2,t3,t4,t5; /* Variables in equation system */ 41887 41888 /* Computing the different vector */ 41889 41890 s6diff(eval1,eval2,idim,gdiff); 41891 41892 /* Computing the length of the different vector. */ 41893 41894 *cdist = s6length(gdiff,idim,&kstat); 41895 41896 t1 = s6scpr(eval1+idim,eval1+idim,idim); 41897 t2 = s6scpr(eval1+idim,eval2+idim,idim); 41898 t3 = s6scpr(eval2+idim,eval2+idim,idim); 41899 t4 = s6scpr(gdiff,eval1+idim,idim); 41900 t5 = s6scpr(gdiff,eval2+idim,idim); 41901 41902 /* Computing the determinant. */ 41903 41904 tdet = t2*t2 - t1*t3; 41905 41906 if (DEQUAL(tdet,DZERO)) 41907 { 41908 *cdiff1 = DZERO; 41909 *cdiff2 = DZERO; 41910 } 41911 else 41912 { 41913 /* Using Cramer's rule to find the solution of the system. */ 41914 41915 *cdiff1 = (t4*t3 - t5*t2)/tdet; 41916 *cdiff2 = (t2*t4 - t1*t5)/tdet; 41917 } 41918 } 41919 41920 //=========================================================================== 41921 void s1314(SISLSurf *ps1,double *epoint,double *enorm,int idim,double aepsco, 41922 double aepsge,double amax,SISLIntcurve *pintcr,int icur, 41923 int igraph,int *jstat) 41924 //=========================================================================== 41925 { 41926 int kpos=0; /* Position of error */ 41927 int kdeg=1; /* The degree of the implicit equation of the plane */ 41928 int kstat; /* Local status variable */ 41929 double simpli[4]; /* Array containing the implicit description of plane */ 41930 double snorm[3]; /* Normalized version of normal vector */ 41931 41932 41933 41934 if (idim != 3) goto err104; 41935 41936 /* Normalize normal vector */ 41937 41938 (void)s6norm(enorm,idim,snorm,&kstat); 41939 41940 simpli[0] = snorm[0]; 41941 simpli[1] = snorm[1]; 41942 simpli[2] = snorm[2]; 41943 simpli[3] = -s6scpr(epoint,snorm,idim); 41944 41945 41946 /* Make intersection of implicit surface and B-spline surface */ 41947 41948 s1313(ps1,simpli,kdeg,aepsco,aepsge,amax,pintcr,icur,igraph,&kstat); 41949 if (kstat == -185) goto err185; 41950 if (kstat < 0) goto error; 41951 41952 *jstat = kstat; 41953 goto out; 41954 41955 /* Dimension not 3 */ 41956 41957 err104: 41958 *jstat = -104; 41959 s6err("s1314",*jstat,kpos); 41960 goto out; 41961 41962 /* Couldn't march */ 41963 41964 err185: 41965 *jstat = -185; 41966 goto out; 41967 41968 /* Error in lower level routine. */ 41969 41970 error: 41971 *jstat = kstat; 41972 s6err("s1314",*jstat,kpos); 41973 goto out; 41974 41975 out: 41976 return; 41977 } 41978 41979 //=========================================================================== 41980 void sh1857(SISLCurve *pc1,SISLCurve *pc2,double aepsco,double aepsge, 41981 int trackflag, int *jtrack, SISLTrack *** wtrack, 41982 int *jpt,double **gpar1,double **gpar2,int **pretop, 41983 int *jcrv,SISLIntcurve ***wcurve,int *jstat) 41984 //=========================================================================== 41985 { 41986 double *nullp = SISL_NULL; 41987 int kstat = 0; /* Local status variable. */ 41988 int kpos = 0; /* Position of error. */ 41989 SISLObject *qo1 = SISL_NULL; /* Object containing first curve in 41990 the intersection. */ 41991 SISLObject *qo2 = SISL_NULL; /* Object containing second curve in 41992 the intersection. */ 41993 SISLIntdat *qintdat = SISL_NULL; /* Structure holding the intersection data. */ 41994 int ksurf=0; /* Dummy number of Intsurfs. */ 41995 SISLIntsurf **wsurf=SISL_NULL; /* Dummy array of Intsurfs. */ 41996 int kdeg=0; 41997 41998 *jpt = 0; 41999 *jcrv = 0; 42000 *jtrack = 0; 42001 42002 /* 42003 * Check dimensions. 42004 * ----------------- 42005 */ 42006 42007 if (pc1 -> idim != pc2 -> idim) goto err106; 42008 42009 /* 42010 * Create objects and connect curves to the objects. 42011 * ------------------------------------------------- 42012 */ 42013 42014 if ((qo1 = newObject(SISLCURVE)) == SISL_NULL) goto err101; 42015 qo1 -> c1 = pc1; 42016 qo1 -> o1 = qo1; 42017 42018 if ((qo2 = newObject(SISLCURVE)) == SISL_NULL) goto err101; 42019 qo2 -> c1 = pc2; 42020 qo2 -> o1 = qo2; 42021 42022 /* 42023 * Find intersections. 42024 * ------------------- 42025 */ 42026 42027 sh1761(qo1,qo2,aepsge,&qintdat,&kstat); 42028 if (kstat < 0) goto error; 42029 42030 /* Join periodic curves */ 42031 int_join_per( &qintdat,qo1,qo2,nullp,kdeg=0,aepsge,&kstat); 42032 if (kstat < 0) 42033 goto error; 42034 42035 /* Create tracks */ 42036 if (trackflag && qintdat) 42037 { 42038 make_tracks (qo1, qo2, 0, nullp, 42039 qintdat->ilist, qintdat->vlist, 42040 jtrack, wtrack, aepsge, &kstat); 42041 if (kstat < 0) 42042 goto error; 42043 } 42044 42045 /* 42046 * Express intersections on output format. 42047 * --------------------------------------- 42048 */ 42049 42050 if (qintdat)/* Only if there were intersections found */ 42051 { 42052 hp_s1880(qo1, qo2, kdeg, 42053 1,1,qintdat,jpt,gpar1,gpar2,pretop,jcrv,wcurve,&ksurf,&wsurf,&kstat); 42054 if (kstat < 0) goto error; 42055 } 42056 42057 /* 42058 * Intersections found. 42059 * -------------------- 42060 */ 42061 42062 *jstat = 0; 42063 goto out; 42064 42065 /* 42066 * Error in space allocation. 42067 * -------------------------- 42068 */ 42069 42070 err101: *jstat = -101; 42071 s6err("sh1857",*jstat,kpos); 42072 goto out; 42073 42074 /* Dimensions conflicting. */ 42075 42076 err106: *jstat = -106; 42077 s6err("sh1857",*jstat,kpos); 42078 goto out; 42079 42080 /* Error in lower level routine. */ 42081 42082 error : *jstat = kstat; 42083 s6err("sh1857",*jstat,kpos); 42084 goto out; 42085 42086 out: 42087 42088 /* 42089 * Free allocated space. 42090 * --------------------- 42091 */ 42092 42093 if (qo1) 42094 { 42095 qo1 -> c1 = SISL_NULL; freeObject(qo1); 42096 } 42097 if (qo2) 42098 { 42099 qo2 -> c1 = SISL_NULL; freeObject(qo2); 42100 } 42101 if (qintdat) freeIntdat(qintdat); 42102 42103 /* 42104 * Exit sh1857. 42105 * ----------- 42106 */ 42107 42108 return; 42109 } 42110 42111 //=========================================================================== 42112 void 42113 s1871(SISLCurve *pc1, double *pt1, int idim, double aepsge, 42114 int *jpt,double **gpar1,int *jcrv,SISLIntcurve ***wcurve,int *jstat) 42115 //=========================================================================== 42116 42117 /* 42118 ********************************************************************* 42119 * 42120 ********************************************************************* 42121 * 42122 * PURPOSE : Find all intersections between a B-spline curve 42123 * and a point. 42124 * 42125 * 42126 * 42127 * INPUT : pc1 - Pointer to the curve. 42128 * pt1 - coordinates of the point. 42129 * idim - number of coordinates in pt1. 42130 * aepsge - Geometry resolution. 42131 * 42132 * 42133 * 42134 * OUTPUT : jpt - Number of single intersection points. 42135 * gpar1 - Array containing the parameter values of the 42136 * single intersection points in the parameter 42137 * interval of the curve. The points lie 42138 * continuous. Intersection curves are stored in wcurve. 42139 * jcrv - Number of intersection curves. 42140 * wcurve - Array containing descriptions of the intersection 42141 * curves. The curves are only described by points 42142 * in the parameter plane. The curve-pointers points 42143 * to nothing. (See description of Intcurve 42144 * in intcurve.dcl). 42145 * If the curves given as input are degnenerate an 42146 * intersection point can be returned as an intersection 42147 * curve. Use s1327 to decide if an intersection curve 42148 * is a point on one of the curves. 42149 * jstat - status messages 42150 * > 0 : warning 42151 * = 0 : ok 42152 * < 0 : error 42153 * 42154 * 42155 * 42156 ********************************************************************* 42157 */ 42158 { 42159 int kstat = 0; /* Local status variable. */ 42160 int kpos = 0; /* Position of error. */ 42161 int trackflag = 0; 42162 int jtrack; 42163 int *pretop=SISL_NULL; 42164 SISLTrack **wtrack=SISL_NULL; 42165 double aepsco = REL_COMP_RES; 42166 42167 sh1871(pc1, pt1, idim, aepsco, aepsge, trackflag, &jtrack, &wtrack, 42168 jpt, gpar1, &pretop, jcrv, wcurve, &kstat); 42169 if(kstat < 0) goto error; 42170 42171 if(pretop != SISL_NULL) freearray(pretop); 42172 42173 /* 42174 * Intersections found. 42175 * -------------------- 42176 */ 42177 42178 *jstat = kstat; 42179 goto out; 42180 42181 /* Error in lower level routine. */ 42182 42183 error : 42184 *jstat = kstat; 42185 s6err("s1871",*jstat,kpos); 42186 goto out; 42187 42188 out: 42189 return; 42190 } 42191 42192 //=========================================================================== 42193 void 42194 sh1871(SISLCurve *pc1, double *pt1, int idim, double aepsco, double aepsge, 42195 int trackflag, int *jtrack, SISLTrack *** wtrack, 42196 int *jpt,double **gpar1,int **pretop,int *jcrv,SISLIntcurve ***wcurve,int *jstat) 42197 //=========================================================================== 42198 42199 /* 42200 ********************************************************************* 42201 * 42202 ********************************************************************* 42203 * 42204 * PURPOSE : Find all intersections between a B-spline curve 42205 * and a point. 42206 * 42207 * 42208 * 42209 * INPUT : pc1 - Pointer to the curve. 42210 * pt1 - coordinates of the point. 42211 * idim - number of coordinates in pt1. 42212 * aepsco - Computational resolution. 42213 * aepsge - Geometry resolution. 42214 * trackflag - For future use. Should now be 0. 42215 * 42216 * 42217 * 42218 * OUTPUT : jtrack - Number of tracks created 42219 * wtrack - Array of pointers to tracks 42220 * jpt - Number of single intersection points. 42221 * gpar1 - Array containing the parameter values of the 42222 * single intersection points in the parameter 42223 * interval of the curve. The points lie 42224 * continuous. Intersection curves are stored in wcurve. 42225 * pretop - Topology info. for single intersection points. 42226 * jcrv - Number of intersection curves. 42227 * wcurve - Array containing descriptions of the intersection 42228 * curves. The curves are only described by points 42229 * in the parameter plane. The curve-pointers points 42230 * to nothing. (See description of Intcurve 42231 * in intcurve.dcl). 42232 * If the curves given as input are degnenerate an 42233 * intersection point can be returned as an intersection 42234 * curve. Use s1327 to decide if an intersection curve 42235 * is a point on one of the curves. 42236 * jstat - status messages 42237 * > 0 : warning 42238 * = 0 : ok 42239 * < 0 : error 42240 * 42241 * 42242 ********************************************************************* 42243 */ 42244 { 42245 double *nullp = SISL_NULL; 42246 int kstat = 0; /* Local status variable. */ 42247 int kpos = 0; /* Position of error. */ 42248 SISLObject *qo1 = SISL_NULL; /* Object containing the curve in 42249 the intersection. */ 42250 SISLObject *qo2 = SISL_NULL; /* Object containing the point in 42251 the intersection.*/ 42252 SISLPoint *pp1 = SISL_NULL; /* Point object containing the point */ 42253 SISLIntdat *qintdat = SISL_NULL; /* Structure holding the intersection data. */ 42254 int ksurf=0; /* Dummy number of Intsurfs. */ 42255 SISLIntsurf **wsurf=SISL_NULL; /* Dummy array of Intsurfs. */ 42256 int kdeg=0; 42257 42258 /* 42259 * Check dimensions. 42260 * ----------------- 42261 */ 42262 42263 *jpt = 0; 42264 *jcrv = 0; 42265 *jtrack = 0; 42266 42267 if (pc1 -> idim != idim) goto err106; 42268 42269 /* 42270 * Create objects and connect curve/point to the objects. 42271 * -------------------------------------------------------- 42272 */ 42273 42274 if ((qo1 = newObject(SISLCURVE)) == SISL_NULL) goto err101; 42275 qo1 -> c1 = pc1; 42276 qo1 -> o1 = qo1; 42277 42278 if ((pp1 = newPoint(pt1,idim, 0)) == SISL_NULL) goto err101; 42279 42280 if ((qo2 = newObject(SISLPOINT)) == SISL_NULL) goto err101; 42281 qo2 -> p1 = pp1; 42282 qo2 -> o1 = qo2; 42283 42284 /* 42285 * Find intersections. 42286 * ------------------- 42287 */ 42288 42289 sh1761(qo1,qo2,aepsge,&qintdat,&kstat); 42290 if (kstat < 0) goto error; 42291 42292 /* Represent degenerated intersection curves as one point. */ 42293 42294 sh6degen(qo1,qo2,&qintdat,aepsge,&kstat); 42295 if (kstat < 0) goto error; 42296 42297 /* Join periodic curves */ 42298 /* int_join_per( &qintdat,qo1,qo2,nullp,kdeg=0,aepsge,&kstat); */ 42299 /* if (kstat < 0) */ 42300 /* goto error; */ 42301 42302 /* Create tracks */ 42303 if (trackflag && qintdat) 42304 { 42305 make_tracks (qo1, qo2, kdeg=0, nullp, 42306 qintdat->ilist, qintdat->vlist, 42307 jtrack, wtrack, aepsge, &kstat); 42308 if (kstat < 0) 42309 goto error; 42310 42311 } 42312 42313 /* 42314 * Express intersections on output format. 42315 * --------------------------------------- 42316 */ 42317 42318 if (qintdat)/* Only if there were intersections found */ 42319 { 42320 hp_s1880(qo1, qo2, 0, 42321 1,0,qintdat,jpt,gpar1,&nullp,pretop,jcrv,wcurve,&ksurf,&wsurf,&kstat); 42322 if (kstat < 0) goto error; 42323 } 42324 42325 /* 42326 * Intersections found. 42327 * -------------------- 42328 */ 42329 42330 *jstat = 0; 42331 goto out; 42332 42333 /* 42334 * Error in space allocation. 42335 * -------------------------- 42336 */ 42337 42338 err101: *jstat = -101; 42339 s6err("sh1871",*jstat,kpos); 42340 goto out; 42341 42342 /* Dimensions conflicting. */ 42343 42344 err106: *jstat = -106; 42345 s6err("sh1871",*jstat,kpos); 42346 goto out; 42347 42348 /* Error in lower level routine. */ 42349 42350 error : *jstat = kstat; 42351 s6err("sh1871",*jstat,kpos); 42352 goto out; 42353 42354 out: 42355 42356 /* 42357 * Free allocated space. 42358 * --------------------- 42359 */ 42360 42361 if (qo1) 42362 { 42363 qo1 -> c1 = SISL_NULL; freeObject(qo1); 42364 } 42365 if (qo2) freeObject(qo2); 42366 42367 if (qintdat) freeIntdat(qintdat); 42368 42369 /* 42370 * Exit sh1871. 42371 * ----------- 42372 */ 42373 42374 return; 42375 } 42376 42377 42378 //=========================================================================== 42379 void s1310(SISLSurf *psurf1,SISLSurf *psurf2,SISLIntcurve *pinter, 42380 double aepsge,double amax,int icur,int igraph,int *jstat) 42381 //=========================================================================== 42382 { 42383 int ki,kj,kl; /* Control variables in for loops */ 42384 int kcont; /* Stop condition for loop */ 42385 int kk,kn; /* Dummy variables */ 42386 int kstpch; /* Status of iteration step */ 42387 int kpoint; /* Number of points in guide curve */ 42388 int kpar1; /* Number of parameter direction in 1st. obj */ 42389 int kpar2; /* Number of parameter direction in 2nd. obj */ 42390 int kpar; /* Indicater tellin if s1359 shall make 42391 parametrization or use parametrization 42392 in spar */ 42393 int ktype; /* Type of intersection curve */ 42394 int klfu=0; /* Pointers into knot vectors */ 42395 int klfv=0; /* Pointers into knot vectors */ 42396 int klfs=0; /* Pointers into knot vectors */ 42397 int klft=0; /* Pointers into knot vectors */ 42398 int kder = 2; /* Calculate up to second derivatives */ 42399 int kdim = 3; /* The dimension of the space we work in */ 42400 int kfirst = 0; /* Indicator telling if first guide point 42401 degenerate */ 42402 int klast = 0; /* Indicator telling if last guide point 42403 degenerate */ 42404 int kpos = 0; /* Position of error */ 42405 int kstat,kstat1; /* Status variable returned form routine */ 42406 int kmaxinf=0; /* Number of entries object that can be stored 42407 in s3dinf, sp1inf, sp2inf */ 42408 int knbinf=0; /* Number of entries stored so far on s3dinf, 42409 sp1inf and sp2inf */ 42410 int kstart; /* Start point for iteration among guide pnts*/ 42411 int kguide; /* Current guide point */ 42412 int kdir; /* March direction */ 42413 int kgdir; /* Direction we march guide point vector */ 42414 int krem,krem1,krem2; /* REmember status of boundary crossing */ 42415 int kbound; /* Whci boundary is crossed */ 42416 int koutside_resolution; /* Flag telling if current seg. outside res. */ 42417 int kdiv=0; /* Flag telling if iteration diverged */ 42418 double tlnorm=DZERO; /* Length of normal vector */ 42419 double tltan1=DZERO; /* Length of tangents */ 42420 double tltan2=DZERO; /* Length of tangents */ 42421 double tang1,tang2; /* Angles */ 42422 int knb1=0; /* Remember number of points after marching 42423 in first marching direction */ 42424 int kgd1=0; /* Remeber last guide point used in first 42425 marching direction */ 42426 double *scorpnt=SISL_NULL; /* Corrected marching points */ 42427 double *scorpr1=SISL_NULL; /* Corrected marching parameter values in ps1*/ 42428 double *scorpr2=SISL_NULL; /* Corrected marching parameter values in ps2*/ 42429 double smidd[6]; /* Description of midpoint and tangent of 42430 current Bezier segment */ 42431 double tcurstep; /* Current step length */ 42432 double tdist; /* Error at middle of current Bezier segement*/ 42433 double tang; /* Angle error at midpoint Bezier segement */ 42434 double tnew; /* Candidate for new step length */ 42435 double tfak; /* How much is the step length to be reduced */ 42436 double *start; /* Pointer to start of current segment */ 42437 double *st; /* Pointer to knot vector */ 42438 double tstep; /* Iteration step length */ 42439 double tmax; /* Local maximal step length */ 42440 double tstartstp; /* Start step length */ 42441 double trad; /* Radius of curvature */ 42442 double spar1[2]; /* Parameter pair of current point surface 1 */ 42443 double spar2[2]; /* Parameter pair of current point surface 2 */ 42444 double sparmid1[2]; /* Parameter values at middle of Bezier segm */ 42445 double sparmid2[2]; /* Parameter values at middle of Bezier segm */ 42446 double sipar1[2]; /* Parameter pair iteration point surface 1 */ 42447 double sipar2[2]; /* Parameter pair iteration point surface 2 */ 42448 double simiddpnt[10]; /* Middle point and tangent of segment */ 42449 double simiddpar1[7]; /* Parameter value at middle point of segment*/ 42450 double simiddpar2[7]; /* Parameter value at middle point of segment*/ 42451 double startg[3]; /* Tangent of start point of iteration */ 42452 double *sgpar1=SISL_NULL; /* Parameter pairs of guide point in surf 1 */ 42453 double *sgpar2=SISL_NULL; /* Parameter pairs of guide point in surf 2 */ 42454 double *sgpara=SISL_NULL; /* Parameter pairs of guide point in surf 1 */ 42455 double *sgparb=SISL_NULL; /* Parameter pairs of guide point in surf 2 */ 42456 double *sgd1 = SISL_NULL; /* 0-2 derivative of guide point + normal 42457 of first object */ 42458 double *sgd2 = SISL_NULL; /* 0-2 derivative of guide point + normal 42459 of second object */ 42460 double spnt1[21]; /* Info on current point in first surface */ 42461 double spnt2[21]; /* Info on current point in second surface */ 42462 double sipnt1[21]; /* Info on iteration point in first surface */ 42463 double sipnt2[21]; /* Info on iteration point in second surface */ 42464 /* For spnt1, spnt2, sipnt1, sipnt2, */ 42465 /* the information is stored 3-tuppels */ 42466 /* in the following sequence */ 42467 /* Position, (1,0)-der, (0,1)-der, */ 42468 /* (2,0)-der, (1,1)-der (0,2)-der and normal */ 42469 /* This is compatible with output of s1421 */ 42470 double spntend1[21]; /* End values of candidate end point in surf1*/ 42471 double spntend2[21]; /* End values of candidate end point in surf1*/ 42472 double sparend1[2]; /* Parameter value at candidate end point */ 42473 double sparend2[2]; /* Parameter value at candidate end point */ 42474 double *snxt1; /* SISLPoint in psurf1 we have accepted */ 42475 double *snxt2; /* SISLPoint in psurf2 we have accepted */ 42476 double *snxp1; /* Parameter value belonging to snxt1 */ 42477 double *snxp2; /* Parameter value belonging to snxt2 */ 42478 double *s3dinf=SISL_NULL; /* Pointer to array used for storing 3-D position 42479 tangent, curvature and radius of curvature found 42480 during the marching process */ 42481 double *sp1inf=SISL_NULL; /* Pointer to array used for storing position 42482 tangent, curvature and radius of curvature found 42483 in the first parameter plane during the 42484 marching process */ 42485 double *sp2inf=SISL_NULL; /* Pointer to array used for storing position 42486 tangent, curvature and radius of curvature found 42487 in the first parameter plane during the 42488 marching process */ 42489 double *spar=SISL_NULL; /* Parametrization of points */ 42490 double sval1[2]; /* Limits of parameter plane in first SISLdir */ 42491 double sval2[2]; /* Limits of parameter plane in second SISLdir */ 42492 double sval3[2]; /* Limits of parameter plane in third SISLdir */ 42493 double sval4[2]; /* Limits of parameter plane in fourth SISLdir */ 42494 double tref1,tref2; /* Reference values for knot vectors */ 42495 double tref3,tref4; /* Reference values for knot vectors */ 42496 double start1[21]; /* Description of start point in psurf1 */ 42497 double start2[21]; /* Description of start point in psurf1 */ 42498 double stpar1[2]; /* Parameter pair belonging to start1 */ 42499 double stpar2[2]; /* Parameter pair belonging to start2 */ 42500 double sdum1[3],sdum2[3];/* Dummy vectors */ 42501 double tdum,tdump1,tdump2;/*Dummy variable */ 42502 double *sp1=SISL_NULL; /* Pointer used when moving information */ 42503 double *sp2=SISL_NULL; /* Pointer used when moving information */ 42504 double stdum[10]; /* Dummy array used when moving information */ 42505 double *stang; /* Pointer to tangent of current point */ 42506 double *stangp1; /* Pointer to tangent of current point in pp1*/ 42507 double *stangp2; /* Pointer to tangent of current point in pp2*/ 42508 double *spoint; /* Pointer to current point */ 42509 double t1distgd,t2distgd;/* Distances to guide points */ 42510 SISLCurve *q3dcur=SISL_NULL;/* Pointer to 3-D curve */ 42511 SISLCurve *qp1cur=SISL_NULL;/* Pointer to curve in first parameter plane*/ 42512 SISLCurve *qp2cur=SISL_NULL;/* Pointer to curve in 2.nd parameter plane*/ 42513 42514 42515 *jstat = 0; 42516 42517 if ( pinter == SISL_NULL ) goto err150; 42518 42519 42520 /* Check if the geometry already has been generated in the topology part. 42521 This will be the case if the geometry is along a constant parameter line. 42522 Freeing the geometry her makes it possible to generate curves for both 42523 parameter planes if required (the pointers will be set to SISL_NULL further 42524 down, i.e. would cause a memory leak if they weren't free'ed here. */ 42525 42526 if (pinter->itype == 9) 42527 { 42528 if (pinter->pgeom) freeCurve(pinter->pgeom); 42529 if (pinter->ppar1) freeCurve(pinter->ppar1); 42530 if (pinter->ppar2) freeCurve(pinter->ppar2); 42531 } 42532 42533 42534 /* Make maximal step length based on box-size of surface */ 42535 42536 sh1992su(psurf1,0,aepsge,&kstat); 42537 if (kstat < 0) goto error; 42538 42539 tmax = MAX(psurf1->pbox->e2max[0][0] - psurf1->pbox->e2min[0][0], 42540 psurf1->pbox->e2max[0][1] - psurf1->pbox->e2min[0][1]); 42541 tmax = MAX(tmax,psurf1->pbox->e2max[0][2] - psurf1->pbox->e2min[0][2]); 42542 42543 sh1992su(psurf2,0,aepsge,&kstat); 42544 if (kstat < 0) goto error; 42545 42546 tmax = MAX(tmax,psurf2->pbox->e2max[0][0] - psurf2->pbox->e2min[0][0]); 42547 tmax = MAX(tmax,psurf2->pbox->e2max[0][1] - psurf2->pbox->e2min[0][1]); 42548 tmax = MAX(tmax,psurf2->pbox->e2max[0][2] - psurf2->pbox->e2min[0][2]); 42549 42550 if (amax>DZERO) tmax = MIN(tmax,amax); 42551 42552 /* Find a none singular start point for the marching process */ 42553 42554 kpoint = pinter->ipoint; 42555 kpar1 = pinter->ipar1; 42556 kpar2 = pinter->ipar2; 42557 sgpara = pinter->epar1; 42558 sgparb = pinter->epar2; 42559 ktype = pinter->itype; 42560 42561 42562 /* To support closed curve the first guide point must be copied after 42563 the last guide point */ 42564 42565 if((sgpar1=newarray(2*kpoint+2,DOUBLE)) == SISL_NULL) goto err101; 42566 if((sgpar2=newarray(2*kpoint+2,DOUBLE)) == SISL_NULL) goto err101; 42567 memcopy(sgpar1,sgpara,2*kpoint,DOUBLE); 42568 memcopy(sgpar2,sgparb,2*kpoint,DOUBLE); 42569 42570 if (ktype ==2 || ktype == 3) 42571 { 42572 /*Closed curve copy first guide point to end of string of guide points */ 42573 memcopy(sgpar1+2*kpoint,sgpara,2,DOUBLE); 42574 memcopy(sgpar2+2*kpoint,sgparb,2,DOUBLE); 42575 kpoint = kpoint + 1; 42576 } 42577 42578 /* Initiate pointers to intersection curve and intersection curve in 42579 parameter plane */ 42580 42581 pinter -> pgeom = SISL_NULL; 42582 pinter -> ppar1 = SISL_NULL; 42583 pinter -> ppar2 = SISL_NULL; 42584 42585 /* Initiate parameter direction boundaries */ 42586 42587 kk = psurf1 -> ik1; 42588 kn = psurf1 -> in1; 42589 st = psurf1 -> et1; 42590 sval1[0] = st[kk-1]; 42591 sval1[1] = st[kn]; 42592 tref1 = (double)3.0*MAX(fabs(*sval1),fabs(*(sval1+1))); 42593 kk = psurf1 -> ik2; 42594 kn = psurf1 -> in2; 42595 st = psurf1 -> et2; 42596 sval2[0] = st[kk-1]; 42597 sval2[1] = st[kn]; 42598 tref2 = (double)3.0*MAX(fabs(*sval2),fabs(*(sval2+1))); 42599 kk = psurf2 -> ik1; 42600 kn = psurf2 -> in1; 42601 st = psurf2 -> et1; 42602 sval3[0] = st[kk-1]; 42603 sval3[1] = st[kn]; 42604 tref3 = (double)3.0*MAX(fabs(*sval3),fabs(*(sval3+1))); 42605 kk = psurf2 -> ik2; 42606 kn = psurf2 -> in2; 42607 st = psurf2 -> et2; 42608 sval4[0] = st[kk-1]; 42609 sval4[1] = st[kn]; 42610 tref4 = (double)3.0*MAX(fabs(*sval4),fabs(*(sval4+1))); 42611 42612 42613 42614 /* Test the both objects have 2 parameter directions */ 42615 42616 if (kpar1 != 2 || kpar2 != 2) goto err123; 42617 42618 /*THE POINTS , TANGENT, CURVATURE AND RADIUS OF CURVATURE FOUND DURING 42619 THE MARCHING PROCESS SHOULD ALL BE STORED IN ARRAYS. ALLOCATE ONE ARRAY 42620 FOR 3-D INFORMATION , ONE ARRAY FOR INFORMATION IN FIRST PARAMETER PLANE 42621 AND ONE ARRAY FOR INFORMATION IN SECOND PARAMETER PLANE. THESE ARRAYS 42622 ARE GIVEN AN INITIAL CAPACITY OF STORING 100 POINTS WITH OTHER INFORMATION. 42623 IF THEY ARE TO SHORT THEY WILL BE REALLOCATED AT A LATER STAGE. 42624 42625 SINCE THE STEPPING WILL GO IN BOTH DIRECTIONS WE WILL HAVE TO TURN THE 42626 INFORMATION FOUND WHEN MARCHING IN NEGATIVE DIRECTION, SO THAT IT CAN 42627 BE COMBINED WITH THE INFORMATION FOUND WHEN WE ARE MARCHING IN POSITVE 42628 DIRECTION. 42629 */ 42630 42631 kmaxinf = 100; 42632 s3dinf = newarray(10*kmaxinf,DOUBLE); 42633 if (s3dinf == SISL_NULL) goto err101; 42634 sp1inf = newarray(7*kmaxinf,DOUBLE); 42635 if (sp1inf == SISL_NULL) goto err101; 42636 sp2inf = newarray(7*kmaxinf,DOUBLE); 42637 if (sp2inf == SISL_NULL) goto err101; 42638 42639 42640 42641 /* Evaluate 0-1-2nd. derivative + normal of all guide points in both 42642 surfaces, first allocate arrays for storing the information */ 42643 42644 sgd1 = newarray(21*kpoint,DOUBLE); 42645 if (sgd1==SISL_NULL) goto err101; 42646 sgd2 = newarray(21*kpoint,DOUBLE); 42647 if (sgd2==SISL_NULL) goto err101; 42648 42649 kpos = 5; 42650 42651 /* Initiate kstart to point at no point */ 42652 42653 kstart = 0; 42654 42655 for (ki=0,kj=0,kl=0 ; ki<kpoint ; ki++,kj+=2,kl+=21) 42656 { 42657 s1421(psurf1,kder,&sgpar1[kj],&klfu,&klfv,&sgd1[kl],&sgd1[kl+18],&kstat); 42658 if (kstat<0) goto error; 42659 42660 /* Find length of normal vector and tangent vectors */ 42661 42662 tlnorm = s6length(&sgd1[kl+18],kdim,&kstat); 42663 tltan1 = s6length(&sgd1[kl+ 3],kdim,&kstat); 42664 tltan2 = s6length(&sgd1[kl+ 6],kdim,&kstat); 42665 42666 /* The cross product satisifes the following conditions: 42667 length(axb) = length(a) length(b) sin(angle(a,b)). 42668 Thus the angle between the two vectors can be found, close to 0 42669 sin(a) is a good approximation of a */ 42670 42671 if (tlnorm == DZERO || tltan1 ==DZERO || tltan2 == DZERO) 42672 tang1 = DZERO; 42673 else 42674 tang1 = tlnorm/(tltan1*tltan2); 42675 42676 s1421(psurf2,kder,&sgpar2[kj],&klfs,&klft,&sgd2[kl],&sgd2[kl+18],&kstat); 42677 if (kstat<0) goto error; 42678 42679 /* Find length of normal vector and tangent vectors */ 42680 42681 tlnorm = s6length(&sgd2[kl+18],kdim,&kstat); 42682 tltan1 = s6length(&sgd2[kl+ 3],kdim,&kstat); 42683 tltan2 = s6length(&sgd2[kl+ 6],kdim,&kstat); 42684 42685 /* The cross product satisifes the follwing conditions: 42686 length(axb) = length(a) length(b) sin(angle(a,b)). 42687 Thus the angle between the two vectors can be found, close to 0 42688 sin(a) is a good approximation of a */ 42689 42690 if (tlnorm == DZERO || tltan1 ==DZERO || tltan2 == DZERO) 42691 tang2 = DZERO; 42692 else 42693 tang2 = tlnorm/(tltan1*tltan2); 42694 42695 42696 if (tang1 >= ANGULAR_TOLERANCE && tang2 >= ANGULAR_TOLERANCE) 42697 { 42698 /* Make tangent of intersection curve */ 42699 42700 s6crss(&sgd1[kl+18],&sgd2[kl+18],sdum1); 42701 42702 tlnorm = s6length(sdum1,kdim,&kstat); 42703 42704 /* Remember if start, internal or end point */ 42705 42706 if (tlnorm != DZERO) 42707 { 42708 if (ki == 0) 42709 kfirst = 1; 42710 else if (ki == kpoint-1) 42711 klast = kpoint; 42712 else 42713 kstart = ki+1; 42714 } 42715 } 42716 } 42717 42718 42719 /* Check if only degenerate points or singularities exist on the 42720 intersection curve */ 42721 42722 if (kstart == 0) 42723 { 42724 /* No internal nondegenerate point exits, start marching from first 42725 or last point if possible */ 42726 42727 if (kfirst != 0 && ktype != 5 && ktype != 7) kstart = kfirst; 42728 else if (klast != 0 && ktype != 6 && 42729 ktype != 7 && ktype != 3) kstart = klast; 42730 else if (kfirst != 0) kstart = kfirst; 42731 else if (klast != 0) kstart = klast; 42732 else goto interpolate; 42733 } 42734 42735 42736 /* To speed up the marching process when many guide points are given, 42737 remove guide points that are not at the start, end or the start point */ 42738 42739 if (kpoint >2 && (kstart==1 || kstart==kpoint) ) 42740 { 42741 /* No internal guide point necessary, copy last point to second point */ 42742 memcopy(sgd1+21,sgd1+21*(kpoint-1),21,DOUBLE); 42743 memcopy(sgpar1+2,sgpar1+2*(kpoint-1),2,DOUBLE); 42744 memcopy(sgd2+21,sgd2+21*(kpoint-1),21,DOUBLE); 42745 memcopy(sgpar2+2,sgpar2+2*(kpoint-1),2,DOUBLE); 42746 42747 if (kstart == kpoint) kstart = 2; 42748 kpoint = 2; 42749 } 42750 else if (kpoint>2) 42751 { 42752 /* Internal guide point exists, copy this to second position and 42753 copy end point to third position */ 42754 42755 memcopy(sgd1+21,sgd1+21*(kstart-1),21,DOUBLE); 42756 memcopy(sgpar1+2,sgpar1+2*(kstart-1),2,DOUBLE); 42757 memcopy(sgd2+21,sgd2+21*(kstart-1),21,DOUBLE); 42758 memcopy(sgpar2+2,sgpar2+2*(kstart-1),2,DOUBLE); 42759 42760 memcopy(sgd1+2*21,sgd1+21*(kpoint-1),21,DOUBLE); 42761 memcopy(sgpar1+4,sgpar1+2*(kpoint-1),2,DOUBLE); 42762 memcopy(sgd2+2*21,sgd2+21*(kpoint-1),21,DOUBLE); 42763 memcopy(sgpar2+4,sgpar2+2*(kpoint-1),2,DOUBLE); 42764 42765 kpoint = 3; 42766 kstart = 2; 42767 } 42768 42769 /* Remember description of start point in both surfaces, 42770 copy point indicated by kstart into spnt1,spnt2,spar1,spar2 */ 42771 42772 memcopy(spnt1,sgd1+21*(kstart-1),21,DOUBLE); 42773 memcopy(spnt2,sgd2+21*(kstart-1),21,DOUBLE); 42774 memcopy(spar1,sgpar1+2*(kstart-1),2,DOUBLE); 42775 memcopy(spar2,sgpar2+2*(kstart-1),2,DOUBLE); 42776 42777 /* Make position, unit tangent, curvature and radius of curvature for 42778 start point of iteration, store them in the arrays just allocated */ 42779 42780 kpos = 10; 42781 s1304(spnt1,spnt2,spar1,spar2,s3dinf,sp1inf,sp2inf,&kstat); 42782 42783 if (kstat<0) goto error; 42784 42785 /* Remember start tangent */ 42786 42787 memcopy(startg,s3dinf+3,3,DOUBLE); 42788 42789 42790 /* Iterate intersection point down to the intersection curve */ 42791 42792 tstep = DZERO; 42793 s9iterate(s3dinf,spnt1,spnt2,spar1,spar2,psurf1,psurf2,tstep, 42794 aepsge,sipnt1,sipnt2,sipar1,sipar2,&kstat); 42795 if (kstat < 0) goto error; 42796 42797 /* Copy result of iteration into spnt1,spnt2,spar1,spar2 */ 42798 42799 42800 if (kstat==0 && 42801 (s6dist(spnt1,sipnt1,3) > aepsge || s6dist(spnt2,sipnt2,3) > aepsge)) 42802 { 42803 /* Copy result of iteration of convergence to no singular point */ 42804 42805 memcopy(spnt1,sipnt1,21,DOUBLE); 42806 memcopy(spnt2,sipnt2,21,DOUBLE); 42807 memcopy(spar1,sipar1,2,DOUBLE); 42808 memcopy(spar2,sipar2,2,DOUBLE); 42809 } 42810 42811 if (kstat==0) 42812 { 42813 memcopy(start1,sipnt1,21,DOUBLE); 42814 memcopy(start2,sipnt2,21,DOUBLE); 42815 memcopy(stpar1,sipar1,2,DOUBLE); 42816 memcopy(stpar2,sipar2,2,DOUBLE); 42817 } 42818 else 42819 { 42820 memcopy(start1,spnt1,21,DOUBLE); 42821 memcopy(start2,spnt2,21,DOUBLE); 42822 memcopy(stpar1,spar1,2,DOUBLE); 42823 memcopy(stpar2,spar2,2,DOUBLE); 42824 } 42825 42826 /* Make position, unit tangent, curvature and radius of curvature for 42827 start point of iteration, store them in the arrays just allocated */ 42828 42829 kpos = 10; 42830 s1304(start1,start2,stpar1,stpar2,s3dinf,sp1inf,sp2inf,&kstat); 42831 42832 if (kstat<0) goto error; 42833 42834 /* Test if singular point reached */ 42835 42836 if (kstat == 2) goto war03; 42837 42838 /* Remember that start point is already stored */ 42839 42840 knbinf = 1; 42841 42842 /* Make step length based on 3-D radius of curvature, tolerances and 42843 maks step length */ 42844 42845 kpos = 20; 42846 tstep = s1311(s3dinf[9],aepsge,tmax,&kstat); 42847 if (kstat<0) goto error; 42848 tstartstp = tstep; 42849 42850 /* STEP IN BOTH DIRECTIONS FROM THE FOUND START POINT */ 42851 42852 /* Indicate that direction in guide point array not determined */ 42853 42854 kguide = kstart; 42855 kgdir = 0; 42856 42857 for (kdir=1;kdir<3;kdir++) 42858 { 42859 42860 if (kdir == 2) 42861 { 42862 /* Remember result of marching in first direction */ 42863 42864 knb1 = knbinf; 42865 kgd1 = kguide; 42866 42867 /* If the previous step direction made no points then knbinf==0. To 42868 enable the marching we start from the same start point as the 42869 previous step direction, thus in this case knbinf should be 1. */ 42870 42871 knbinf = MAX(1,knbinf); 42872 42873 /* We now step in the second step direction. Turn the sequence of 42874 the points found as well as change tangent directions */ 42875 42876 /* First interchange 3-D info */ 42877 42878 for (sp1=s3dinf,sp2=s3dinf+10*(knbinf-1) ; sp1<sp2 ; sp1+=10,sp2-=10) 42879 { 42880 memcopy(stdum,sp1, 10,DOUBLE); 42881 memcopy(sp1 ,sp2, 10,DOUBLE); 42882 memcopy(sp2 ,stdum,10,DOUBLE); 42883 } 42884 42885 for (sp1=s3dinf+3;sp1<s3dinf+10*knbinf;sp1+=10) 42886 { 42887 sp1[0] = - sp1[0]; 42888 sp1[1] = - sp1[1]; 42889 sp1[2] = - sp1[2]; 42890 } 42891 42892 /* Then interchange info in first parameter plane */ 42893 42894 for (sp1=sp1inf,sp2=sp1inf+7*(knbinf-1) ; sp1<sp2 ; sp1+=7,sp2-=7) 42895 { 42896 memcopy(stdum,sp1 ,7,DOUBLE); 42897 memcopy(sp1 ,sp2 ,7,DOUBLE); 42898 memcopy(sp2 ,stdum,7,DOUBLE); 42899 } 42900 42901 for (sp1=sp1inf+2;sp1<sp1inf+7*knbinf;sp1+=7) 42902 { 42903 sp1[0] = - sp1[0]; 42904 sp1[1] = - sp1[1]; 42905 sp1[2] = - sp1[2]; 42906 } 42907 42908 /* Then interchange info in second parameter plane */ 42909 42910 for (sp1=sp2inf,sp2=sp2inf+7*(knbinf-1) ; sp1<sp2 ; sp1+=7,sp2-=7) 42911 { 42912 memcopy(stdum,sp1 ,7,DOUBLE); 42913 memcopy(sp1 ,sp2 ,7,DOUBLE); 42914 memcopy(sp2 ,stdum,7,DOUBLE); 42915 } 42916 42917 for (sp1=sp2inf+2;sp1<sp2inf+7*knbinf;sp1+=7) 42918 { 42919 sp1[0] = - sp1[0]; 42920 sp1[1] = - sp1[1]; 42921 sp1[2] = - sp1[2]; 42922 } 42923 42924 /* Turn direction of remembered start tangent */ 42925 42926 for (ki=0;ki<3;ki++) 42927 startg[ki] = -startg[ki]; 42928 42929 42930 /* Update spnt1, spnt2, spar1 and spar2 to 42931 have the start point values */ 42932 42933 memcopy(spnt1,start1,21,DOUBLE); 42934 memcopy(spnt2,start2,21,DOUBLE); 42935 memcopy(spar1,stpar1,2,DOUBLE); 42936 memcopy(spar2,stpar2,2,DOUBLE); 42937 42938 /* Turn the direction we march the guide point vector, 42939 and set current guide point to kstart */ 42940 42941 kgdir = -kgdir; 42942 kguide = kstart; 42943 42944 /* Update step length */ 42945 42946 tstep = tstartstp; 42947 } 42948 42949 kpos = 30; 42950 42951 /* Step direction ok, perform marching until stop condition reached */ 42952 42953 kcont = 1; 42954 42955 while (kcont) 42956 { 42957 42958 42959 /* We must make sure that we are not stepping past a guide point. 42960 * Thus if we get close to a guide point, make sure that we step 42961 * through this. The direction we travers the guide point array 42962 * might not have been determined yet. Thus we have to test in 42963 * both directions in guide point array. 42964 * 42965 * Remember how we step in the varaible kstpch: 42966 * kstpch = -1 : Try to step to previous guide point 42967 * kstpch = 0 : Try not to step through guide point 42968 * kstpch = 1 : Try to step to next guide point 42969 * kstpch = 3 : Step to start point and stop marching 42970 * kstpch = 4 : Don't step through guide point, candidate 42971 * end point of segement found in iteration loop 42972 */ 42973 42974 42975 kstpch = 0; 42976 stang = s3dinf + 10*(knbinf-1) + 3; 42977 stangp1 = sp1inf + 7*(knbinf-1) + 2; 42978 stangp2 = sp2inf + 7*(knbinf-1) + 2; 42979 42980 if (kgdir >=0) 42981 { 42982 42983 /* We are stepping in positive direction in guide point vector 42984 * calculate distance to next guide point. If the guide point 42985 * is lying closer than the step length to the current point 42986 * we should step directly to this point provided that the cross 42987 * product of the normal vectors at current point and at the 42988 * guide point have the same direction, e.g. that their scalar 42989 * product is positiv 42990 */ 42991 42992 t1distgd = (double)2.0*tstep; 42993 if (kguide < kpoint) 42994 { 42995 /* Decide if we should step through the guide point */ 42996 42997 kpos = 40; 42998 t1distgd = s9adstep(spnt1,spar1,spnt2,spar2,&sgd1[kguide*21], 42999 &sgpar1[kguide*2],&sgd2[kguide*21], 43000 &sgpar2[kguide*2],stang, 43001 stangp1,stangp2,tstep,&kstat); 43002 if (kstat<0) goto error; 43003 if (kstat == 1) 43004 { 43005 /* Step through guide point remember this */ 43006 43007 kstpch = 1; 43008 snxt1 = sgd1 + 21*kguide; 43009 snxt2 = sgd2 + 21*kguide; 43010 snxp1 = sgpar1 + 2*kguide; 43011 snxp2 = sgpar2 + 2*kguide; 43012 tstep = MIN(tstep,t1distgd); 43013 } 43014 } 43015 } 43016 43017 if (kgdir <=0) 43018 { 43019 43020 /* We are stepping in negative direction in guide point vector 43021 * calculate distance to previous guide point. If the guide point 43022 * is lying closer than the step length to the current point 43023 * we should step directly to this point provided that the cross 43024 * product of the normal vectors at current point and at the 43025 * guide point have the same direction, e.g. that their scalar 43026 * product is positiv 43027 */ 43028 43029 if (1 < kguide) 43030 { 43031 /* Decide if we should step through the guide point */ 43032 43033 kpos = 50; 43034 t2distgd = s9adstep(spnt1,spar1,spnt2,spar2, 43035 &sgd1[(kguide-2)*21],&sgpar1[(kguide-2)*2], 43036 &sgd2[(kguide-2)*21],&sgpar2[(kguide-2)*2], 43037 stang,stangp1,stangp2,tstep,&kstat); 43038 43039 if (kstat<0) goto error; 43040 if ((kstat == 1 &&kstpch == 0) || 43041 (kstat == 1 && kstpch == 1 && t2distgd < t1distgd)) 43042 { 43043 /* Step through guide point remember this */ 43044 43045 kstpch = -1; 43046 snxt1 = sgd1 + 21*(kguide-2); 43047 snxt2 = sgd2 + 21*(kguide-2); 43048 snxp1 = sgpar1 + 2*(kguide-2); 43049 snxp2 = sgpar2 + 2*(kguide-2); 43050 tstep = MIN(tstep,t2distgd); 43051 } 43052 } 43053 } 43054 43055 /* Check if we step through the start point, should only be necessary 43056 if at least 3 points found in this marching direction */ 43057 43058 if ((kdir==1 && knbinf>3) || (kdir==2 && knbinf>knb1+2)) 43059 { 43060 kpos = 60; 43061 tdum = s9adstep(spnt1,spar1,spnt2,spar2,start1,stpar1,start2, 43062 stpar2,stang,stangp1,stangp2,tstep,&kstat); 43063 if (kstat<0) goto error; 43064 if (kstat == 1) 43065 { 43066 /* Step to start point remember this */ 43067 43068 kstpch = 3; 43069 snxt1 = start1; 43070 snxt2 = start2; 43071 snxp1 = stpar1; 43072 snxp2 = stpar2; 43073 tstep = MIN(tstep,tdum); 43074 43075 } 43076 } 43077 43078 /* At this stage kstpch=0 if we have not reached a guide point or 43079 if we have not reached the start point of the iteration. 43080 43081 Now we want to find a Bezier segement that is lying within the 43082 geometric tolerance that is approximating the intersection curve. 43083 If a guide point is reached (kstpch=-1 or 1), then we have a 43084 candidate for the end point of the Bezier segement. If the start 43085 point is reached (kstpch=3) then we also have a candidate 43086 end point for the segment. 43087 43088 The next loop use kstpch to indicate if we have a candidate 43089 end point for the segment: 43090 43091 kstpch==0 : No candidate end point exists 43092 kstpch!=0 : Candidate end point exists 43093 43094 43095 To indicate if the segement is within the resolution we 43096 use koutside_resolution: 43097 43098 koutside_resolution==0 : Segment outside resolution 43099 koutside_resolution!=0 : Segment inside resolution 43100 */ 43101 43102 koutside_resolution = 0; 43103 43104 43105 /* Make sure that there is enough space for one more point */ 43106 43107 if (knbinf>=kmaxinf) 43108 { 43109 kmaxinf = kmaxinf + 100; 43110 s3dinf = increasearray(s3dinf,((3*kdim+1)*kmaxinf),DOUBLE); 43111 if (s3dinf==SISL_NULL) goto err101; 43112 sp1inf = increasearray(sp1inf,7*kmaxinf,DOUBLE); 43113 if (sp1inf==SISL_NULL) goto err101; 43114 sp2inf = increasearray(sp2inf,7*kmaxinf,DOUBLE); 43115 if (sp2inf==SISL_NULL) goto err101; 43116 } 43117 43118 43119 /*Make description of candidate endpoint if it exists and store it */ 43120 43121 if (kstpch != 0) 43122 { 43123 s1304(snxt1,snxt2,snxp1,snxp2,s3dinf+10*knbinf, 43124 sp1inf+7*knbinf,sp2inf+7*knbinf,&kstat); 43125 if (kstat<0) goto error; 43126 43127 /* It is allowed to jump on to a singular point 43128 Make sure that the tangents of previous and the new point 43129 point in the same direction */ 43130 43131 if (knbinf>0) 43132 tdum = s6scpr(s3dinf+10*(knbinf-1)+3, 43133 s3dinf+10*knbinf+3,kdim); 43134 else 43135 tdum = s6scpr(startg,s3dinf+3,kdim); 43136 43137 43138 if (tdum < DZERO) 43139 { 43140 /* Change tangent direction 3-D and in parameter plane */ 43141 sp1 = s3dinf + 10*knbinf + 3; 43142 sp1[0] = -sp1[0]; 43143 sp1[1] = -sp1[1]; 43144 sp1[2] = -sp1[2]; 43145 sp1 = sp1inf + 7*knbinf + 2; 43146 sp1[0] = -sp1[0]; 43147 sp1[1] = -sp1[1]; 43148 sp1 = sp2inf + 7*knbinf + 2; 43149 sp1[0] = -sp1[0]; 43150 sp1[1] = -sp1[1]; 43151 } 43152 43153 /* Copy the candidate point to spntend1, spntend2,sparend1 43154 and sparend2 */ 43155 43156 memcopy(spntend1,snxt1,21,DOUBLE); 43157 memcopy(sparend1,snxp1,2,DOUBLE); 43158 memcopy(spntend2,snxt2,21,DOUBLE); 43159 memcopy(sparend2,snxp2,2,DOUBLE); 43160 } 43161 43162 43163 while (kstpch == 0 || koutside_resolution == 0) 43164 { 43165 if (kstpch!=0) 43166 { 43167 /* Candidate end point exist, iterate to find point close 43168 to the midpoint of the Bezier segement */ 43169 43170 43171 /* Decide if Hermit shape acceptable and find position and 43172 tangent at midpoint of segment */ 43173 43174 start = s3dinf + 10*(knbinf-1); 43175 43176 s1361(start,start+10,3,smidd,smidd+3,&kstat); 43177 if (kstat<0) goto error; 43178 43179 tcurstep = DZERO; 43180 spoint = smidd; 43181 } 43182 else 43183 { 43184 43185 /* Iterate to find end point of segment */ 43186 43187 /* ITERATE by intersecting the two surface and the plane 43188 defined by current point (s3dinf), the tangent (s3dinf+3) 43189 and the step length */ 43190 43191 spoint = s3dinf + 10*(knbinf-1); 43192 tcurstep = tstep; 43193 } 43194 43195 /* Perform the actual iteration */ 43196 43197 kpos = 70; 43198 s9iterate(spoint,spnt1,spnt2,spar1,spar2,psurf1,psurf2,tcurstep, 43199 aepsge,sipnt1,sipnt2,sipar1,sipar2,&kstat); 43200 if (kstat < 0) goto error; 43201 43202 /* Initiate distance between midpoint and iteration point 43203 to -1 to enable detection of divergence */ 43204 43205 tdist = (double)-1.0; 43206 43207 /* Check if iteration has converged */ 43208 43209 if (kstat == 2) 43210 { 43211 /* Iteration has diverged, half step length if possible, 43212 find new endpoint of segement. */ 43213 43214 kstpch = 0; 43215 koutside_resolution = 0; 43216 } 43217 else if(kstat == 1 && kstpch != 0) 43218 { 43219 /* The point found is closer to the input point than 43220 the relative computer resolution or is a singular point. 43221 We stop the marching in this direction here 43222 Half step length if possible, find new endpoint of 43223 segement. */ 43224 43225 kstpch = 0; 43226 koutside_resolution = 0; 43227 } 43228 else if (kstpch!=0) 43229 { 43230 43231 43232 /* Make description of intersection point */ 43233 43234 s1304(sipnt1,sipnt2,sipar1,sipar2,simiddpnt,simiddpar1, 43235 simiddpar2,&kstat); 43236 if (kstat<0) goto error; 43237 43238 43239 if (kstat != 2) 43240 { 43241 /* We iterated to find midpoint of segment, test if 43242 it is within resolution */ 43243 43244 tdist = s6dist(simiddpnt,smidd,3); 43245 tang = s6ang(simiddpnt+3,smidd+3,3); 43246 } 43247 43248 /* If point is singular or not within resolution a new 43249 Hermit segment has to be made */ 43250 43251 if (kstat == 2 || (fabs(tdist) > aepsge || 43252 (fabs(tang) > ANGULAR_TOLERANCE && 43253 tstep > aepsge))) 43254 { 43255 kstpch = 0; 43256 koutside_resolution = 0; 43257 } 43258 else 43259 { 43260 /*Segment within tolerance. 43261 Check that the relationship between the two surfaces 43262 has not been interchanged, by making the cross product 43263 of the normal vectors in current point and the point 43264 found by iteration. Then make the scalar product of 43265 these vectors. If the scalar product is negative then 43266 we have either jumped to another branch or passed a 43267 singularity,iterprete this as the iteration has diverged 43268 In addition we don't want the direction of the tangents 43269 change to much. We set a limit of approximately PI/3 43270 Make normal vectors in implicit surface for both points 43271 Make also sure that the curve in the parameter plane 43272 does not turn more than 90 degrees. 43273 by testing on a cosin value of 0.5 43274 */ 43275 43276 s6crss(spnt1+18,spnt2+18,sdum1); 43277 (void)s6norm(sdum1,kdim,sdum1,&kstat); 43278 if (kstat < 0) goto error; 43279 43280 s6crss(spntend1+18,spntend2+18,sdum2); 43281 (void)s6norm(sdum2,kdim,sdum2,&kstat); 43282 if (kstat < 0) goto error; 43283 43284 tdum = s6scpr(sdum1,sdum2,kdim); 43285 43286 s6diff(sipar1,spar1,2,sdum1); 43287 tdump1 = s6scpr(sdum1,sp1inf+7*(knbinf-1)+2,2); 43288 43289 s6diff(sipar2,spar2,2,sdum1); 43290 tdump2 = s6scpr(sdum1,sp2inf+7*(knbinf-1)+2,2); 43291 43292 if (tdum == DZERO) 43293 { 43294 double tl1,tl2; 43295 43296 /* If one of the tangents have zero length, 43297 accept segment */ 43298 43299 tl1 = s6length(sdum1,kdim,&kstat); 43300 tl2 = s6length(sdum2,kdim,&kstat); 43301 43302 if (tl1 == DZERO || tl2 == DZERO) 43303 koutside_resolution = 1; 43304 else 43305 { 43306 /* Find new end point of segment */ 43307 43308 koutside_resolution = 0; 43309 kstpch = 0; 43310 } 43311 43312 } 43313 else if (tdum <= (double)0.5 || tdump1 <= DZERO 43314 || tdump2 <= DZERO) 43315 { 43316 /*Find new end point of segment */ 43317 43318 koutside_resolution = 0; 43319 kstpch = 0; 43320 } 43321 else 43322 { 43323 koutside_resolution = 1; 43324 } 43325 } 43326 } 43327 else 43328 { 43329 /* We iterated to find end point of segment, 43330 update pointer */ 43331 43332 memcopy(spntend1,sipnt1,21,DOUBLE); 43333 memcopy(sparend1,sipar1,2,DOUBLE); 43334 memcopy(spntend2,sipnt2,21,DOUBLE); 43335 memcopy(sparend2,sipar2,2,DOUBLE); 43336 43337 s1304(sipnt1,sipnt2,sipar1,sipar2,s3dinf+10*knbinf, 43338 sp1inf+7*knbinf,sp2inf+7*knbinf,&kstat); 43339 if (kstat<0) goto error; 43340 43341 /* Make sure that the tangents of previous and the new point 43342 point in the same direction, singular end point allowed' */ 43343 43344 if (knbinf>0) 43345 tdum = s6scpr(s3dinf+10*(knbinf-1)+3, 43346 s3dinf+10*knbinf+3,kdim); 43347 else 43348 tdum = s6scpr(startg,s3dinf+3,kdim); 43349 43350 43351 if (tdum < DZERO) 43352 { 43353 /* Change tangent direction 3-D and in parameter plane */ 43354 43355 sp1 = s3dinf + 10*knbinf + 3; 43356 sp1[0] = -sp1[0]; 43357 sp1[1] = -sp1[1]; 43358 sp1[2] = -sp1[2]; 43359 sp1 = sp1inf + 7*knbinf + 2; 43360 sp1[0] = -sp1[0]; 43361 sp1[1] = -sp1[1]; 43362 sp1 = sp2inf + 7*knbinf + 2; 43363 sp1[0] = -sp1[0]; 43364 sp1[1] = -sp1[1]; 43365 } 43366 /* Indicate that end point accepted */ 43367 43368 kstpch = 4; 43369 koutside_resolution = 0; 43370 } 43371 /* It the segment is acceptable clip to the boundary */ 43372 43373 if (kstpch != 0 && koutside_resolution == 1) 43374 { 43375 43376 /* Check if the curve between the start and end point 43377 cross the boundary */ 43378 43379 memcopy(sparmid1,sipar1,2,double); 43380 memcopy(sparmid2,sipar2,2,double); 43381 43382 s1330(spar1,spar2,sparend1,sparend2,sval1,sval2,sval3,sval4, 43383 &kbound,sipar1,sipar2,&kstat); 43384 if (kstat<0) goto error; 43385 43386 43387 /* In case of kstat==4 (we go from the boundary and out) 43388 or kstat==0 and the start is within computer resolution 43389 from the boundary, make sure that the tangent points out 43390 in both parameter planes. 43391 If not set status to 1 e.g, we are inside the patch */ 43392 43393 if(kstat==0 || kstat==4) 43394 { 43395 /* Set pointer to tangents at start point */ 43396 ki = 7*(knbinf-1)+2; 43397 43398 if(((DEQUAL(spar1[1]+tref2,sval2[0]+tref2) && 43399 sp1inf[ki+1]>DZERO) || 43400 (DEQUAL(spar1[1]+tref2,sval2[1]+tref2) && 43401 sp1inf[ki+1]<DZERO) || 43402 (DEQUAL(spar1[0]+tref1,sval1[0]+tref1) && 43403 sp1inf[ki ]>DZERO) || 43404 (DEQUAL(spar1[0]+tref1,sval1[1]+tref1) && 43405 sp1inf[ki ]<DZERO) 43406 ) && 43407 ((DEQUAL(spar2[1]+tref4,sval3[0]+tref4) && 43408 sp2inf[ki+1]>DZERO) || 43409 (DEQUAL(spar2[1]+tref4,sval3[1]+tref4) && 43410 sp2inf[ki+1]<DZERO) || 43411 (DEQUAL(spar2[0]+tref3,sval2[0]+tref3) && 43412 sp2inf[ki ]>DZERO) || 43413 (DEQUAL(spar2[0]+tref3,sval2[1]+tref3) && 43414 sp2inf[ki ]<DZERO))) 43415 kstat = 1; 43416 } 43417 krem1 = kstat; 43418 43419 /* Check if the curve between the start and midpoint cross 43420 the boundary */ 43421 43422 s1330(spar1,spar2,sparmid1,sparmid2,sval1,sval2,sval3,sval4, 43423 &kbound,sipar1,sipar2,&kstat); 43424 if (kstat<0) goto error; 43425 43426 krem2 = kstat; 43427 43428 /* We now have the following cases: 43429 kstat == 0 : 43430 Line between (spar1,spar2) and (sparend1,sparend2) 43431 outside. If this happens when kdir=1, then 43432 just forget the start point. If it happens 43433 when kdir=2, then we just stop the marching. 43434 kstat == 1 : Line between epar1 and epar2 inside. 43435 Continue iteration. 43436 kstat == 2 : We step out of the patch. Clip to the edge 43437 of the patch. Update start point. 43438 kstat == 3 : We step into the patch. Clip to the edge 43439 of the patch. Update endpoint 43440 kstat == 4 : We go from the boundary and out. Try next 43441 iteration direction. 43442 */ 43443 43444 if (krem1 == 0 || krem2 == 0) 43445 { 43446 if (kdir==1) knbinf--; 43447 goto nextdir; 43448 } 43449 else if ((krem1 !=1 || krem2 !=1) && 43450 krem1 != 4 && krem2 != 4) 43451 { 43452 43453 /* If we clip to the boundary, 43454 forget any guide point identified */ 43455 43456 kstat1 = 0; 43457 if (krem2 == 2 || krem2 == 3) 43458 { 43459 s9clipit(spar1,spar2,sparmid1,sparmid2,psurf1,psurf2, 43460 sval1,sval2,sval3,sval4,aepsge, 43461 sipnt1,sipnt2,sipar1,sipar2,&kstat); 43462 if (kstat<0) goto error; 43463 if (krem2==3 && kstat==1) kstpch = 4; 43464 kstat1 = kstat; 43465 krem = krem2; 43466 } 43467 if (kstat1 !=1 && (krem1 == 2 || krem1 == 3)) 43468 { 43469 s9clipit(spar1,spar2,sparend1,sparend2,psurf1,psurf2, 43470 sval1,sval2,sval3,sval4,aepsge, 43471 sipnt1,sipnt2,sipar1,sipar2,&kstat); 43472 if (kstat<0) goto error; 43473 if (krem1==3 && kstat==1) kstpch = 4; 43474 kstat1 = kstat; 43475 krem = krem1; 43476 } 43477 43478 if (kstat1 == 1) 43479 { 43480 /*Check that the relationship between the two 43481 surfaces has not been interchanged, 43482 by making the cross product 43483 of the normal vectors in current point and 43484 the point found by iteration. 43485 Then make the scalar product of these vectors. 43486 If the scalar product is negative then 43487 we have either jumped to another branch or passed a 43488 singularity, iterprete this as the iteration 43489 has diverged. 43490 In addition we don't want the direction of the 43491 tangents change to much. We set a limit of 43492 approximately PI/3 by testing on a 43493 cosin value of 0.5 43494 Make normal vectors in implicit surface for both 43495 points Make also sure that the curves in the 43496 parameter plane does not turn more than 90 degrees. 43497 */ 43498 43499 s6crss(spnt1+18,spnt2+18,sdum1); 43500 (void)s6norm(sdum1,kdim,sdum1,&kstat); 43501 if (kstat < 0) goto error; 43502 43503 s6crss(sipnt1+18,sipnt2+18,sdum2); 43504 (void)s6norm(sdum2,kdim,sdum2,&kstat); 43505 if (kstat < 0) goto error; 43506 43507 tdum = s6scpr(sdum1,sdum2,kdim); 43508 43509 /*Check that sipar1 lies on the same side of spar1 as 43510 the tangent at spar1 */ 43511 43512 s6diff(sipar1,spar1,2,sdum1); 43513 tdump1 = s6scpr(sdum1,sp1inf+7*(knbinf-1)+2,2); 43514 43515 s6diff(sipar2,spar2,2,sdum1); 43516 tdump2 = s6scpr(sdum1,sp2inf+7*(knbinf-1)+2,2); 43517 } 43518 43519 /* An intersection point has only been 43520 found when kstat==1 */ 43521 43522 if ( kstat1==1 && tdump1 >= DZERO && 43523 tdump1 >= DZERO && tdum > (double)0.5) 43524 43525 { 43526 /* If krem=3 we step into the patch, 43527 if krem=2 we step 43528 out of the patch */ 43529 43530 if (krem==2 || krem==3) 43531 { 43532 /* If krem==3 we step into the patch, make new 43533 start point of segment */ 43534 43535 if (krem==3) knbinf--; 43536 43537 memcopy(spntend1,sipnt1,21,DOUBLE); 43538 memcopy(sparend1,sipar1,2,DOUBLE); 43539 memcopy(spntend2,sipnt2,21,DOUBLE); 43540 memcopy(sparend2,sipar2,2,DOUBLE); 43541 43542 s1304(sipnt1,sipnt2,sipar1,sipar2, 43543 s3dinf+10*knbinf, 43544 sp1inf+7*knbinf, 43545 sp2inf+7*knbinf,&kstat); 43546 if (kstat<0) goto error; 43547 43548 /* Make sure that the tangents of previous 43549 and the new point 43550 point in the same direction */ 43551 43552 if (knbinf>0) 43553 tdum = s6scpr(s3dinf+10*(knbinf-1)+3, 43554 s3dinf+10*knbinf+3,kdim); 43555 else 43556 tdum = s6scpr(startg,s3dinf+3,kdim); 43557 43558 43559 if (tdum < DZERO) 43560 { 43561 /* Change tangent direction 3-D and in 43562 parameter plane */ 43563 43564 sp1 = s3dinf + 10*knbinf + 3; 43565 sp1[0] = -sp1[0]; 43566 sp1[1] = -sp1[1]; 43567 sp1[2] = -sp1[2]; 43568 sp1 = sp1inf + 7*knbinf + 2; 43569 sp1[0] = -sp1[0]; 43570 sp1[1] = -sp1[1]; 43571 sp1 = sp2inf + 7*knbinf + 2; 43572 sp1[0] = -sp1[0]; 43573 sp1[1] = -sp1[1]; 43574 } 43575 /* If the new end point tangent points out go to 43576 next direction */ 43577 43578 ki = 7*knbinf; 43579 if((sp1inf[ki+1] <= sval2[0] && 43580 sp1inf[ki+3] < DZERO) || 43581 (sp1inf[ki+1] >= sval2[1] && 43582 sp1inf[ki+3] > DZERO) || 43583 (sp1inf[ki ] <= sval1[0] && 43584 sp1inf[ki+2] < DZERO) || 43585 (sp1inf[ki ] >= sval1[1] && 43586 sp1inf[ki+2] > DZERO) || 43587 (sp2inf[ki+1] <= sval4[0] && 43588 sp2inf[ki+3] < DZERO) || 43589 (sp2inf[ki+1] >= sval4[1] && 43590 sp2inf[ki+3] > DZERO) || 43591 (sp2inf[ki ] <= sval3[0] && 43592 sp2inf[ki+2] < DZERO) || 43593 (sp2inf[ki ] >= sval3[1] && 43594 sp2inf[ki+2] > DZERO)) 43595 { 43596 knbinf++; 43597 goto nextdir; 43598 } 43599 else if (krem == 2 && 43600 ((sp1inf[ki+1] <= sval2[0] && 43601 sp1inf[ki+3] >= DZERO) || 43602 (sp1inf[ki+1] >= sval2[1] && 43603 sp1inf[ki+3] <= DZERO) || 43604 (sp1inf[ki ] <= sval1[0] && 43605 sp1inf[ki+2] >= DZERO) || 43606 (sp1inf[ki ] >= sval1[1] && 43607 sp1inf[ki+2] <= DZERO) || 43608 (sp2inf[ki+1] <= sval4[0] && 43609 sp2inf[ki+3] >= DZERO) || 43610 (sp2inf[ki+1] >= sval4[1] && 43611 sp2inf[ki+3] <= DZERO) || 43612 (sp2inf[ki ] <= sval3[0] && 43613 sp2inf[ki+2] >= DZERO) || 43614 (sp2inf[ki ] >= sval3[1] && 43615 sp2inf[ki+2] <= DZERO))) 43616 { 43617 /* We were marching out of the patch 43618 but the tangent 43619 is pointing in half step length */ 43620 kstpch = 0; 43621 } 43622 43623 43624 43625 } 43626 } 43627 else 43628 { 43629 /* Divergence or point on wrong side in the parameter 43630 plane or 3-d */ 43631 kstpch = 0; 43632 koutside_resolution = 0; 43633 } 43634 } 43635 else if (kstat==4) 43636 goto nextdir; 43637 } 43638 43639 /* Update step length if new endpoint is to be found */ 43640 43641 if (kstpch==0) 43642 { 43643 if (tdist<DZERO) 43644 { 43645 tnew = tstep/(double)10.0; 43646 } 43647 else 43648 { 43649 tfak = MAX(tdist/aepsge,(double)1.0); 43650 tfak = (double)2.0*pow(tfak,ONE_FOURTH); 43651 tnew = MIN(tstep/(double)2.0,tstep/tfak); 43652 } 43653 if (DEQUAL(tmax+tnew,tmax+tstep)) goto nextdir; 43654 tstep = tnew; 43655 } 43656 } 43657 43658 /* If kstpch= -1,1,3 or 4 then a point is accepted and 43659 snxt1 points to the position and derivatives 43660 of the accepted point. */ 43661 43662 43663 /* Update number of intersection points */ 43664 43665 knbinf++; 43666 43667 /* Copy point and parameter pair descriptions */ 43668 43669 memcopy(spnt1,spntend1,21,DOUBLE); 43670 memcopy(spar1,sparend1,2,DOUBLE); 43671 memcopy(spnt2,spntend2,21,DOUBLE); 43672 memcopy(spar2,sparend2,2,DOUBLE); 43673 43674 /* Update guide point pointers */ 43675 43676 43677 if (kstpch == 1) 43678 { 43679 kguide++; 43680 kgdir = 1; 43681 43682 /* Test if end of guide point array reached */ 43683 43684 if (kguide >= kpoint) goto nextdir; 43685 43686 } 43687 if (kstpch == -1) 43688 { 43689 kguide--; 43690 kgdir = -1; 43691 43692 /* Test if start of guide point array reached */ 43693 43694 if (1 >= kguide) goto nextdir; 43695 } 43696 43697 /* Make new radius of curvature */ 43698 43699 trad = *(s3dinf + 10*knbinf - 1); 43700 tstep = s1311(trad,aepsge,tmax,&kstat); 43701 if (kstat<0) goto error; 43702 43703 /* Test if start point reached, e.g. that the curve is closed */ 43704 43705 if (kstpch == 3) 43706 { 43707 /* Closed curve found */ 43708 43709 goto finished; 43710 } 43711 43712 43713 /* End while loop */ 43714 } 43715 43716 nextdir:; 43717 43718 /* End two step directions */ 43719 } 43720 43721 finished: 43722 43723 /* In certain cases too many marched point may be found. These cases are: 43724 43725 - Open curve and start of marching first guide point 43726 - Open curve and start of marching last guide point 43727 - Closed curve and this found in second marching direction 43728 43729 In these cases some of the found points have to be discarded */ 43730 43731 scorpnt = s3dinf; 43732 scorpr1 = sp1inf; 43733 scorpr2 = sp2inf; 43734 43735 if (kstpch !=3 && kpoint>1) 43736 { 43737 43738 /* Open curve */ 43739 43740 if ( (kstart==1 && kgd1 == kpoint) || 43741 (kstart==kpoint && kgd1==1) ) 43742 { 43743 /* First marching direction traced curve */ 43744 43745 knbinf = knb1; 43746 } 43747 else if ( (kstart==1 && kguide==kpoint) || 43748 (kstart==kpoint && kguide==1) ) 43749 { 43750 /* Second marching direction traced curve */ 43751 43752 scorpnt = scorpnt + 10*(knb1-1); 43753 scorpr1 = scorpr1 + 7*(knb1-1); 43754 scorpr2 = scorpr2 + 7*(knb1-1); 43755 knbinf = knbinf - knb1 + 1; 43756 } 43757 } 43758 else if (kpoint>1) 43759 { 43760 /* Closed curve, correct if result of second marching direction */ 43761 43762 if (kdir != 1) 43763 { 43764 /* Second marching direction, disc ard result of first direction */ 43765 43766 scorpnt = scorpnt + 10*(knb1-1); 43767 scorpr1 = scorpr1 + 7*(knb1-1); 43768 scorpr2 = scorpr2 + 7*(knb1-1); 43769 knbinf = knbinf - knb1 + 1; 43770 } 43771 } 43772 43773 interpolate: 43774 43775 if (knbinf>1) 43776 { 43777 if (igraph == 1 && knbinf > 1) 43778 { 43779 /* Output curve through s6line and s6move */ 43780 43781 s6move(scorpnt); 43782 for (ki=1,sp1=scorpnt+10;ki<knbinf;ki++,sp1+=10) 43783 s6line(sp1); 43784 } 43785 43786 /* A curve is traced out only if at least two points are found */ 43787 43788 if (icur > 0 && knbinf > 1) 43789 { 43790 43791 /* Make 3-D representation of intersection curve */ 43792 43793 kpar = 0; 43794 43795 spar = newarray(knbinf,DOUBLE); 43796 if (spar == SISL_NULL) goto err101; 43797 s1359(scorpnt,aepsge,kdim,knbinf,kpar,spar,&q3dcur,&kstat); 43798 if (kstat < 0) goto error; 43799 43800 /* Set pointer in intcurve object to 3-D curve */ 43801 43802 pinter -> pgeom = q3dcur; 43803 43804 if (icur == 2) 43805 { 43806 /* Make curves in parameter planes */ 43807 43808 kdim = 2; 43809 kpar = 1; 43810 s1359(scorpr1,aepsge,kdim,knbinf,kpar,spar,&qp1cur,&kstat); 43811 if (kstat < 0) goto error; 43812 43813 43814 s1359(scorpr2,aepsge,kdim,knbinf,kpar,spar,&qp2cur,&kstat); 43815 if (kstat < 0) goto error; 43816 43817 /* Set pointers in intcurve object to curves in parameter plane*/ 43818 43819 pinter -> ppar1 = qp1cur; 43820 pinter -> ppar2 = qp2cur; 43821 } 43822 } 43823 } 43824 else if( pinter->ipoint > 1) 43825 { 43826 /* If no points produced on intersection curve */ 43827 43828 s1310_s9constline(psurf1,psurf2,pinter,aepsge,icur,igraph,&kstat); 43829 if (kstat<0) goto error; 43830 if (kstat==0) goto err185; 43831 } 43832 else 43833 goto err185; 43834 43835 if (kdiv == 1) goto war03; 43836 *jstat = 0; 43837 43838 goto out; 43839 43840 /* Iteration can not continue */ 43841 war03: *jstat = 3; 43842 goto out; 43843 43844 /* Error in space allocation */ 43845 err101: *jstat = -101; 43846 s6err("s1310",*jstat,kpos); 43847 goto out; 43848 43849 43850 /* Error in surface description parameter direction does not exist */ 43851 err123: *jstat = -123; 43852 s6err("s1310",*jstat,kpos); 43853 goto out; 43854 43855 43856 /* Error - SISL_NULL pointer was given */ 43857 err150 : 43858 *jstat = -150; 43859 s6err("s1310",*jstat,kpos); 43860 goto out; 43861 43862 /* Only degenerate or singular guide points */ 43863 err185: *jstat = -185; 43864 goto out; 43865 43866 /* Error in lower leve function */ 43867 error: 43868 *jstat = kstat; 43869 s6err("s1310",*jstat,kpos); 43870 goto out; 43871 43872 out: 43873 43874 /* Free allocated space */ 43875 43876 if (sgd1 != SISL_NULL) freearray(sgd1); 43877 if (sgd2 != SISL_NULL) freearray(sgd2); 43878 if (s3dinf != SISL_NULL) freearray(s3dinf); 43879 if (sp1inf != SISL_NULL) freearray(sp1inf); 43880 if (sp2inf != SISL_NULL) freearray(sp2inf); 43881 if (spar != SISL_NULL) freearray(spar); 43882 if (sgpar1 != SISL_NULL) freearray(sgpar1); 43883 if (sgpar2 != SISL_NULL) freearray(sgpar2); 43884 43885 43886 return; 43887 } 43888 43889 //=========================================================================== 43890 void sh1851(SISLSurf * ps1, double epoint[], double enorm[], int idim, 43891 double aepsco, double aepsge,int trackflag, int *jtrack, 43892 SISLTrack *** wtrack,int *jpt, double **gpar, int **pretop, 43893 int *jcrv, SISLIntcurve *** wcurve, int *jsurf, 43894 SISLIntsurf ***wsurf, int *jstat) 43895 //=========================================================================== 43896 { 43897 int kstat = 0; /* Local status varible. */ 43898 int kpos = 0; /* Position of error. */ 43899 int kdim = 1; /* Dimension of space in which the point in the 43900 intersect point and surface problem lies. */ 43901 double *spar = SISL_NULL; /* Dummy array containing parameter values of 43902 second object of single intersection points.*/ 43903 double spoint[1]; /* SISLPoint to intersect with object. */ 43904 SISLSurf *qs = SISL_NULL; /* Pointer to surface in 43905 surface/point intersection.*/ 43906 SISLPoint *qp = SISL_NULL; /* Pointer to point in 43907 surface/point intersection. */ 43908 SISLObject *qo1 = SISL_NULL; /* Pointer to surface in 43909 object/point intersection. */ 43910 SISLObject *qo2 = SISL_NULL; /* Pointer to point in 43911 object/point intersection */ 43912 SISLIntdat *qintdat = SISL_NULL; /* Intersection result */ 43913 int kdeg = 1; /* Implisit descr. to track */ 43914 double simpli[16]; 43915 double snorm[3]; 43916 SISLObject *track_obj=SISL_NULL; 43917 SISLSurf *qkreg=SISL_NULL; /* Input surface ensured k-regularity. */ 43918 43919 /* -------------------------------------------------------- */ 43920 43921 if (ps1->cuopen_1 == SISL_SURF_PERIODIC || 43922 ps1->cuopen_2 == SISL_SURF_PERIODIC) 43923 { 43924 /* Cyclic surface. */ 43925 43926 make_sf_kreg(ps1,&qkreg,&kstat); 43927 if (kstat < 0) goto error; 43928 } 43929 else 43930 qkreg = ps1; 43931 43932 /* 43933 * Create new object and connect surface to object. 43934 * ------------------------------------------------ 43935 */ 43936 43937 if (!(track_obj = newObject (SISLSURFACE))) 43938 goto err101; 43939 track_obj->s1 = ps1; 43940 43941 /* 43942 * Check dimension. 43943 * ---------------- 43944 */ 43945 43946 *jpt = 0; 43947 *jcrv = 0; 43948 *jtrack = 0; 43949 43950 if (idim != qkreg->idim) 43951 goto err106; 43952 43953 /* 43954 * Put surface into plane-equation. 43955 * -------------------------------- 43956 */ 43957 43958 s1329 (qkreg, epoint, enorm, idim, &qs, &kstat); 43959 if (kstat < 0) 43960 goto error; 43961 43962 /* 43963 * Create new object and connect surface to object. 43964 * ------------------------------------------------ 43965 */ 43966 43967 if (!(qo1 = newObject (SISLSURFACE))) 43968 goto err101; 43969 qo1->s1 = qs; 43970 qo1->o1 = qo1; 43971 43972 /* 43973 * Create new object and connect point to object. 43974 * ---------------------------------------------- 43975 */ 43976 43977 if (!(qo2 = newObject (SISLPOINT))) 43978 goto err101; 43979 spoint[0] = DZERO; 43980 if (!(qp = newPoint (spoint, kdim, 1))) 43981 goto err101; 43982 qo2->p1 = qp; 43983 43984 /* 43985 * Find intersections. 43986 * ------------------- 43987 */ 43988 43989 sh1761 (qo1, qo2, aepsge, &qintdat, &kstat); 43990 if (kstat < 0) 43991 goto error; 43992 43993 /* Represent degenerated intersection curves as one point. */ 43994 43995 sh6degen(track_obj,track_obj,&qintdat,aepsge,&kstat); 43996 if (kstat < 0) goto error; 43997 43998 /* BUG BEOrd13026, simpli is now always in use, UJK */ 43999 /* Normalize plane normal */ 44000 44001 (void) s6norm (enorm, 3, snorm, &kstat); 44002 44003 simpli[0] = snorm[0]; 44004 simpli[1] = snorm[1]; 44005 simpli[2] = snorm[2]; 44006 simpli[3] = -s6scpr (epoint, snorm, 3); 44007 44008 44009 /* Create tracks */ 44010 if (trackflag && qintdat) 44011 { 44012 refine_all (&qintdat, track_obj, track_obj, simpli, kdeg, aepsge, &kstat); 44013 if (kstat < 0) 44014 goto error; 44015 } 44016 44017 /* Join periodic curves */ 44018 int_join_per( &qintdat,track_obj, track_obj, simpli, kdeg,aepsge,&kstat); 44019 if (kstat < 0) 44020 goto error; 44021 44022 if (trackflag && qintdat) 44023 { 44024 make_tracks (track_obj, track_obj, kdeg, simpli, 44025 qintdat->ilist, qintdat->vlist, 44026 jtrack, wtrack, aepsge, &kstat); 44027 if (kstat < 0) 44028 goto error; 44029 } 44030 44031 /* 44032 * Express intersections on output format. 44033 * --------------------------------------- 44034 */ 44035 44036 if (qintdat) /* Only if there were intersections found */ 44037 { 44038 hp_s1880 (track_obj, track_obj, kdeg, 44039 2, 0, qintdat, jpt, gpar, &spar, pretop, jcrv, wcurve, jsurf,wsurf,&kstat); 44040 if (kstat < 0) 44041 goto error; 44042 } 44043 44044 /* 44045 * Intersections found. 44046 * -------------------- 44047 */ 44048 44049 *jstat = 0; 44050 goto out; 44051 44052 /* Error in space allocation. */ 44053 44054 err101:*jstat = -101; 44055 s6err ("sh1851", *jstat, kpos); 44056 goto out; 44057 44058 /* Dimensions conflicting. */ 44059 44060 err106:*jstat = -106; 44061 s6err ("sh1851", *jstat, kpos); 44062 goto out; 44063 44064 /* Error in lower level routine. */ 44065 44066 error:*jstat = kstat; 44067 s6err ("sh1851", *jstat, kpos); 44068 goto out; 44069 44070 out: 44071 44072 /* Free allocated space. */ 44073 44074 if (spar) 44075 freearray (spar); 44076 if (qo1) 44077 freeObject (qo1); 44078 if (qo2) 44079 freeObject (qo2); 44080 if (qintdat) 44081 freeIntdat (qintdat); 44082 if (track_obj) 44083 { 44084 track_obj->s1 = SISL_NULL; 44085 freeObject(track_obj); 44086 } 44087 44088 /* Free local surface. */ 44089 if (qkreg != SISL_NULL && qkreg != ps1) freeSurf(qkreg); 44090 44091 return; 44092 } 44093 44094 //=========================================================================== 44095 void freeIntsurf(SISLIntsurf *intsurf) 44096 //=========================================================================== 44097 { 44098 /* Free the arrays if not SISL_NULL. */ 44099 44100 if(intsurf->epar != SISL_NULL) freearray(intsurf->epar); 44101 if(intsurf->const_par != SISL_NULL) freearray(intsurf->const_par); 44102 44103 /* Free the instance pointed at by intsurf. */ 44104 44105 freearray(intsurf); 44106 44107 return; 44108 } 44109 44110 //=========================================================================== 44111 void sh1859 (SISLSurf * ps1, SISLSurf * ps2, double aepsco, double aepsge, 44112 int trackflag, int *jtrack, SISLTrack *** wtrack, 44113 int *jpt, double **gpar1, double **gpar2, int **pretop, 44114 int *jcrv, SISLIntcurve *** wcurve, int *jsurf, 44115 SISLIntsurf *** wsurf, int *jstat) 44116 //=========================================================================== 44117 { 44118 double *nullp = SISL_NULL; 44119 int kstat = 0; /* Local status variable. */ 44120 int kpos = 0; /* Position of error. */ 44121 SISLObject *qo1 = SISL_NULL; /* Object containing first curve in 44122 the intersection. */ 44123 SISLObject *qo2 = SISL_NULL; /* Object containing second curve in 44124 the intersection. */ 44125 SISLIntdat *qintdat = SISL_NULL; /* Structure holding the intersection data. */ 44126 int kdeg=0; /* input to int_join_per. */ 44127 44128 /* 44129 * Check dimensions. 44130 * ----------------- 44131 */ 44132 44133 *jpt = 0; 44134 *jcrv = 0; 44135 *jtrack = 0; 44136 *jsurf = 0; 44137 44138 if (ps1->idim != ps2->idim) 44139 goto err106; 44140 44141 /* 44142 * Create objects and connect surfaces to the objects. 44143 * --------------------------------------------------- 44144 */ 44145 44146 if ((qo1 = newObject (SISLSURFACE)) == SISL_NULL) 44147 goto err101; 44148 qo1->s1 = ps1; 44149 qo1->o1 = qo1; 44150 44151 if ((qo2 = newObject (SISLSURFACE)) == SISL_NULL) 44152 goto err101; 44153 qo2->s1 = ps2; 44154 qo2->o1 = qo2; 44155 44156 /* 44157 * Find intersections. 44158 * ------------------- 44159 */ 44160 44161 sh1761 (qo1, qo2, aepsge, &qintdat, &kstat); 44162 if (kstat < 0) 44163 goto error; 44164 44165 /* Represent degenerated intersection curves as one point. */ 44166 44167 sh6degen(qo1,qo2,&qintdat,aepsge,&kstat); 44168 if (kstat < 0) goto error; 44169 44170 /* Create tracks */ 44171 if (trackflag && qintdat) 44172 { 44173 refine_all( &qintdat,qo1,qo2,nullp,kdeg=0,aepsge,&kstat); 44174 if (kstat < 0) 44175 goto error; 44176 } 44177 44178 /* Join periodic curves */ 44179 int_join_per( &qintdat,qo1,qo2,nullp,kdeg=0,aepsge,&kstat); 44180 if (kstat < 0) 44181 goto error; 44182 44183 /* Create tracks */ 44184 if (trackflag && qintdat) 44185 { 44186 make_tracks (qo1, qo2, 0, nullp, 44187 qintdat->ilist, qintdat->vlist, 44188 jtrack, wtrack, aepsge, &kstat); 44189 if (kstat < 0) 44190 goto error; 44191 } 44192 44193 44194 /* 44195 * Express intersections on output format. 44196 * --------------------------------------- 44197 */ 44198 44199 if (qintdat) /* Only if there were intersections found */ 44200 { 44201 hp_s1880(qo1, qo2, 0, 44202 2,2,qintdat,jpt,gpar1,gpar2,pretop,jcrv,wcurve,jsurf,wsurf,&kstat); 44203 if (kstat < 0) 44204 goto error; 44205 } 44206 44207 44208 /* 44209 * Intersections found. 44210 * -------------------- 44211 */ 44212 44213 *jstat = 0; 44214 goto out; 44215 44216 /* 44217 * Error in space allocation. 44218 * -------------------------- 44219 */ 44220 44221 err101:*jstat = -101; 44222 s6err ("sh1859", *jstat, kpos); 44223 goto out; 44224 44225 /* Dimensions conflicting. */ 44226 44227 err106:*jstat = -106; 44228 s6err ("sh1859", *jstat, kpos); 44229 goto out; 44230 44231 /* Error in lower level routine. */ 44232 44233 error:*jstat = kstat; 44234 s6err ("sh1859", *jstat, kpos); 44235 goto out; 44236 44237 out: 44238 44239 /* 44240 * Free allocated space. 44241 * --------------------- 44242 */ 44243 44244 if (qo1) 44245 { 44246 qo1->s1 = SISL_NULL; 44247 freeObject (qo1); 44248 } 44249 if (qo2) 44250 { 44251 qo2->s1 = SISL_NULL; 44252 freeObject (qo2); 44253 } 44254 if (qintdat) 44255 freeIntdat (qintdat); 44256 44257 /* 44258 * Exit sh1859. 44259 * ----------- 44260 */ 44261 44262 return; 44263 } 44264 44265 //=========================================================================== 44266 void s1770_2D(SISLCurve *pcurve1,SISLCurve *pcurve2,double aepsge, 44267 double astart1,double astart2,double aend1,double aend2, 44268 double anext1,double anext2,double *cpos1,double *cpos2,int *jstat) 44269 //=========================================================================== 44270 { 44271 int kstat = 0; /* Local status variable. */ 44272 int kpos = 0; /* Position of error. */ 44273 int ki; 44274 int kleft1=0,kleft2=0; /* Variables used in the evaluator. */ 44275 int dim; /* Dimension of space the curves lie in */ 44276 int knbit; /* Number of iterations */ 44277 int p_dir; /* Changing direction in par-space. */ 44278 int g_up,ng_up,g_dir; /* Changing direction in geometric space. */ 44279 int order; /* Order of methode. */ 44280 int sing = 0; /* Mark that singularity has ocured. */ 44281 int keep_order = 0; 44282 int max_it = 20; /* Maximum number of iterations. */ 44283 double delta[2]; /* Parameter interval of the curves. */ 44284 double dist; /* Distance between the positions. */ 44285 double prev_dist; /* Previous difference between the curves. */ 44286 double d[2]; /* Clipped distances between old and new par. 44287 value in the two parameter directions. */ 44288 double det; 44289 double c_d[2]; /* Computed distances .... */ 44290 double nc_d[2]; /* New computed distances .... */ 44291 double *c1=SISL_NULL; /* Value of first curve. */ 44292 double *c1_t; /* First derivatiev of curve. */ 44293 double *c1_tt; /* Second derivatiev of curve. */ 44294 double *c2; /* Value of second curve. */ 44295 double *c2_t; /* First derivative of second curve. */ 44296 double *c2_tt; /* Second derivative of second curve. */ 44297 double *diff; /* Difference between the curves. */ 44298 double *prev_diff; /* Previous difference. */ 44299 double *norm; /* Normal to the second curve. */ 44300 double *norm_1; /* Normal to the first curve. */ 44301 double par_val[2]; /* Parameter values */ 44302 double local[48]; 44303 int corr = 0, div2 = 0, quick = *jstat; 44304 44305 if (quick) max_it = 10; /* Reduce requirement on exactness. */ 44306 44307 /* Test input. */ 44308 44309 if (pcurve1->idim != pcurve2->idim) goto err106; 44310 44311 dim = pcurve1 -> idim; 44312 44313 /* Fetch endpoints and the intervals of parameter interval of curves. */ 44314 44315 delta[0] = pcurve1->et[pcurve1->in] - pcurve1->et[pcurve1->ik - 1]; 44316 delta[1] = pcurve2->et[pcurve2->in] - pcurve2->et[pcurve2->ik - 1]; 44317 44318 /* Allocate local used memory */ 44319 44320 if (dim > 3) 44321 { 44322 c1 = newarray(10*dim,double); 44323 if (c1 == SISL_NULL) goto err101; 44324 } 44325 else 44326 c1 = local; 44327 44328 c1_t = c1 + dim; 44329 c1_tt = c1_t + dim; 44330 c2 = c1_tt + dim; 44331 c2_t = c2 + dim; 44332 c2_tt = c2_t + dim; 44333 diff = c2_tt + dim; 44334 prev_diff = diff + dim; 44335 norm = prev_diff + dim; 44336 norm_1 = norm + dim; 44337 44338 44339 44340 /* Initiate variables. */ 44341 44342 44343 par_val[0] = anext1; 44344 par_val[1] = anext2; 44345 44346 for (ki=1; ki<3; ki++) 44347 { 44348 s1770_2D_set_order(ki); 44349 44350 /* Evaluate 0-2.st derivatives of curve 1 */ 44351 44352 if (par_val[0] == aend1) 44353 s1227(pcurve1,1+order,par_val[0],&kleft1,c1,&kstat); 44354 else 44355 s1221(pcurve1,1+order,par_val[0],&kleft1,c1,&kstat); 44356 if (kstat < 0) goto error; 44357 44358 44359 /* Evaluate 0-2.st derivatives of curve 2 */ 44360 44361 if (par_val[1] == aend2) 44362 s1227(pcurve2,1+order,par_val[1],&kleft2,c2,&kstat); 44363 else 44364 s1221(pcurve2,1+order,par_val[1],&kleft2,c2,&kstat); 44365 if (kstat < 0) goto error; 44366 44367 44368 /* Compute the distanse vector and value and the new step. */ 44369 44370 s1770_2D_s9dir(&dist,diff,c_d, c1,c1_t,c1_tt, 44371 c2,c2_t,c2_tt,dim,order,&det,&kstat); 44372 if (kstat < 0) goto error; 44373 if (kstat == 1) /* Singular matrix. */ 44374 { 44375 if (order == 1 && dist > aepsge) goto singular; 44376 else if (order == 1) goto not_singular; 44377 } 44378 else break; 44379 } 44380 44381 /* Correct if we are not inside the parameter intervall. */ 44382 44383 d[0] = c_d[0]; 44384 d[1] = c_d[1]; 44385 norm_1[0] = -c1_t[1]; norm_1[1] = c1_t[0]; 44386 norm[0] = -c2_t[1]; norm[1] = c2_t[0]; 44387 g_up = (s6scpr(diff,norm,dim) >= DZERO) ? 1 : -1; 44388 g_up += ((s6scpr(diff,norm_1,dim) >= DZERO) ? 10 : -10); 44389 s1770_2D_s9corr(d,par_val,astart1,aend1,astart2,aend2,&corr); 44390 44391 prev_dist = dist; 44392 prev_diff[0] = diff[0]; 44393 prev_diff[1] = diff[1]; 44394 44395 /* Iterate to find the intersection point. */ 44396 44397 for (knbit = 0; knbit < max_it; knbit++) 44398 { 44399 s1770_2D_incr2(par_val,d,2); 44400 44401 while (1) 44402 { 44403 /* Evaluate 0-2.st derivatives of curve */ 44404 44405 if (par_val[0] == aend1) 44406 s1227(pcurve1,1+order,par_val[0],&kleft1,c1,&kstat); 44407 else 44408 s1221(pcurve1,1+order,par_val[0],&kleft1,c1,&kstat); 44409 if (kstat < 0) goto error; 44410 44411 if (par_val[1] == aend2) 44412 s1227(pcurve2,1+order,par_val[1],&kleft2,c2,&kstat); 44413 else 44414 s1221(pcurve2,1+order,par_val[1],&kleft2,c2,&kstat); 44415 if (kstat < 0) goto error; 44416 44417 /* Compute the distanse vector and value and the new step. */ 44418 44419 s1770_2D_s9dir(&dist,diff,nc_d,c1,c1_t,c1_tt,c2,c2_t,c2_tt, 44420 dim,order,&det,&kstat); 44421 if (kstat < 0) goto error; 44422 if (kstat == 1) /* Singular matrix. */ 44423 { 44424 sing++; 44425 if (order == 1 && dist > aepsge) goto singular; 44426 else if (order == 1) goto not_singular; 44427 else s1770_2D_set_order(2); /* Change order to 2. */ 44428 } 44429 else 44430 { 44431 norm_1[0] = -c1_t[1]; norm_1[1] = c1_t[0]; 44432 norm[0] = -c2_t[1]; norm[1] = c2_t[0]; 44433 44434 ng_up = (s6scpr(diff,norm,dim) >= DZERO) ? 1 : -1; 44435 ng_up += ((s6scpr(diff,norm_1,dim) >= DZERO) ? 10 : -10); 44436 g_dir = (ng_up+g_up != 0); /* 0 if changed. */ 44437 p_dir = (c_d[0]*nc_d[0] >= DZERO && 44438 c_d[1]*nc_d[1] >= DZERO); /* 0 if changed. */ 44439 44440 if (!order && g_dir && (!p_dir || dist > 0.4*prev_dist) 44441 && !keep_order) 44442 { 44443 if (!quick && div2) div2 = 0; 44444 s1770_2D_set_order(2); 44445 } 44446 else if (order && !g_dir) 44447 { 44448 if (sing && dist > aepsge) goto singular; 44449 else if (sing) goto not_singular; 44450 if (div2) div2 = 0; 44451 s1770_2D_set_order(1); 44452 } 44453 else 44454 { 44455 keep_order = 0; 44456 if (sing) sing = 0; 44457 break; 44458 } 44459 } 44460 } 44461 44462 if (corr) 44463 if (!(p_dir && g_dir)) corr = 0; 44464 44465 if (dist < prev_dist || p_dir) 44466 { 44467 44468 /* Corrigate if we are not inside the parameter interval. */ 44469 44470 g_up = ng_up; 44471 s1770_2D_copy3(d,c_d,nc_d,2); 44472 s1770_2D_s9corr(d, par_val, astart1, aend1, astart2, aend2, &corr); 44473 prev_dist = dist; 44474 s1770_2D_copy2(prev_diff,diff,dim); 44475 44476 /* if (corr > 3) break; */ 44477 44478 if (corr > 2 || 44479 ((fabs(d[0]/MAX(par_val[0],delta[0])) <= REL_COMP_RES) && 44480 (fabs(d[1]/MAX(par_val[1],delta[1])) <= REL_COMP_RES))) break; 44481 if (div2) div2 = 0; 44482 44483 if (corr > 1 && order) 44484 { 44485 keep_order = 1; 44486 s1770_2D_set_order(1); 44487 } 44488 } 44489 44490 else if (corr > 2 || 44491 ((fabs(d[0]/MAX(par_val[0],delta[0])) <= REL_COMP_RES) && 44492 (fabs(d[1]/MAX(par_val[1],delta[1])) <= REL_COMP_RES))) break; 44493 else 44494 { 44495 /* Not converging, corrigate and try again. */ 44496 44497 if (dist > prev_dist && div2 > 5) break; 44498 if (quick && dist > prev_dist && div2 > 3) break; 44499 div2++; 44500 s1770_2D_decr2(par_val,d,2); 44501 d[0] /= (double)2; d[1] /= (double)2; 44502 44503 /* printf("XXX %d, dist=%f, orden=%d\n",div2,dist,order); */ 44504 } 44505 } 44506 44507 /* Iteration stopped, test if point founds found is within resolution */ 44508 44509 44510 if (dim == 2 && fabs(det)<0.1) 44511 { 44512 if (order < 1) 44513 { 44514 s1770_2D_set_order(2); 44515 44516 if (par_val[0] == aend1) 44517 s1227(pcurve1,1+order,par_val[0],&kleft1,c1,&kstat); 44518 else 44519 s1221(pcurve1,1+order,par_val[0],&kleft1,c1,&kstat); 44520 if (kstat < 0) goto error; 44521 44522 if (par_val[1] == aend2) 44523 s1227(pcurve2,1+order,par_val[1],&kleft2,c2,&kstat); 44524 else 44525 s1221(pcurve2,1+order,par_val[1],&kleft2,c2,&kstat); 44526 if (kstat < 0) goto error; 44527 } 44528 goto singular; 44529 } 44530 44531 goto not_singular; 44532 44533 singular: 44534 44535 /* if (!quick && dist > aepsge) */ 44536 if (!quick && dist > aepsge && dim == 2) 44537 { 44538 ki = s1770_2D_s6local_pretop(dist,diff,norm,c1,c1_t,c1_tt, 44539 c2,c2_t,c2_tt,dim,&kstat); 44540 44541 if (kstat < 0) goto error; 44542 if (ki == 0) 44543 { 44544 s1770_2D_s6sekant1(pcurve1,pcurve2,par_val,c_d[0],&dist,aepsge, 44545 astart1,astart2,aend1,aend2,c1,c2,norm,&kstat); 44546 if (kstat < 0) goto error; 44547 44548 } 44549 } 44550 44551 not_singular: 44552 44553 if (dist <= aepsge) 44554 { 44555 *jstat = 1; 44556 } 44557 else 44558 { 44559 44560 s6diff(c1,c2,dim,norm); 44561 if ((PIHALF-s6ang(c1_t,norm,dim)) < ANGULAR_TOLERANCE && 44562 (PIHALF-s6ang(c2_t,norm,dim)) < ANGULAR_TOLERANCE) 44563 *jstat = 3; 44564 else 44565 *jstat = 2; 44566 } 44567 44568 *cpos1 = par_val[0]; 44569 *cpos2 = par_val[1]; 44570 44571 /* Iteration completed. */ 44572 44573 44574 goto out; 44575 44576 /* Error in allocation */ 44577 44578 err101: *jstat = -101; 44579 s6err("s1770_2D",*jstat,kpos); 44580 goto out; 44581 44582 /* Error in input. Conflicting dimensions. */ 44583 44584 err106: *jstat = -106; 44585 s6err("s1770_2D",*jstat,kpos); 44586 goto out; 44587 44588 /* Error in lower level routine. */ 44589 44590 error : *jstat = kstat; 44591 s6err("s1770_2D",*jstat,kpos); 44592 goto out; 44593 44594 out: 44595 if (c1 != local && c1 != SISL_NULL) freearray(c1); 44596 44597 return; 44598 } 44599 44600 //=========================================================================== 44601 void s1770_2D_s9corr(double gd[],double acoef[],double astart1,double aend1, 44602 double astart2,double aend2,int *corr) 44603 //=========================================================================== 44604 { 44605 int lcorr = 0; 44606 if (acoef[0] + gd[0] < astart1) 44607 { 44608 gd[0] = astart1 - acoef[0]; 44609 lcorr=1; 44610 } 44611 else if (acoef[0] + gd[0] > aend1) 44612 { 44613 gd[0] = aend1 - acoef[0]; 44614 lcorr=1; 44615 } 44616 44617 if (acoef[1] + gd[1] < astart2) 44618 { 44619 gd[1] = astart2 - acoef[1]; 44620 lcorr=1; 44621 } 44622 else if (acoef[1] + gd[1] > aend2) 44623 { 44624 gd[1] = aend2 - acoef[1]; 44625 lcorr=1; 44626 } 44627 44628 if (lcorr) 44629 (*corr)++; 44630 else 44631 (*corr) = 0; 44632 } 44633 44634 //=========================================================================== 44635 void s1770_2D_s9dir(double *dist,double diff[],double delta[], 44636 double c1[],double c1_t[],double c1_tt[], 44637 double c2[],double c2_t[],double c2_tt[], 44638 int dim, int second, double* det,int* jstat) 44639 //=========================================================================== 44640 { 44641 int kstat; /* Local status variable. */ 44642 double a1,a2,a3; /* The A matrix, diagonal and A12. */ 44643 double b1,b2; /* The B matrix, diagonal. */ 44644 double A[4],mat[4]; /* Matrix in linear equation to be solved */ 44645 double h[2]; /* Left side in the equation. */ 44646 double x[2]; /* Left side in the equation. */ 44647 double r[2]; /* Left side in the equation. */ 44648 long double ss,aa,xx,bb; /* For use in iterative improvement. */ 44649 int piv[2]; /* Pivotation array */ 44650 int k,k3,j; /* Counters. */ 44651 44652 44653 /* Computing the different vector */ 44654 44655 s6diff(c1,c2,dim,diff); 44656 44657 /* Computing the length of the different vector. */ 44658 44659 *dist = s6length(diff,dim,&kstat); 44660 if (kstat<0) goto error; 44661 44662 if (second || dim != 2) 44663 { 44664 a1 = s6scpr(c1_t,c1_t,dim); 44665 a2 = s6scpr(c2_t,c2_t,dim); 44666 a3 = s6scpr(c1_t,c2_t,dim); 44667 } 44668 44669 if (second) 44670 { 44671 b1 = s6scpr(diff,c1_tt,dim); 44672 b2 = s6scpr(diff,c2_tt,dim); 44673 } 44674 else b1=b2=0.0; 44675 44676 if (second || dim != 2) 44677 { 44678 mat[0] = -a1-b1; mat[1] = a3; 44679 mat[2] = -a3; mat[3] = a2-b2; 44680 44681 h[0] = s6scpr(diff,c1_t,dim); 44682 h[1] = s6scpr(diff,c2_t,dim); 44683 } 44684 else 44685 { 44686 mat[0] = -c1_t[0]; mat[1] = c2_t[0]; 44687 mat[2] = -c1_t[1]; mat[3] = c2_t[1]; 44688 44689 h[0] = diff[0]; 44690 h[1] = diff[1]; 44691 } 44692 44693 for (k=0;k<4;k++) A[k]=mat[k]; 44694 for (k=0;k<2;k++) x[k]=h[k]; 44695 44696 *det = A[0]*A[3]-A[1]*A[2]; 44697 if (fabs(*det) < 1.0e-16) 44698 { 44699 *jstat = 1; 44700 goto out; 44701 } 44702 44703 /* solve the linear 2x2 system */ 44704 44705 s6lufacp(mat,piv,2,&kstat); 44706 if (kstat<0) goto error; 44707 if (kstat == 1) 44708 { 44709 *jstat = 1; 44710 goto out; 44711 } 44712 44713 s6lusolp(mat,x,piv,2,&kstat); 44714 if (kstat<0) goto error; 44715 if (kstat == 1) 44716 { 44717 *jstat = 1; 44718 goto out; 44719 } 44720 44721 for (k=0;k<2;k++) delta[k] = x[k]; 44722 44723 44724 for (k=k3=0; k<2; k++,k3+=2) 44725 { 44726 for (ss=0.0,j=0; j<2; j++) 44727 { 44728 aa = A[j+k3]; 44729 xx = x[j]; 44730 ss += aa*xx; 44731 } 44732 bb = h[k]; 44733 ss = bb-ss; 44734 r[k] = ss; 44735 } 44736 s6lusolp(mat,r,piv,2,&kstat); 44737 if (kstat<0) goto error; 44738 if (kstat == 1) 44739 { 44740 *jstat = 1; 44741 goto out; 44742 } 44743 44744 for (k=0;k<2;k++) delta[k] = x[k] + r[k]; 44745 44746 *jstat = 0; 44747 goto out; 44748 44749 error : 44750 *jstat = kstat; 44751 s6err("s1770_2D_s9dir",*jstat,0); 44752 goto out; 44753 44754 out: 44755 return; 44756 } 44757 44758 //=========================================================================== 44759 void s1770_2D_s6sekant1(SISLCurve *pcurve1,SISLCurve *pcurve2, 44760 double par_val[], double delta, double *dist, double aepsge, 44761 double astart1,double astart2,double aend1,double aend2, 44762 double c1[], double c2[], double norm[], 44763 int *jstat) 44764 //=========================================================================== 44765 { 44766 int ki,kj; /* Counter. */ 44767 int kstat = 0; /* Local status variable. */ 44768 int kpos = 0; /* Position of error. */ 44769 int dim; /* Dimension of space the curves lie in */ 44770 int knbit; /* Number of iterations */ 44771 double cu_val[2]; /* Parameter values on curve. */ 44772 double new_cu_val; /* New parameter value on curve. */ 44773 double *diff; /* Difference vector between curve surface. */ 44774 double y[2],new_y,delta_y;/* Signed distance. */ 44775 SISLPoint *pt=SISL_NULL; /* Point for use in closest point point/surface*/ 44776 int cu1_left = 0; /* Keep left knot information for evaluator. */ 44777 int cu2_left = 0; /* Keep left knot information for evaluator. */ 44778 int shift = 0; /* Mark that the diriction have been changed. */ 44779 44780 *jstat = 0; 44781 44782 /* Test input. */ 44783 44784 if (pcurve1->idim != pcurve2->idim) goto err106; 44785 dim = pcurve1->idim; 44786 diff = c1 + dim; 44787 44788 if ((pt = newPoint(c1,dim,0)) == SISL_NULL) goto err101; 44789 44790 if (delta == 0.0) delta =1e-15; 44791 44792 if (par_val[0] < astart1) par_val[0] = astart1; 44793 else if (par_val[0] > aend1) par_val[0] = aend1; 44794 44795 if ((par_val[0] == astart1 && delta < 0.0) || 44796 (par_val[0] == aend1 && delta > 0.0)) 44797 { 44798 delta = -delta; 44799 shift++; 44800 } 44801 44802 if (fabs(delta) < (aend1 -astart1)/100.0) 44803 { 44804 if (delta < 0.0) 44805 delta = (astart1 - aend1)/100.0; 44806 else 44807 delta = (aend1 - astart1)/100.0; 44808 } 44809 else if (fabs(delta) > (aend1 -astart1)/10.0) 44810 { 44811 if (delta < 0.0) 44812 delta = (astart1 - aend1)/10.0; 44813 else 44814 delta = (aend1 - astart1)/10.0; 44815 } 44816 44817 44818 cu_val[0] = par_val[0]; 44819 s1221(pcurve1,0,cu_val[0],&cu1_left,pt->ecoef,&kstat); 44820 if (kstat < 0) goto error; 44821 s1771(pt,pcurve2,aepsge,astart2,aend2,par_val[1],par_val+1,&kstat); 44822 if (kstat < 0) goto error; 44823 s1221(pcurve2,1,par_val[1],&cu2_left,c2,&kstat); 44824 if (kstat < 0) goto error; 44825 norm[0] = -c2[3]; norm[1] = c2[2]; 44826 for(kj=0; kj<dim; kj++) diff[kj] = c2[kj] - pt->ecoef[kj]; 44827 new_y = s6norm(norm,dim,norm,&kstat); 44828 if (kstat == 0) 44829 { 44830 (*dist)=s6length(diff,dim,&kstat); 44831 new_cu_val = cu_val[0]; 44832 goto out; 44833 } 44834 if (((*dist)=s6length(diff,dim,&kstat)) < aepsge) 44835 { 44836 new_cu_val = cu_val[0]; 44837 goto out; 44838 } 44839 y[0] = s6scpr(norm,diff,dim); 44840 cu_val[1] = cu_val[0] + delta; 44841 if (cu_val[1] < astart1) cu_val[1] = astart1; 44842 else if (cu_val[1] > aend1) cu_val[1] = aend1; 44843 44844 for (ki=0; ki<20; ki++) 44845 { 44846 s1221(pcurve1,0,cu_val[1],&cu1_left,pt->ecoef,&kstat); 44847 if (kstat < 0) goto error; 44848 s1771(pt,pcurve2,aepsge,astart2,aend2,par_val[1],par_val+1,&kstat); 44849 if (kstat < 0) goto error; 44850 s1221(pcurve2,1,par_val[1],&cu2_left,c2,&kstat); 44851 if (kstat < 0) goto error; 44852 norm[0] = -c2[3]; norm[1] = c2[2]; 44853 for(kj=0; kj<dim; kj++) diff[kj] = c2[kj] - pt->ecoef[kj]; 44854 new_y = s6norm(norm,dim,norm,&kstat); 44855 if (kstat == 0) 44856 { 44857 (*dist)=s6length(diff,dim,&kstat); 44858 new_cu_val = cu_val[1]; 44859 goto out; 44860 } 44861 if (((*dist)=s6length(diff,dim,&kstat)) < aepsge) 44862 { 44863 new_cu_val = cu_val[1]; 44864 goto out; 44865 } 44866 y[1] = s6scpr(norm,diff,dim); 44867 new_y = y[1]/y[0]; 44868 if (new_y > 1.0000000000001) 44869 { 44870 if (shift) 44871 { 44872 new_cu_val = cu_val[1]; 44873 goto out; 44874 } 44875 delta = -delta; 44876 cu_val[1] = cu_val[0] + delta; 44877 if (cu_val[1] < astart1) cu_val[1] = astart1; 44878 else if (cu_val[1] > aend1) cu_val[1] = aend1; 44879 shift++; 44880 } 44881 else if (y[0]*y[1] <= 0.0 || new_y < 0.6) break; 44882 else 44883 { 44884 if (cu_val[1]+delta <= aend1 && 44885 cu_val[1]+delta >= astart1) cu_val[1] += delta; 44886 else if (cu_val[1] < aend1) cu_val[1] = aend1; 44887 else if (cu_val[1] > astart1) cu_val[1] = astart1; 44888 else 44889 { 44890 new_cu_val = cu_val[1]; 44891 goto out; 44892 } 44893 } 44894 } 44895 44896 if (ki == 20) 44897 { 44898 *jstat = 2; 44899 new_cu_val = par_val[0]; 44900 goto out; 44901 } 44902 44903 for (knbit=0; knbit < 25; knbit++) 44904 { 44905 delta_y = y[0]-y[1]; 44906 if (fabs(delta_y) < REL_COMP_RES) break; 44907 44908 if (y[0]*y[1] < 0.0 && 44909 (fabs(y[0]) < 6*fabs(y[1]) || fabs(y[1]) < 6*fabs(y[0]))) 44910 new_cu_val = 0.5*(cu_val[1]+cu_val[0]); 44911 else 44912 new_cu_val = cu_val[1] + y[1]*(cu_val[1]-cu_val[0])/delta_y; 44913 if (new_cu_val >= aend1) 44914 { 44915 new_cu_val = aend1; 44916 if (cu_val[0] == aend1 || cu_val[1] == aend1) goto out; 44917 } 44918 else if (new_cu_val <= astart1) 44919 { 44920 new_cu_val = astart1; 44921 if (cu_val[0] == astart1 || cu_val[1] == astart1) goto out; 44922 } 44923 44924 s1221(pcurve1,0,new_cu_val,&cu1_left,pt->ecoef,&kstat); 44925 if (kstat < 0) goto error; 44926 s1771(pt,pcurve2,aepsge,astart2,aend2,par_val[1],par_val+1,&kstat); 44927 if (kstat < 0) goto error; 44928 s1221(pcurve2,1,par_val[1],&cu2_left,c2,&kstat); 44929 if (kstat < 0) goto error; 44930 for(kj=0; kj<dim; kj++) diff[kj] = c2[kj] - pt->ecoef[kj]; 44931 norm[0] = -c2[3]; norm[1] = c2[2]; 44932 new_y = s6norm(norm,dim,norm,&kstat); 44933 if (kstat == 0) 44934 { 44935 (*dist) = s6length(diff,dim,&kstat); 44936 goto out; 44937 } 44938 if (((*dist)=s6length(diff,dim,&kstat)) < aepsge) goto out; 44939 new_y = s6scpr(norm,diff,dim); 44940 44941 if ((y[0] < 0.0 && y[1] > 0.0) || 44942 (y[0] > 0.0 && y[1] < 0.0)) 44943 { 44944 if ((new_y > 0.0 && y[0] > 0.0) || 44945 (new_y < 0.0 && y[0] < 0.0)) 44946 { 44947 cu_val[0] = new_cu_val; 44948 y[0] = new_y; 44949 } 44950 else 44951 { 44952 cu_val[1] = new_cu_val; 44953 y[1] = new_y; 44954 } 44955 } 44956 else 44957 { 44958 if ( y[0] < 0.0 && new_y > 0.0) 44959 { 44960 if (y[0] < y[1]) 44961 { 44962 cu_val[0] = new_cu_val; 44963 y[0] = new_y; 44964 } 44965 else 44966 { 44967 cu_val[1] = new_cu_val; 44968 y[1] = new_y; 44969 } 44970 } 44971 else if ( y[0] > 0.0 && new_y < 0.0) 44972 { 44973 if (y[0] > y[1]) 44974 { 44975 cu_val[0] = new_cu_val; 44976 y[0] = new_y; 44977 } 44978 else 44979 { 44980 cu_val[1] = new_cu_val; 44981 y[1] = new_y; 44982 } 44983 } 44984 else if (y[0] > 0.0) 44985 { 44986 if (y[0] > y[1]) 44987 { 44988 if (new_y >= y[0]) break; 44989 cu_val[0] = new_cu_val; 44990 y[0] = new_y; 44991 } 44992 else 44993 { 44994 if (new_y >= y[1]) break; 44995 cu_val[1] = new_cu_val; 44996 y[1] = new_y; 44997 } 44998 44999 } 45000 else if (y[0] < 0.0) 45001 { 45002 if (y[0] < y[1]) 45003 { 45004 if (new_y <= y[0]) break; 45005 cu_val[0] = new_cu_val; 45006 y[0] = new_y; 45007 } 45008 else 45009 { 45010 if (new_y <= y[1]) break; 45011 cu_val[1] = new_cu_val; 45012 y[1] = new_y; 45013 } 45014 } 45015 } 45016 } 45017 45018 /* Iteration completed. */ 45019 45020 goto out; 45021 45022 /* Error in allocation */ 45023 45024 err101: 45025 *jstat = -101; 45026 s6err("s1770_2D_s6sekant1",*jstat,kpos); 45027 goto out; 45028 45029 /* Error in input. Conflicting dimensions. */ 45030 45031 err106: 45032 *jstat = -106; 45033 s6err("s1770_2D_s6sekant1",*jstat,kpos); 45034 goto out; 45035 45036 /* Error in lower level routine. */ 45037 45038 error : 45039 *jstat = kstat; 45040 s6err("s1770_2D_s6sekant1",*jstat,kpos); 45041 goto out; 45042 45043 out: 45044 par_val[0] = new_cu_val; 45045 if(pt) freePoint(pt); 45046 } 45047 45048 //=========================================================================== 45049 int s1770_2D_s6local_pretop(double dist,double diff[],double normal[], 45050 double c1[],double c1_t[],double c1_tt[], 45051 double c2[],double c2_t[],double c2_tt[], 45052 int dim, int*jstat) 45053 //=========================================================================== 45054 { 45055 int kpos = 0; 45056 int return_val; /* For return value. */ 45057 double l_1,l_2; 45058 double v_1,v_2; 45059 double k_1,k_2; 45060 double r_1,r_2; 45061 45062 45063 *jstat = 0; 45064 45065 if (dim != 2) goto err101; 45066 45067 l_1 = s6scpr(c1_tt,diff,dim); 45068 l_2 = s6scpr(c2_tt,diff,dim); 45069 45070 if (( l_1 < 0.0 && l_2 > 0.0) || (l_1 > 0.0 && l_2 < 0.0)) 45071 { 45072 return_val = 1; 45073 goto out; 45074 } 45075 45076 v_1 = s6scpr(c1_t,c1_t,dim); 45077 v_1 = v_1*sqrt(v_1); 45078 k_1 = fabs(c1_t[0]*c1_tt[1] - c1_tt[0]*c1_t[1]); 45079 if (k_1 < REL_COMP_RES) r_1 = 0.0; 45080 else r_1 = v_1/k_1; 45081 45082 v_2 = s6scpr(c2_t,c2_t,dim); 45083 v_2 = v_2*sqrt(v_2); 45084 k_2 = fabs(c2_t[0]*c2_tt[1] - c2_tt[0]*c2_t[1]); 45085 if (k_2 < REL_COMP_RES) r_2 = 0.0; 45086 else r_2 = v_2/k_2; 45087 45088 45089 if (( l_1 < 0.0 || l_2 < 0.0) && (r_1 > r_2 + dist)) 45090 return_val = 1; 45091 else if (( l_1 > 0.0 || l_2 > 0.0) && (r_2 > r_1 + dist)) 45092 return_val = 1; 45093 else 45094 return_val = 0; 45095 45096 goto out; 45097 45098 45099 /* Error in allocation */ 45100 45101 err101: 45102 *jstat = -101; 45103 s6err("s1770_2D_s6local_pretop",*jstat,kpos); 45104 goto out; 45105 45106 out: 45107 return return_val; 45108 } 45109 45110 //=========================================================================== 45111 void s1221(SISLCurve *pc1,int ider,double ax,int *ileft,double eder[],int *jstat) 45112 //=========================================================================== 45113 { 45114 int kstat=0; /* Local status variable. */ 45115 int kpos=0; /* The position of the error. */ 45116 int kn; /* The number of B-splines, i.e., the dimension of 45117 the spline space associated with the knot 45118 vector. */ 45119 int kk; /* The polynomial order of the curve. */ 45120 int kdim; /* The dimension of the space in which the curve 45121 lies. Equivalently, the number of components 45122 of each B-spline coefficient. */ 45123 int kleft; /* Local version of ileft which is used in order to 45124 avoid the pointer. */ 45125 int kder; /* Local version of ider. Since derivatives of order 45126 higher than kk-1 are all zero, we set 45127 kder = min(kk-1,ider). */ 45128 int kind; /* Type of curve */ 45129 int ki,kj,kih,kjh; /* Control variables in for loops and for stepping 45130 through arrays. */ 45131 int kl,kl1,kl2; /* Control variables in for loops and for stepping 45132 through arrays. */ 45133 double *st; /* Pointer to the first element of the knot vector 45134 of the curve. The knot vector has [kn+kk] 45135 elements. */ 45136 double *scoef; /* Pointer to the first element of the curve's 45137 B-spline coefficients. This is assumed to be an 45138 array with [kn*kdim] elements stored in the 45139 following order: 45140 First the kdim components of the first B-spline 45141 coefficient, then the kdim components of the 45142 second B-spline coefficient and so on. */ 45143 double tt; /* Dummy variable used for holding an array element 45144 in a for loop. */ 45145 double *ebder=SISL_NULL; /* Pointer to an array of dimension [kk*(ider+1)] 45146 which will contain the values and ider first derivatives 45147 of the kk nonzero B-splines at ax. 45148 These are stored in the following order: 45149 First the value, 1. derivative etc. of the 45150 first nonzero B-spline, then the same for the 45151 second nonzero B-spline and so on. */ 45152 double *sder=SISL_NULL; /* Pointer to array used for storage of points, if 45153 non rational sder points to eder, if rational sder 45154 has to be allocated to make room for the homogenous 45155 coordinate */ 45156 45157 /* Copy curve attributes to local parameters. */ 45158 45159 kn = pc1 -> in; 45160 kk = pc1 -> ik; 45161 st = pc1 -> et; 45162 kdim = pc1 -> idim; 45163 kind = pc1 ->ikind; 45164 45165 if (kind == 2 || kind == 4) 45166 { 45167 scoef = pc1 -> rcoef; 45168 kdim +=1; 45169 sder = newarray(kdim*(ider+1),DOUBLE); 45170 if (sder==SISL_NULL) goto err101; 45171 } 45172 else 45173 { 45174 scoef = pc1 -> ecoef; 45175 sder = eder; 45176 } 45177 45178 /* Check the input. */ 45179 45180 if (kdim < 1) goto err102; 45181 45182 if (kk < 1) goto err110; 45183 45184 if (kn < kk) goto err111; 45185 45186 if (st[kk-1] == st[kk] || st[kn-1] == st[kn]) goto err112; 45187 45188 if (ider < 0) goto err178; 45189 45190 if (pc1->ikind == 1 || pc1->ikind == 3) 45191 kder = min(kk-1,ider); 45192 else 45193 kder = ider; 45194 45195 /* Allocate space for B-spline values and derivatives. */ 45196 45197 ebder = newarray(kk*(kder+1),double); 45198 if (ebder == SISL_NULL) goto err101; 45199 45200 /* Set all the elements of sder to 0. */ 45201 45202 for (ki=0; ki<(ider+1)*kdim; ki++) sder[ki] = DZERO; 45203 45204 /* Compute the values and derivatives of the nonzero B-splines and 45205 update ileft if necessary. */ 45206 45207 s1220(st,kk,kn,ileft,ax,kder,ebder,&kstat); 45208 45209 if (kstat < 0) goto error; 45210 45211 kleft = *ileft; 45212 45213 /* Multiply together as indicated above. */ 45214 45215 /* ki steps through the appropriate kk B-spline coefficients while kih steps 45216 through the B-spline value and derivatives for the B-spline given by ki.*/ 45217 45218 kih = 0; 45219 for (ki=kleft-kk+1; ki<=kleft; ki++) 45220 { 45221 45222 /* kj counts through the kder+1 derivatives to be computed. 45223 kjh steps through sder once for each ki to accumulate the contribution 45224 from the different B-splines. 45225 kl1 points to the first component of B-spline coefficient no. ki. */ 45226 45227 kjh = 0; kl1 = kdim*ki; 45228 for (kj=0; kj<=kder; kj++) 45229 { 45230 45231 /* The value of the B-spline derivative is stored in tt while 45232 kl2 steps through the idim components of this B-spline 45233 coefficient. */ 45234 45235 tt = ebder[kih++]; kl2 = kl1; 45236 for (kl=0; kl<kdim; kl++,kjh++,kl2++) 45237 { 45238 sder[kjh] += scoef[kl2]*tt; 45239 } 45240 } 45241 } 45242 45243 /* Free memory. */ 45244 45245 /* If rational curve calculate the derivatives based on derivatives in 45246 homogenous coordinates */ 45247 45248 if (kind == 2 || kind == 4) 45249 { 45250 s6ratder(sder,pc1->idim,ider,eder,&kstat); 45251 if (kstat<0) goto error; 45252 freearray(sder); 45253 } 45254 45255 freearray(ebder); 45256 45257 /* Successful computations. */ 45258 45259 *jstat = 0; 45260 goto out; 45261 45262 /* Not enough memory. */ 45263 err101: *jstat = -101; 45264 s6err("s1221",*jstat,kpos); 45265 goto out; 45266 45267 /* kdim less than 1. */ 45268 err102: *jstat = -102; 45269 s6err("s1221",*jstat,kpos); 45270 goto out; 45271 45272 /* Polynomial order less than 1. */ 45273 err110: *jstat = -110; 45274 s6err("s1221",*jstat,kpos); 45275 goto out; 45276 45277 /* Fewer B-splines than the order. */ 45278 err111: *jstat = -111; 45279 s6err("s1221",*jstat,kpos); 45280 goto out; 45281 45282 /* Error in knot vector. 45283 (The first or last interval of the knot vector is empty.) */ 45284 err112: *jstat = -112; 45285 s6err("s1221",*jstat,kpos); 45286 goto out; 45287 45288 /* Illegal derivative requested. */ 45289 err178: *jstat = -178; 45290 s6err("s1221",*jstat,kpos); 45291 goto out; 45292 45293 /* Error in lower level routine. */ 45294 45295 error: *jstat = kstat; 45296 s6err("s1221",*jstat,kpos); 45297 goto out; 45298 45299 out: return; 45300 } 45301 45302 //=========================================================================== 45303 void s6diff(double e1[],double e2[],int idim,double e3[]) 45304 //=========================================================================== 45305 { 45306 int ki; 45307 for (ki=0;ki<idim;ki++) 45308 e3[ki] = e1[ki] - e2[ki]; 45309 return; 45310 } 45311 45312 //=========================================================================== 45313 double s6norm(double e1[],int idim,double e2[],int *jstat) 45314 //=========================================================================== 45315 { 45316 register int ki; /* Running variable in loop */ 45317 register double tsum=DZERO; /* Dummy variables in summing loop */ 45318 45319 /* If the dimension is 1 the length of the vector is the same as the 45320 * absolute value of the number */ 45321 45322 if (idim == 1) 45323 tsum = fabs(e1[0]); 45324 else 45325 { 45326 for (ki=0;ki<idim;ki++) 45327 tsum += (e1[ki]*e1[ki]); 45328 45329 tsum = sqrt(tsum); 45330 } 45331 45332 if (DNEQUAL(tsum,DZERO)) 45333 for (ki=0;ki<idim;ki++) 45334 e2[ki] = e1[ki]/tsum; 45335 else 45336 { 45337 for (ki=0;ki<idim;ki++) 45338 e2[ki] = DZERO; 45339 goto mes00; 45340 } 45341 goto mes01; 45342 45343 /* Length of vector is zero */ 45344 45345 mes00: 45346 *jstat = 0; 45347 goto out; 45348 45349 /* Length of vector different from zero */ 45350 45351 mes01: 45352 *jstat = 1; 45353 goto out; 45354 out: return(tsum); 45355 } 45356 45357 //=========================================================================== 45358 void s1313(SISLSurf *ps1,double eimpli[],int ideg,double aepsco,double aepsge, 45359 double amax,SISLIntcurve *pintcr,int icur,int igraph,int *jstat) 45360 //=========================================================================== 45361 { 45362 int ki,kj,kl; /* Control variables in for loops */ 45363 int kcont; /* Stop condition for loop */ 45364 int kk,kn; /* Dummy variables */ 45365 int kstpch; /* Status of iteration step */ 45366 int kpoint; /* Number of points in guide curve */ 45367 int kpar1; /* Number of parameter direction in 1st. obj */ 45368 int kpar2; /* Number of parameter direction in 2st. obj */ 45369 int kpar; /* Indicater tellin if S1359 shall make 45370 parametrization or use parametrization 45371 in spar */ 45372 int ktype; /* Type of intersection curve */ 45373 int klfu=0; /* Pointers into knot vectors */ 45374 int klfv=0; /* Pointers into knot vectors */ 45375 int kder = 2; /* Calculate up to second derivatives */ 45376 int kdim = 3; /* The dimension of the space we work in */ 45377 int kfirst = 0; /* Indicator telling if first guide point degenerate */ 45378 int klast = 0; /* Indicator telling if last guide point degenerate */ 45379 int kpos = 0; /* Position of error */ 45380 int kstat,kstat1; /* Status variable returned form routine */ 45381 int kmaxinf=0; /* Number of entries object that can be stored 45382 in s3dinf, sp1inf, sp2inf */ 45383 int knbinf=0; /* Number of entries stored so far on s3dinf, 45384 sp1inf and sp2inf */ 45385 int kstart; /* Start point for iteration among guide pnts*/ 45386 int kguide; /* Current guide point */ 45387 int kdir; /* March direction */ 45388 int kgdir; /* Direction we march guide point vector */ 45389 int krem,krem1,krem2; /* Remember if we step in or out of patch */ 45390 int kbound; /* Dummy variiable */ 45391 int koutside_resolution; /* Flag telling if current seg. outside res. */ 45392 int ksize; /* Number of doubles for storage of derivateves 45393 and normal vector */ 45394 int ksizem3; /* ksize - 3 */ 45395 int kdiv=0; /* Flag remembering if iteration diverged */ 45396 int knb1=0; /* Remember number of points after marching 45397 in first marching direction */ 45398 int kgd1=0; /* Remeber last guide point used in first 45399 marching direction */ 45400 double *scorpnt=SISL_NULL; /* Corrected marching points */ 45401 double *scorpar=SISL_NULL; /* Corrected marching parameter values */ 45402 double smidd[6]; /* Description of midpoint and tangent of 45403 current Bezier segment */ 45404 double tcurstep; /* Current step length */ 45405 double tdist; /* Error at middle of current Bezier segement*/ 45406 double tang; /* Angle error at midpoint Bezier segement */ 45407 double tnew; /* Candidate for new step length */ 45408 double tfak; /* How much is the step length to be reduced */ 45409 double *start; /* Pointer to start of current segment */ 45410 double *st; /* Pointer to knot vector */ 45411 double sval1[2]; /* Limits of parameter plane in first SISLdir */ 45412 double tref1,tref2; /* Reference values for knot vectors */ 45413 double sval2[2]; /* Limits of parameter plane in second SISLdir */ 45414 double tstep; /* Iteration step length */ 45415 double tmax; /* Local maximal step length */ 45416 double tstartstp; /* Start step length */ 45417 double trad; /* Radius of curvature */ 45418 double tval[6]; /* Dummy array in s1331 */ 45419 double *spar=SISL_NULL; /* Parametrization of points in Hermit interp*/ 45420 double spar1[2]; /* Parameter pair of current point surface 1 */ 45421 double spar2[2]; /* Parameter pair of boundarypoint surface 1 */ 45422 double siparmid[2]; /* Parameter value at middle of Bezier segment*/ 45423 double sipar1[2]; /* Parameter pair iteration point surface 1 */ 45424 double simiddpnt[10]; /* Middle point and tangent of segment */ 45425 double simiddpar[7]; /* Parameter value at middle point of segment*/ 45426 double *sgpar1=SISL_NULL; /* Parameter pairs of guide point in surf 1 */ 45427 double *sgpar2=SISL_NULL; /* Parameter pairs of guide point in surf 2 */ 45428 double *sgpar=SISL_NULL; /* guide points used */ 45429 double *sgd1 = SISL_NULL; /* 0-2 derivative of guide point + normal 45430 of first object */ 45431 double spnt1[33]; /* Info on current point in first surface */ 45432 double spnt2[33]; /* Info on boundary point in first surface */ 45433 double sipnt1[33]; /* Info on iteration point in first surface */ 45434 /* For spnt1, sipnt1, the */ 45435 /* information is stored 3-tuppels in the */ 45436 /* following sequence */ 45437 /* Position, (1,0)-der, (0,1)-der, */ 45438 /* (2,0)-der, (1,1)-der, (0,2)-der and normal*/ 45439 /* This is compatible with output of s1421 */ 45440 double snorm1[3]; /* Normal vector of implicit surface */ 45441 double snorm2[3]; /* Normal vector of implicit surface */ 45442 double startg[3]; /* Start tangent of iteration */ 45443 45444 double *snxt1; /* SISLPoint in ps1 we have accepted */ 45445 double *snxp1; /* Parameter value belonging to snxt1 */ 45446 double *s3dinf=SISL_NULL; /* Pointer to array used for storing 3-D position 45447 tangent, curvature and radius of curvature found 45448 during the marching process if possible */ 45449 double *sp1inf=SISL_NULL; /* Pointer to array used for storing position 45450 tangent, curvature and radius of curvature found 45451 in the first parameter plane during the 45452 marching process */ 45453 double start1[33]; /* Description of start point in ps1 */ 45454 double stpar1[2]; /* Parameter pair belonging to start1 */ 45455 double sdum1[3],sdum2[3];/* Dummy vectors */ 45456 double tdum,tdump; /* Dummy variable */ 45457 double *sp1=SISL_NULL; /* Pointer used when moving information */ 45458 double *sp2=SISL_NULL; /* Pointer used when moving information */ 45459 double stdum[10]; /* Dummy array used when moving information */ 45460 double *stang; /* Pointer to tangent of current point */ 45461 double *sptang; /* Pointer to tangent in parameter plane */ 45462 double *spoint; /* Pointer to current point */ 45463 double t1distgd,t2distgd;/* Distances to guide points */ 45464 double tlnorm; /* Length of normal vector */ 45465 double tltan1,tltan2; /* Tangent lengths */ 45466 SISLCurve *q3dcur=SISL_NULL;/* Pointer to 3-D curve */ 45467 SISLCurve *qp1cur=SISL_NULL;/* Pointer to curve in first parameter plane*/ 45468 double sdiffcur[3]; /* Difference between current and previous point found */ 45469 double sdiffprev[3]; /* Difference between previous point and the one before that */ 45470 45471 45472 *jstat = 0; 45473 45474 if (pintcr == SISL_NULL) goto err150; 45475 45476 45477 /* Check if the geometry already has been generated in the topology part. 45478 This will be the case if the geometry is along a constant parameter line. */ 45479 45480 if (pintcr->itype == 9) goto out; 45481 45482 45483 45484 /* Make maximal step length based on box-size of surface */ 45485 45486 sh1992su(ps1,0,aepsge,&kstat); 45487 if (kstat < 0) goto error; 45488 45489 tmax = MAX(ps1->pbox->e2max[0][0] - ps1->pbox->e2min[0][0], 45490 ps1->pbox->e2max[0][1] - ps1->pbox->e2min[0][1]); 45491 tmax = MAX(tmax,ps1->pbox->e2max[0][2] - ps1->pbox->e2min[0][2]); 45492 45493 if (amax>DZERO) tmax = MIN(tmax,amax); 45494 45495 45496 /* If ideg=1,2 or 1001 then only derivatives up to second order 45497 are calculated, then 18 doubles for derivatives and 3 for the 45498 normal vector are to be used for calculation of points in the 45499 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 45500 derivatives up to the third are to be calculated, 45501 thus 30 +3 a total of 33 doubles are to be calculated */ 45502 45503 if (ideg==1003 || ideg==1004 || ideg==1005) 45504 { 45505 kder = 3; 45506 ksize = 33; 45507 } 45508 else 45509 { 45510 ksize = 21; 45511 kder =2; 45512 } 45513 ksizem3 = ksize -3; 45514 45515 45516 /* Find a none singular start point for the marching process */ 45517 45518 kpoint = pintcr->ipoint; 45519 kpar1 = pintcr->ipar1; 45520 kpar2 = pintcr->ipar2; 45521 sgpar1 = pintcr->epar1; 45522 sgpar2 = pintcr->epar2; 45523 ktype = pintcr->itype; 45524 45525 45526 /* Initiate pointers to intersection curve and intersection curve in 45527 parameter plane */ 45528 45529 pintcr -> pgeom = SISL_NULL; 45530 pintcr -> ppar1 = SISL_NULL; 45531 pintcr -> ppar2 = SISL_NULL; 45532 45533 45534 /* Initiate parameter direction boundaries */ 45535 kk = ps1 -> ik1; 45536 kn = ps1 -> in1; 45537 st = ps1 -> et1; 45538 sval1[0] = st[kk-1]; 45539 sval1[1] = st[kn]; 45540 tref1 = (double)3.0*MAX(fabs(*sval1),fabs(*(sval1+1))); 45541 kk = ps1 -> ik2; 45542 kn = ps1 -> in2; 45543 st = ps1 -> et2; 45544 sval2[0] = st[kk-1]; 45545 sval2[1] = st[kn]; 45546 tref2 = (double)3.0*MAX(fabs(*sval2),fabs(*(sval2+1))); 45547 45548 /* Test that first object has 2 parameter direction and second object 0*/ 45549 45550 if (kpar1 == 2 && kpar2 == 0) 45551 { 45552 /* Everithing is ok */ 45553 ; 45554 } 45555 else if (kpar1 == 0 && kpar2 == 2) 45556 { 45557 sgpar1 = sgpar2; 45558 } 45559 else 45560 { 45561 goto err123; 45562 } 45563 45564 /* To support closed curve the first guide point must be copied after 45565 the last guide point */ 45566 45567 if((sgpar=newarray(2*kpoint+2,DOUBLE)) == SISL_NULL) goto err101; 45568 memcopy(sgpar,sgpar1,2*kpoint,DOUBLE); 45569 if (ktype ==2 || ktype == 3) 45570 { 45571 /* Closed curve copy first guide point to end of string of guide points */ 45572 memcopy(sgpar+2*kpoint,sgpar1,2,DOUBLE); 45573 kpoint = kpoint + 1; 45574 } 45575 45576 /* THE POINTS , TANGENT, CURVATURE AND RADIUS OF CURVATURE FOUND DURING 45577 * THE MARCHING PROCESS SHOULD ALL BE STORED IN ARRAYS. ALLOCATE ONE ARRAY 45578 * FOR 3-D INFORMATION AND ONE ARRAY FOR INFORMATION IN THE PARAMETER PLANE. 45579 * THESE ARRAYS ARE GIVEN AN INITIAL CAPACITY OF STORING 100 POINTS WITH 45580 * OTHER INFORMATION. 45581 * IF THEY ARE TOO SHORT THEY WILL BE REALLOCATED AT A LATER STAGE. 45582 * 45583 * SINCE THE MARCHING WILL GO IN BOTH DIRECTIONS WE WILL HAVE TO TURN THE 45584 * INFORMATION FOUND WHEN MARCHING IN NEGATIVE DIRECTION, SO THAT IT CAN 45585 * BE COMBINED WITH THE INFORMATION FOUND WHEN WE ARE MARCHING IN POSITVE 45586 * DIRECTION. 45587 */ 45588 45589 kmaxinf = 100; 45590 s3dinf = newarray(10*kmaxinf,DOUBLE); 45591 if (s3dinf == SISL_NULL) goto err101; 45592 sp1inf = newarray(7*kmaxinf,DOUBLE); 45593 if (sp1inf == SISL_NULL) goto err101; 45594 45595 /* Evaluate 0-1-2nd. derivative + normal of all guide points in the surface, 45596 first allocate arrays for storing the information, check that the points 45597 have a defined normal, and that the combination of the implicit surface 45598 and the surface defines a tangent direction in the curve */ 45599 45600 sgd1 = newarray(ksize*kpoint,DOUBLE); 45601 if (sgd1==SISL_NULL) goto err101; 45602 45603 kpos = 5; 45604 45605 /* Initiate kstart to point at no point */ 45606 45607 kstart = 0; 45608 45609 for (ki=0,kj=0,kl=0 ; ki<kpoint ; ki++,kj+=2,kl+=ksize) 45610 { 45611 s1421(ps1,kder,&sgpar[kj],&klfu,&klfv,&sgd1[kl],&sgd1[kl+ksizem3],&kstat); 45612 if (kstat<0) goto error; 45613 45614 45615 45616 if (ideg == 1003 || ideg == 1004 || ideg == 1005) 45617 { 45618 /* Find length of normal vector and tangent vectors */ 45619 45620 tlnorm = s6length(&sgd1[kl+ksizem3],kdim,&kstat); 45621 tltan1 = s6length(&sgd1[kl+kdim],kdim,&kstat); 45622 tltan2 = s6length(&sgd1[kl+kdim+kdim],kdim,&kstat); 45623 45624 /* The cross product satisifes the follwing conditions: 45625 length(axb) = length(a) length(b) sin(angle(a,b)). 45626 Thus the angle between the two vectors can be found, close to 0 45627 sin(a) is a good approximation of a 45628 */ 45629 if (tlnorm == (double)0.0 || tltan1 ==(double)0.0 || tltan2 == (double)0.0) 45630 tang = (double)0.0; 45631 else 45632 tang = tlnorm/(tltan1*tltan2); 45633 45634 /* Silhouette line calculation no normal can be found in implicit surface 45635 accept point as candidate start point if tang greater tha angular 45636 resolution */ 45637 45638 if (tang >= ANGULAR_TOLERANCE) kstart = ki+1; 45639 } 45640 else 45641 { 45642 /* Make direction of intersection curve */ 45643 45644 s1306(&sgd1[kl],&sgpar[kj],eimpli,ideg,s3dinf,sp1inf,&kstat); 45645 if (kstat < 0) goto error; 45646 45647 45648 /* Remember if start, internal or end point */ 45649 45650 if (kstat != 2) 45651 { 45652 if (ki == 0) kfirst = 1; 45653 else if (ki == kpoint-1) klast = kpoint; 45654 else kstart = ki+1; 45655 } 45656 } 45657 } 45658 45659 /* Check if only degenerate points or singularities exist on the 45660 intersection curve */ 45661 45662 if (kstart == 0) 45663 { 45664 /* No internal nondegenerate point exits, start marching from first 45665 or last point if possible */ 45666 if (kfirst != 0 && ktype != 5 && ktype != 7) kstart = kfirst; 45667 else if (klast != 0 && ktype != 6 && 45668 ktype != 7 && ktype != 3) kstart = klast; 45669 else if (kfirst != 0) kstart = kfirst; 45670 else if (klast != 0) kstart = klast; 45671 else goto interpolate; 45672 } 45673 45674 /* To speed up the marching process when many guide points are given, 45675 remove guide points that are not at the start, end or the start point */ 45676 45677 if (kpoint >2 && (kstart==1 || kstart==kpoint) ) 45678 { 45679 /* No internal guide point necessary, copy last point 45680 to second point */ 45681 45682 memcopy(sgd1+ksize,sgd1+ksize*(kpoint-1),ksize,DOUBLE); 45683 memcopy(sgpar+2,sgpar+2*(kpoint-1),2,DOUBLE); 45684 45685 if (kstart == kpoint) kstart = 2; 45686 kpoint = 2; 45687 } 45688 else if (kpoint>2) 45689 { 45690 /*Internal guide point exists, copy this to second position and 45691 copy end point to third position */ 45692 45693 memcopy(sgd1+ksize,sgd1+ksize*(kstart-1),ksize,DOUBLE); 45694 memcopy(sgpar+2,sgpar+2*(kstart-1),2,DOUBLE); 45695 45696 memcopy(sgd1+2*ksize,sgd1+ksize*(kpoint-1),ksize,DOUBLE); 45697 memcopy(sgpar+4,sgpar+2*(kpoint-1),2,DOUBLE); 45698 45699 kpoint = 3; 45700 kstart = 2; 45701 } 45702 45703 45704 45705 /* Remember description of start point in both surfaces, 45706 * copy point indicated by kstart into spnt1,spar1 */ 45707 45708 memcopy(spnt1,sgd1+ksize*(kstart-1),ksize,DOUBLE); 45709 memcopy(spar1,sgpar+2*(kstart-1),2,DOUBLE); 45710 45711 /* Make position, unit tangent, curvature and radius of curvature for 45712 * start point of iteration, store them in the arrays just allocated */ 45713 45714 kpos = 10; 45715 s1306(spnt1,spar1,eimpli,ideg,s3dinf,sp1inf,&kstat); 45716 45717 if (kstat<0) goto error; 45718 45719 /* Test if singular point reached */ 45720 45721 if (kstat == 2) goto war03; 45722 45723 /* Remember start tangent */ 45724 memcopy(startg,s3dinf+3,3,DOUBLE); 45725 45726 45727 /* Iterate intersection point down to the intersection curve */ 45728 45729 tstep = DZERO; 45730 s9iterimp(s3dinf,spnt1,spar1,ps1,eimpli,ideg,tstep, 45731 aepsge,sipnt1,sipar1,&kstat); 45732 if (kstat < 0) goto error; 45733 45734 if (kstat==0 && s6dist(spnt1,sipnt1,3) > aepsge) 45735 { 45736 45737 /* Nonsingular point found and adjustment greater than aepsge, 45738 copy result of iteration into spnt1,spar1 */ 45739 45740 memcopy(spnt1,sipnt1,ksize,DOUBLE); 45741 memcopy(spar1,sipar1,2,DOUBLE); 45742 } 45743 45744 /* Remember start point */ 45745 45746 if (kstat==0) 45747 { 45748 memcopy(start1,sipnt1,ksize,DOUBLE); 45749 memcopy(stpar1,sipar1,2,DOUBLE); 45750 } 45751 else 45752 { 45753 memcopy(start1,spnt1,ksize,DOUBLE); 45754 memcopy(stpar1,spar1,2,DOUBLE); 45755 } 45756 45757 /* Make position, unit tangent, curvature and radius of curvature for 45758 start point of iteration, store them in the arrays just allocated */ 45759 45760 kpos = 10; 45761 s1306(start1,stpar1,eimpli,ideg,s3dinf,sp1inf,&kstat); 45762 45763 if (kstat<0) goto error; 45764 45765 45766 /* Test if singular point reached */ 45767 45768 if (kstat == 2) goto war03; 45769 45770 /* Remember that start point is already stored */ 45771 45772 knbinf = 1; 45773 45774 /* Make step length based on 3-D radius of curvature, tolerances and 45775 maks step length */ 45776 45777 kpos = 20; 45778 tstep = s1311(s3dinf[9],aepsge,tmax,&kstat); 45779 if (kstat<0) goto error; 45780 tstartstp = tstep; 45781 45782 /* STEP IN BOTH DIRECTIONS FROM THE FOUND START POINT */ 45783 45784 /* Indicate that direction in guide point array not determined */ 45785 kguide = kstart; 45786 kgdir = 0; 45787 45788 for (kdir=1;kdir<3;kdir++) 45789 { 45790 45791 if (kdir == 2) 45792 { 45793 45794 /* Remember result of marching in first direction */ 45795 45796 knb1 = knbinf; 45797 kgd1 = kguide; 45798 45799 45800 /* If the previous step direction made no points then knbinf==0. To 45801 enable the marching we start from the same start point as the 45802 previous step direction, thus in this case knbinf should be 1. */ 45803 45804 knbinf = MAX(1,knbinf); 45805 45806 /* We now step in the second step direction. Turn the sequence of 45807 the points found as well as change tangent directions */ 45808 45809 /* First interchange 3-D info */ 45810 45811 for (sp1=s3dinf,sp2=s3dinf+10*(knbinf-1) ; sp1<sp2 ; sp1+=10,sp2-=10) 45812 { 45813 memcopy(stdum,sp1, 10,DOUBLE); 45814 memcopy(sp1 ,sp2, 10,DOUBLE); 45815 memcopy(sp2 ,stdum,10,DOUBLE); 45816 } 45817 45818 for (sp1=s3dinf+3;sp1<s3dinf+10*knbinf;sp1+=10) 45819 { 45820 sp1[0] = - sp1[0]; 45821 sp1[1] = - sp1[1]; 45822 sp1[2] = - sp1[2]; 45823 } 45824 45825 /* Then interchange info in parameter plane */ 45826 45827 for (sp1=sp1inf,sp2=sp1inf+7*(knbinf-1) ; sp1<sp2 ; sp1+=7,sp2-=7) 45828 { 45829 memcopy(stdum,sp1 ,7,DOUBLE); 45830 memcopy(sp1 ,sp2 ,7,DOUBLE); 45831 memcopy(sp2 ,stdum,7,DOUBLE); 45832 } 45833 45834 for (sp1=sp1inf+2;sp1<sp1inf+7*knbinf;sp1+=7) 45835 { 45836 sp1[0] = - sp1[0]; 45837 sp1[1] = - sp1[1]; 45838 sp1[2] = - sp1[2]; 45839 } 45840 45841 /* Turn direction of remembered start tangent */ 45842 45843 for (ki=0;ki<3;ki++) 45844 startg[ki] = -startg[ki]; 45845 45846 45847 /* Update spnt1 and spar1 to have the start point values */ 45848 45849 memcopy(spnt1,start1,ksize,DOUBLE); 45850 memcopy(spar1,stpar1,2,DOUBLE); 45851 45852 /* Turn the direction we march the guide point vector, and set current 45853 guide point to kstart */ 45854 45855 kgdir = -kgdir; 45856 kguide = kstart; 45857 45858 /* Update step length */ 45859 tstep = tstartstp; 45860 } 45861 45862 45863 stang = s3dinf + 10*(knbinf-1) + 3; 45864 kpos = 30; 45865 45866 /* Step direction ok, perform marching until stop condition reached */ 45867 45868 kcont = 1; 45869 45870 while (kcont) 45871 { 45872 45873 /* We must make sure that we are not stepping past a guide point. 45874 * Thus if we get close to a guide point, make sure that we step 45875 * through this. The direction we travers the guide point array 45876 * might not have been determined yet. Thus we have to test in 45877 * both directions in guide point array. 45878 * 45879 * Remember how we step in the varaible kstpch: 45880 * kstpch = -1 : Try to step to previous guide point 45881 * kstpch = 0 : Try not to step through guide point 45882 * kstpch = 1 : Try to step to next guide point 45883 * kstpch = 3 : Step to start point and stop marching 45884 * kstpch = 4 : Don't step through guide point, candidate 45885 * end point of segement found in iteration loop 45886 */ 45887 45888 45889 kstpch = 0; 45890 stang = s3dinf + 10*(knbinf-1) + 3; 45891 sptang = sp1inf + 7*(knbinf-1) + 2; 45892 if (kgdir >=0) 45893 { 45894 45895 /* We are stepping in positive direction in guide point vector 45896 * calculate distance to next guide point. If the guide point 45897 * is lying closer than the step length to the current point 45898 * we should step directly to this point provided that the cross 45899 * product of the normal vectors at current point and at the 45900 * guide point have the same direction, e.g. that their scalar 45901 * product is positiv */ 45902 45903 t1distgd = (double)2.0*tstep; 45904 if (kguide < kpoint) 45905 { 45906 /* Decide if we should step through the guide point */ 45907 45908 kpos = 40; 45909 t1distgd = s9adsimp(spnt1,spar1,eimpli,ideg, 45910 &sgd1[kguide*ksize], 45911 &sgpar[kguide*2], 45912 stang,sptang,tstep,&kstat); 45913 if (kstat < 0) goto error; 45914 if (kstat == 1) 45915 { 45916 /* Step through guide point remember this */ 45917 45918 kstpch = 1; 45919 snxt1 = sgd1 + ksize*kguide; 45920 snxp1 = sgpar + 2*kguide; 45921 tstep = MIN(tstep,t1distgd); 45922 } 45923 } 45924 } 45925 45926 if (kgdir <=0) 45927 { 45928 45929 /* We are stepping in negative direction in guide point vector 45930 * calculate distance to previous guide point. If the guide point 45931 * is lying closer than the step length to the current point 45932 * we should step directly to this point provided that the cross 45933 * product of the normal vectors at current point and at the 45934 * guide point have the same direction, e.g. that their scalar 45935 * product is positiv */ 45936 45937 if (1 < kguide) 45938 { 45939 /* Decide if we should step through the guide point */ 45940 45941 kpos = 50; 45942 t2distgd = s9adsimp(spnt1,spar1,eimpli,ideg, 45943 &sgd1[(kguide-2)*ksize],&sgpar[2*kguide-4], 45944 stang,sptang,tstep,&kstat); 45945 if (kstat<0) goto error; 45946 if ((kstat == 1 &&kstpch == 0) || 45947 (kstat == 1 && kstpch == 1 && t2distgd < t1distgd)) 45948 { 45949 /* Step through guide point remember this */ 45950 45951 kstpch = -1; 45952 snxt1 = sgd1 + ksize*(kguide-2); 45953 snxp1 = sgpar + 2*(kguide-2); 45954 tstep = MIN(tstep,t2distgd); 45955 } 45956 } 45957 } 45958 45959 /* Check if we step through the start point. Should only be done if at least 45960 three points found in this marching direction, a full closed curve will 45961 require 6 segments. */ 45962 if ((kdir==1 && knbinf>3) || (kdir==2 && knbinf>knb1+3)) 45963 { 45964 45965 kpos = 60; 45966 tdum = s9adsimp(spnt1,spar1,eimpli,ideg,start1,stpar1,stang,sptang, 45967 tstep,&kstat); 45968 if (kstat < 0) goto error; 45969 if (kstat == 1) 45970 { 45971 /* Step to start point remember this */ 45972 45973 kstpch = 3; 45974 snxt1 = start1; 45975 snxp1 = stpar1; 45976 tstep = MIN(tstep,tdum); 45977 } 45978 } 45979 45980 45981 /* At this stage kstpch=0 if we have not reached a guide point or 45982 if we have not reached the start point of the iteration. 45983 45984 Now we want to find a Bezier segement that is lying within the 45985 geometric tolerance that is approximating the intersection curve. 45986 If a guide point is reached (kstpch=-1 or 1), then we have a 45987 candidate for the end point of the Bezier segement. If the start 45988 point is reached (kstpch=3) then we also have a candidate end point 45989 for the segment. 45990 45991 The next loop use kstpch to indicate if we have a candidate 45992 end point for the segment: 45993 45994 kstpch==0 : No candidate end point exists 45995 kstpch!=0 : Candidate end point exists 45996 45997 45998 To indicate if the segement is within the resolution we 45999 use koutside_resolution: 46000 46001 koutside_resolution==0 : Segment outside resolution 46002 koutside_resolution!=0 : Segment inside resolution 46003 */ 46004 46005 koutside_resolution = 0; 46006 46007 /* Make sure that there is enough space for one more point */ 46008 if (knbinf>=kmaxinf) 46009 { 46010 kmaxinf = kmaxinf + 100; 46011 s3dinf = increasearray(s3dinf,((3*kdim+1)*kmaxinf),DOUBLE); 46012 if (s3dinf==SISL_NULL) goto err101; 46013 sp1inf = increasearray(sp1inf,7*kmaxinf,DOUBLE); 46014 if (sp1inf==SISL_NULL) goto err101; 46015 } 46016 46017 /* Make description of candidate endpoint if it exists and store it */ 46018 46019 if (kstpch != 0) 46020 { 46021 s1306(snxt1,snxp1,eimpli,ideg,s3dinf+10*knbinf, 46022 sp1inf+7*knbinf,&kstat); 46023 if (kstat<0) goto error; 46024 46025 /* It is allowed to jump on to a singular point */ 46026 46027 /* Make sure that the tangents of previous and the 46028 candidate end point point in the same direction */ 46029 46030 if (knbinf>0) 46031 tdum = s6scpr(s3dinf+10*(knbinf-1)+3, 46032 s3dinf+10*knbinf+3,kdim); 46033 else 46034 tdum = s6scpr(startg,s3dinf+3,kdim); 46035 46036 46037 if (tdum < DZERO) 46038 { 46039 /* Change tangent direction 3-D and in parameter plane */ 46040 sp1 = s3dinf + 10*knbinf + 3; 46041 sp1[0] = -sp1[0]; 46042 sp1[1] = -sp1[1]; 46043 sp1[2] = -sp1[2]; 46044 sp1 = sp1inf + 7*knbinf + 2; 46045 sp1[0] = -sp1[0]; 46046 sp1[1] = -sp1[1]; 46047 } 46048 46049 /* Copy the candidate point to spnt2 and spar2 */ 46050 46051 memcopy(spnt2,snxt1,ksize,DOUBLE); 46052 memcopy(spar2,snxp1,2,DOUBLE); 46053 } 46054 46055 while (kstpch == 0 || koutside_resolution == 0) 46056 { 46057 if (kstpch!=0) 46058 { 46059 /* Candidate end point exist, iterate to find point close 46060 to the midpoint of the Bezier segement */ 46061 46062 46063 /* Decide if Hermit shape acceptable and find position and 46064 tangent at midpoint of segment */ 46065 46066 start = s3dinf + 10*(knbinf-1); 46067 46068 s1361(start,start+10,3,smidd,smidd+3,&kstat); 46069 if (kstat<0) goto error; 46070 46071 tcurstep = DZERO; 46072 spoint = smidd; 46073 } 46074 else 46075 { 46076 46077 /* Iterate to find end point of segment */ 46078 46079 /* ITERATE by intersecting the two surface and the plane 46080 * defined by current point (s3dinf), the tangent (s3dinf+3) 46081 * and the step length */ 46082 46083 spoint = s3dinf + 10*(knbinf-1); 46084 tcurstep = tstep; 46085 } 46086 46087 /* Perform the actual iteration */ 46088 46089 kpos = 70; 46090 s9iterimp(spoint,spnt1,spar1,ps1,eimpli,ideg,tcurstep, 46091 aepsge,sipnt1,sipar1,&kstat); 46092 if (kstat < 0) goto error; 46093 46094 /* Initiate distance between midpoint and iteration point 46095 to -1 to enable detection of divergence */ 46096 46097 tdist = -1; 46098 46099 /* Check if iteration has converged */ 46100 46101 if (kstat == 2) 46102 { 46103 /* Iteration has diverged, half step length if possible, 46104 find new endpoint of segement. */ 46105 46106 kstpch = 0; 46107 koutside_resolution = 0; 46108 } 46109 else if(kstat == 1 && kstpch != 0) 46110 { 46111 /* The point found is closer to the input point than 46112 the relative computer resolution or is a singular point. 46113 Half step length if possible, find new endpoint of 46114 segement. */ 46115 46116 kstpch = 0; 46117 koutside_resolution = 0; 46118 } 46119 else if (kstpch!=0) 46120 { 46121 46122 46123 /* Make description of intersection point */ 46124 46125 s1306(sipnt1,sipar1,eimpli,ideg,simiddpnt,simiddpar,&kstat); 46126 if (kstat<0) goto error; 46127 46128 if (kstat != 2) 46129 { 46130 /* We iterated to find midpoint of segment, test if 46131 it is within resolution */ 46132 46133 tdist = s6dist(simiddpnt,smidd,3); 46134 tang = s6ang(simiddpnt+3,smidd+3,3); 46135 } 46136 46137 /* If point is singular or not within resolution a new 46138 Hermit segment has to be made */ 46139 46140 if (kstat == 2 || (fabs(tdist) > aepsge || 46141 (fabs(tang) > ANGULAR_TOLERANCE && tstep>aepsge))) 46142 { 46143 kstpch = 0; 46144 koutside_resolution = 0; 46145 } 46146 else 46147 { 46148 /* Segment within tolerance. 46149 * Check that the relationship between the two surfaces 46150 * has not been interchanged, by making the cross product 46151 * of the normal vectors in current point and the point 46152 * found by iteration. Then make the scalar product of 46153 * these vectors. If the scalar product is negative then 46154 * we have either jumped to another branch or passed a 46155 * singularity, iterprete this as the iteration has diverged 46156 * In addition we don't want the direction of the tangents 46157 * change to much. We set a limit of approximately 41 degrees 46158 * by testing on a cosin value of 0.75 46159 * Make normal vectors in implicit surface for both points 46160 * Make also sure that the curve in the parameter plane 46161 * does not turn more than 90 degrees. 46162 */ 46163 46164 s1331(spnt1,eimpli,ideg,-1,tval,snorm1,&kstat); 46165 if (kstat < 0) goto error; 46166 s1331(spnt2,eimpli,ideg,-1,tval,snorm2,&kstat); 46167 if (kstat < 0) goto error; 46168 46169 if(ideg == 1003 || ideg == 1004 || ideg == 1005) 46170 { 46171 tdum = s6scpr(snorm1,snorm2,kdim); 46172 } 46173 else 46174 { 46175 s6crss(spnt1+ksizem3,snorm1,sdum1); 46176 (void)s6norm(sdum1,kdim,sdum1,&kstat); 46177 if (kstat < 0) goto error; 46178 s6crss(sipnt1+ksizem3,snorm2,sdum2); 46179 (void)s6norm(sdum2,kdim,sdum2,&kstat); 46180 if (kstat < 0) goto error; 46181 tdum = s6scpr(sdum1,sdum2,kdim); 46182 } 46183 46184 s6diff(spar2,spar1,2,sdum1); 46185 tdump = s6scpr(sdum1,sp1inf+7*(knbinf-1)+2,2); 46186 /* The test below was added to detect the case when the 46187 normal of the parametric surface turns */ 46188 if(s6scpr(spnt1+ksizem3,sipnt1+ksizem3,kdim) < 0.0) 46189 { 46190 tdum = -tdum; 46191 } 46192 if (tdum == DZERO) 46193 { 46194 double tl1,tl2; 46195 46196 /* If one of the tangents have zero length, accept 46197 segment */ 46198 46199 tl1 = s6length(sdum1,kdim,&kstat); 46200 tl2 = s6length(sdum2,kdim,&kstat); 46201 46202 if (tl1 == DZERO || tl2 == DZERO) 46203 koutside_resolution = 1; 46204 else 46205 { 46206 /* Find new end point of segment */ 46207 koutside_resolution = 0; 46208 kstpch = 0; 46209 } 46210 46211 } 46212 else if (tdum <= (double)0.75 || tdump <= (double)0.0) 46213 { 46214 /* Find new end point of segment */ 46215 koutside_resolution = 0; 46216 kstpch = 0; 46217 } 46218 else 46219 { 46220 koutside_resolution = 1; 46221 } 46222 } 46223 } 46224 else 46225 { 46226 /* We iterated to find end point of segment, update pointer */ 46227 46228 memcopy(spnt2,sipnt1,ksize,DOUBLE); 46229 memcopy(spar2,sipar1,2,DOUBLE); 46230 46231 s1306(sipnt1,sipar1,eimpli,ideg,s3dinf+10*knbinf, 46232 sp1inf+7*knbinf,&kstat); 46233 if (kstat<0) goto error; 46234 46235 /* Make sure that the tangents of previous and the new point 46236 point in the same direction, singular end point allowed */ 46237 46238 if (knbinf>0) 46239 tdum = s6scpr(s3dinf+10*(knbinf-1)+3, 46240 s3dinf+10*knbinf+3,kdim); 46241 else 46242 tdum = s6scpr(startg,s3dinf+3,kdim); 46243 46244 46245 if (tdum < DZERO) 46246 { 46247 /* Change tangent direction 3-D and in parameter plane */ 46248 sp1 = s3dinf + 10*knbinf + 3; 46249 sp1[0] = -sp1[0]; 46250 sp1[1] = -sp1[1]; 46251 sp1[2] = -sp1[2]; 46252 sp1 = sp1inf + 7*knbinf + 2; 46253 sp1[0] = -sp1[0]; 46254 sp1[1] = -sp1[1]; 46255 } 46256 46257 /* Indicate that end point accepted */ 46258 46259 kstpch = 4; 46260 koutside_resolution = 0; 46261 } 46262 46263 /* If the segment is accepted. check if we cross the 46264 boundary of the patch */ 46265 46266 if (kstpch !=0 && koutside_resolution == 1) 46267 { 46268 46269 /* Check if curve between start and endpoint cross the 46270 boundary */ 46271 46272 memcopy(siparmid,sipar1,2,double); 46273 46274 s1305(spar1,spar2,sval1,sval2,&kbound,sipar1,&kstat); 46275 if (kstat<0) goto error; 46276 46277 46278 if(kstat==0 || kstat==4) 46279 { 46280 /* Set pointer to tangents at start point */ 46281 ki = 7*(knbinf-1)+2; 46282 46283 if( (DEQUAL(spar1[1]+tref2,sval2[0]+tref2) && sp1inf[ki+1]>DZERO) || 46284 (DEQUAL(spar1[1]+tref2,sval2[1]+tref2) && sp1inf[ki+1]<DZERO) || 46285 (DEQUAL(spar1[0]+tref1,sval1[0]+tref1) && sp1inf[ki]>DZERO) || 46286 (DEQUAL(spar1[0]+tref1,sval1[1]+tref1) && sp1inf[ki]<DZERO) 46287 46288 ) 46289 kstat = 1; 46290 } 46291 krem1 = kstat; 46292 46293 46294 46295 /* Check if curve between start and midd point cross the 46296 boundary */ 46297 46298 s1305(spar1,siparmid,sval1,sval2,&kbound,sipar1,&kstat); 46299 if (kstat<0) goto error; 46300 krem2 = kstat; 46301 46302 /* We now have the following cases: 46303 kstat == 0 : Line between epar1 and epar2 outside, 46304 If this happens when kdir=1, then 46305 just forget the start point. If it happens 46306 when kdir=2, then we just stop the marching. 46307 kstat == 1 : Line between epar1 and epar2 inside. 46308 Continue iteration. 46309 kstat == 2 : We step out of the patch. Clip to the edge 46310 of the patch. Update start point. 46311 kstat == 3 : We step into the patch. Clip to the edge 46312 of the patch. Update endpoint 46313 kstat == 4 : We go from the boundary and out. Try next 46314 iteration direction. 46315 46316 */ 46317 if (krem1==0 || krem2==0) 46318 { 46319 if (kdir==1) knbinf--; 46320 goto nextdir; 46321 } 46322 else if ((krem1 !=1 || krem2 !=1) && krem1 != 4 && krem2 !=4) 46323 { 46324 46325 /* If we clip to the boundary, forget any guide point 46326 identified. The actual action is dependent on which 46327 of the points spar2 or sipar1 indicates the crossing */ 46328 46329 kstat1 = 0; 46330 if (krem2==2 || krem2==3) 46331 { 46332 s9clipimp(spar1,siparmid,ps1,eimpli,ideg,sval1,sval2, 46333 aepsge,sipnt1,sipar1,&kstat); 46334 if (kstat<0) goto error; 46335 if (krem2==3 && kstat==1) kstpch = 4; 46336 kstat1 = kstat; 46337 krem = krem2; 46338 } 46339 if (kstat1 != 1 && (krem1 ==2 || krem1==3)) 46340 { 46341 s9clipimp(spar1,spar2,ps1,eimpli,ideg,sval1,sval2, 46342 aepsge,sipnt1,sipar1,&kstat); 46343 if (kstat<0) goto error; 46344 if (krem1==3 && kstat==1) kstpch = 4; 46345 kstat1 = kstat; 46346 krem = krem1; 46347 } 46348 46349 if (kstat1 == 1) 46350 { 46351 /* Check that the relationship between the two surfaces 46352 * has not been interchanged, by making the cross product 46353 * of the normal vectors in current point and the point 46354 * found by iteration. Then make the scalar product of 46355 * these vectors. If the scalar product is negative then 46356 * we have either jumped to another branch or passed a 46357 * singularity, iterprete this as the iteration has diverged 46358 * In addition we don't want the direction of the tangents 46359 * change to much. We set a limit of approximately 41 degrees 46360 * by testing on a cosin value of 0.75 46361 * Make normal vectors in implicit surface for both points 46362 * Make also sure that the curve in the parameter plane 46363 * does not turn more than 90 degrees. 46364 */ 46365 46366 s1331(spnt1,eimpli,ideg,-1,tval,snorm1,&kstat); 46367 if (kstat < 0) goto error; 46368 s1331(sipnt1,eimpli,ideg,-1,tval,snorm2,&kstat); 46369 if (kstat < 0) goto error; 46370 46371 if(ideg == 1003 || ideg == 1004 || ideg == 1005) 46372 { 46373 tdum = s6scpr(snorm1,snorm2,kdim); 46374 } 46375 else 46376 { 46377 s6crss(spnt1+ksizem3,snorm1,sdum1); 46378 (void)s6norm(sdum1,kdim,sdum1,&kstat); 46379 if (kstat < 0) goto error; 46380 s6crss(sipnt1+ksizem3,snorm2,sdum2); 46381 (void)s6norm(sdum2,kdim,sdum2,&kstat); 46382 if (kstat < 0) goto error; 46383 46384 tdum = s6scpr(sdum1,sdum2,kdim); 46385 } 46386 46387 46388 /* Check that sipar1 lies on the same side of spar1 as 46389 the tangent at spar1 */ 46390 46391 s6diff(sipar1,spar1,2,sdum1); 46392 tdump = s6scpr(sdum1,sp1inf+7*(knbinf-1)+2,2); 46393 /* The test below was added to detect the case when the 46394 normal of the parametric surface turns */ 46395 if(s6scpr(spnt1+ksizem3,sipnt1+ksizem3,kdim) < 0.0) 46396 { 46397 tdum = -tdum; 46398 } 46399 } 46400 46401 /* An intersection point has only been found when kstat==1 46402 */ 46403 if (kstat1==1 && tdump >= (double)0.0 && tdum > (double)0.75) 46404 { 46405 /* If krem=3 we step into the patch, if krem=2 we step 46406 out of the patch */ 46407 46408 if (krem==2 || krem==3) 46409 { 46410 /* Since we clip, set kstpch=0, no guide point reached */ 46411 46412 /* If krem==3 we step into the patch, make new 46413 start point of segment */ 46414 46415 if (krem==3) knbinf--; 46416 46417 memcopy(spnt2,sipnt1,ksize,DOUBLE); 46418 memcopy(spar2,sipar1,2,DOUBLE); 46419 46420 s1306(sipnt1,sipar1,eimpli,ideg,s3dinf+10*knbinf, 46421 sp1inf+7*knbinf,&kstat); 46422 if (kstat<0) goto error; 46423 46424 46425 /* Make sure that the tangents of previous and the new point 46426 point in the same direction */ 46427 46428 if (knbinf>0) 46429 tdum = s6scpr(s3dinf+10*(knbinf-1)+3, 46430 s3dinf+10*knbinf+3,kdim); 46431 else 46432 tdum = s6scpr(startg,s3dinf+3,kdim); 46433 46434 46435 if (tdum < DZERO) 46436 { 46437 /* Change tangent direction 3-D and in 46438 parameter plane 46439 */ 46440 sp1 = s3dinf + 10*knbinf + 3; 46441 sp1[0] = -sp1[0]; 46442 sp1[1] = -sp1[1]; 46443 sp1[2] = -sp1[2]; 46444 sp1 = sp1inf + 7*knbinf + 2; 46445 sp1[0] = -sp1[0]; 46446 sp1[1] = -sp1[1]; 46447 } 46448 46449 /* If the new end point tangent points out go 46450 to next direction */ 46451 46452 ki = 7*knbinf; 46453 if( (sp1inf[ki+1] <= sval2[0] && sp1inf[ki+3] < DZERO) || 46454 (sp1inf[ki+1] >= sval2[1] && sp1inf[ki+3] > DZERO) || 46455 (sp1inf[ki ] <= sval1[0] && sp1inf[ki+2] < DZERO) || 46456 (sp1inf[ki ] >= sval1[1] && sp1inf[ki+2] > DZERO) ) 46457 { 46458 knbinf++; 46459 goto nextdir; 46460 } 46461 else if(krem == 2 && 46462 ((sp1inf[ki+1] <= sval2[0] && sp1inf[ki+3] >= DZERO) || 46463 (sp1inf[ki+1] >= sval2[1] && sp1inf[ki+3] <= DZERO) || 46464 (sp1inf[ki ] <= sval1[0] && sp1inf[ki+2] >= DZERO) || 46465 (sp1inf[ki ] >= sval1[1] && sp1inf[ki+2] <=DZERO) )) 46466 { 46467 /* We were marching out ou the patch, but the tangent 46468 points in, half step length */ 46469 kstpch = 0; 46470 } 46471 46472 46473 46474 } 46475 } 46476 46477 else 46478 { 46479 /* Divergence or point on wrong side in the parameter 46480 plane or 3-d */ 46481 kstpch = 0; 46482 koutside_resolution = 0; 46483 } 46484 } 46485 else if (krem1==4 || krem2==4) 46486 goto nextdir; 46487 46488 } 46489 46490 /* Update step length if new endpoint is to be found */ 46491 46492 if (kstpch==0) 46493 { 46494 if (tdist<DZERO) 46495 { 46496 tnew = tstep/(double)10.0; 46497 } 46498 else 46499 { 46500 tfak = MAX(tdist/aepsge,(double)1.0); 46501 tfak = (double)2.0*pow(tfak,ONE_FOURTH); 46502 tnew = MIN(tstep/(double)2.0,tstep/tfak); 46503 } 46504 if (DEQUAL(tmax+tnew,tmax+tstep)) goto nextdir; 46505 tstep = tnew; 46506 } 46507 } 46508 46509 /* If kstpch= -1,1,3 or 4 then a point is accepted and 46510 * snxt1 points to the position and derivatives 46511 * of the accepted point. */ 46512 46513 /* If we have accepted a segment pointing in the opposite 46514 * direction of the previous segment, something very wrong 46515 * has happened, and we go out with an error. */ 46516 if (knbinf >= 2) 46517 { 46518 s6diff(s3dinf + 10*knbinf, s3dinf + 10*(knbinf - 1), kdim, sdiffcur); 46519 s6diff(s3dinf + 10*(knbinf-1), s3dinf + 10*(knbinf - 2), kdim, sdiffprev); 46520 if (s6scpr(sdiffcur, sdiffprev ,kdim) < DZERO) 46521 { 46522 /* We have a problem with degeneracy, quit now. */ 46523 goto war03; 46524 } 46525 /* printf("%7.13f\n", s6scpr(sdiffcur, sdiffprev ,kdim)); */ 46526 } 46527 46528 /* Update number of intersection points */ 46529 46530 knbinf++; 46531 46532 /* Copy point and parameter pair descriptions */ 46533 46534 memcopy(spnt1,spnt2,ksize,DOUBLE); 46535 memcopy(spar1,spar2,2,DOUBLE); 46536 46537 /* Update guide point pointers */ 46538 46539 if (kstpch == 1) 46540 { 46541 kguide++; 46542 kgdir = 1; 46543 46544 /* Test if end of guide point array reached */ 46545 46546 if (kguide >= kpoint) goto nextdir; 46547 46548 } 46549 if (kstpch == -1) 46550 { 46551 kguide--; 46552 kgdir = -1; 46553 46554 /* Test if start of guide point array reached */ 46555 46556 if (1 >= kguide) goto nextdir; 46557 } 46558 46559 /* Make new radius of curvature */ 46560 46561 trad = *(s3dinf + 10*knbinf - 1); 46562 tstep = s1311(trad,aepsge,tmax,&kstat); 46563 if (kstat<0) goto error; 46564 46565 /* Test if start point reached, e.g. that the curve is closed */ 46566 46567 if (kstpch == 3) 46568 { 46569 /* Closed curve found */ 46570 goto finished; 46571 } 46572 46573 46574 /* End while loop */ 46575 } 46576 /* End inside */ 46577 /* INSIDE TEST REMOVED BECAUSE OF CHANGED STRATEGY 46578 } 46579 */ 46580 nextdir:; 46581 /* End two step directions */ 46582 } 46583 46584 finished: 46585 46586 /* In certain cases too many marched point may be found. These cases are: 46587 46588 - Open curve and start of marching first guide point 46589 - Open curve and start of marching last guide point 46590 - Closed curve and this found in second marching direction 46591 46592 In these cases some of the found points have to be discarded */ 46593 46594 scorpnt = s3dinf; 46595 scorpar = sp1inf; 46596 46597 if (kstpch !=3 && kpoint>1) 46598 { 46599 46600 /* Open curve */ 46601 46602 if ( (kstart==1 && kgd1 == kpoint) || 46603 (kstart==kpoint && kgd1==1) ) 46604 { 46605 /* First marching direction traced curve */ 46606 46607 knbinf = knb1; 46608 } 46609 else if ( (kstart==1 && kguide==kpoint) || 46610 (kstart==kpoint && kguide==1) ) 46611 { 46612 /* Second marching direction traced curve */ 46613 46614 scorpnt = scorpnt + 10*(knb1-1); 46615 scorpar = scorpar + 7*(knb1-1); 46616 knbinf = knbinf - knb1 + 1; 46617 } 46618 } 46619 else if (kpoint>1) 46620 { 46621 /* Closed curve, correct if result of second marching direction */ 46622 46623 if (kdir != 1) 46624 { 46625 /* Second marching direction, disc ard result of first direction */ 46626 46627 scorpnt = scorpnt + 10*(knb1-1); 46628 scorpar = scorpar + 7*(knb1-1); 46629 knbinf = knbinf - knb1 + 1; 46630 } 46631 } 46632 46633 /* A curve is traced out only if at least two points are found, if less 46634 points found try to pick out constant parameter line */ 46635 46636 interpolate: 46637 46638 if (knbinf>1) 46639 { 46640 if (igraph == 1 && knbinf > 1) 46641 { 46642 /* Output curve through s6line and s6move */ 46643 46644 s6move(scorpnt); 46645 for (ki=1,sp1=scorpnt+10;ki<knbinf;ki++,sp1+=10) 46646 s6line(sp1); 46647 } 46648 46649 if (icur > 0 && knbinf >1) 46650 { 46651 46652 /* Make 3-D representation of intersection curve */ 46653 46654 kpar = 0; 46655 46656 /* We allocate space for parametrization array */ 46657 46658 46659 spar = newarray(knbinf,DOUBLE); 46660 if (spar == SISL_NULL) goto err101; 46661 46662 s1359(scorpnt,aepsge,kdim,knbinf,kpar,spar,&q3dcur,&kstat); 46663 if (kstat < 0) goto error; 46664 46665 /* Set pointer in intcurve object to 3-D curve */ 46666 pintcr -> pgeom = q3dcur; 46667 46668 if (icur == 2) 46669 { 46670 /* Make curve in parameter plane */ 46671 46672 kdim = 2; 46673 kpar = 1; 46674 s1359(scorpar,aepsge,kdim,knbinf,kpar,spar,&qp1cur,&kstat); 46675 if (kstat < 0) goto error; 46676 46677 46678 /* Set pointersin intcurve object to curves in parameter plane */ 46679 if (kpar1 ==2) 46680 { 46681 pintcr -> ppar1 = qp1cur; 46682 } 46683 else 46684 { 46685 pintcr -> ppar2 = qp1cur; 46686 } 46687 } 46688 } 46689 } 46690 /* Dont use s9constline for the silhouette curves -- it won't work! */ 46691 else if(pintcr->ipoint > 1 && ideg < 1003) 46692 { 46693 46694 /* If no points produced on intersection curve */ 46695 46696 s1313_s9constline(ps1,eimpli,ideg,aepsge,pintcr, 46697 icur,igraph,&kstat); 46698 if (kstat<0) goto error; 46699 if (kstat==0) goto err185; 46700 } 46701 else 46702 goto err185; 46703 46704 if (kdiv==1) goto war03; 46705 *jstat = 0; 46706 46707 goto out; 46708 46709 /* Iteration can not continue */ 46710 war03: *jstat = 3; 46711 goto out; 46712 46713 /* Error in space allocation */ 46714 err101: *jstat = -101; 46715 s6err("s1313",*jstat,kpos); 46716 goto out; 46717 46718 /* Error in surface description parameter direction does not exist */ 46719 err123: *jstat = -123; 46720 s6err("s1313",*jstat,kpos); 46721 goto out; 46722 46723 46724 /* Error - SISL_NULL pointer was given */ 46725 err150 : 46726 *jstat = -150; 46727 s6err("s1313",*jstat,kpos); 46728 goto out; 46729 46730 46731 /* Only degenerate or singular guide points */ 46732 err185: *jstat = -185; 46733 goto out; 46734 46735 46736 /* Error in lower leve function */ 46737 error: 46738 *jstat = kstat; 46739 s6err("s1313",*jstat,kpos); 46740 goto out; 46741 46742 out: 46743 46744 /* Free allocated space */ 46745 46746 if (sgpar != SISL_NULL) freearray(sgpar); 46747 if (sgd1 != SISL_NULL) freearray(sgd1); 46748 if (s3dinf != SISL_NULL) freearray(s3dinf); 46749 if (sp1inf != SISL_NULL) freearray(sp1inf); 46750 if (spar != SISL_NULL) freearray(spar); 46751 46752 46753 return; 46754 } 46755 46756 46757 //=========================================================================== 46758 void sh1761 (SISLObject * po1, SISLObject * po2, double aepsge, 46759 SISLIntdat ** pintdat, int *jstat) 46760 //=========================================================================== 46761 { 46762 int kstat = 0; /* Local status variable. */ 46763 int kpos = 0; /* Position of error. */ 46764 int ktotal = 1; /* Make totally expanded box. */ 46765 int kxintercept = (*jstat == 202); /* Extra interception */ 46766 double tpar; /* Help variable used for parameter value 46767 and geometric distance. */ 46768 SISLObject *po1_kreg=SISL_NULL; /* Pointer to first object converted to 46769 k-regular basis. */ 46770 SISLObject *po2_kreg=SISL_NULL; /* Pointer to second object converted to 46771 k-regular basis. */ 46772 SISLIntpt *qt = SISL_NULL; /* Temporary intersection point. */ 46773 SISLEdge *qedge[2]; /* Edges for use in s1862(). */ 46774 SISLIntdat *qintdat = SISL_NULL; /* Intdat for use in recurson. */ 46775 46776 double *nullp = SISL_NULL; 46777 int idummy; 46778 46779 qedge[0] = qedge[1] = SISL_NULL; /* PFU - to fix memory leak */ 46780 46781 46782 /* Ensure K-regularity on B-spline basis ________________*/ 46783 if (po1->iobj == SISLCURVE) 46784 { 46785 if (po1->c1->cuopen == SISL_CRV_PERIODIC) 46786 { 46787 if ((po1_kreg = newObject (SISLCURVE)) == SISL_NULL) 46788 goto err101; 46789 make_cv_kreg(po1->c1, &po1_kreg->c1, &kstat); 46790 if (kstat < 0) goto error; 46791 } 46792 else po1_kreg = po1; 46793 46794 } 46795 else if (po1->iobj == SISLSURFACE) 46796 { 46797 if (po1->s1->cuopen_1 == SISL_CRV_PERIODIC || 46798 po1->s1->cuopen_2 == SISL_CRV_PERIODIC) 46799 { 46800 if ((po1_kreg = newObject (SISLSURFACE)) == SISL_NULL) 46801 goto err101; 46802 make_sf_kreg(po1->s1, &po1_kreg->s1, &kstat); 46803 if (kstat < 0) goto error; 46804 } 46805 else po1_kreg = po1; 46806 } 46807 else po1_kreg = po1; 46808 46809 46810 46811 if (po2->iobj == SISLCURVE) 46812 { 46813 if (po2->c1->cuopen == SISL_CRV_PERIODIC) 46814 { 46815 if ((po2_kreg = newObject (SISLCURVE)) == SISL_NULL) 46816 goto err101; 46817 make_cv_kreg(po2->c1, &po2_kreg->c1, &kstat); 46818 if (kstat < 0) goto error; 46819 } 46820 else po2_kreg = po2; 46821 } 46822 else if (po2->iobj == SISLSURFACE) 46823 { 46824 if (po2->s1->cuopen_1 == SISL_CRV_PERIODIC || 46825 po2->s1->cuopen_2 == SISL_CRV_PERIODIC) 46826 { 46827 if ((po2_kreg = newObject (SISLSURFACE)) == SISL_NULL) 46828 goto err101; 46829 make_sf_kreg(po2->s1, &po2_kreg->s1, &kstat); 46830 if (kstat < 0) goto error; 46831 } 46832 else po2_kreg = po2; 46833 } 46834 46835 else po2_kreg = po2; 46836 46837 /* End of ensure K-regularity on B-spline basis ________________*/ 46838 46839 46840 if (po1_kreg->iobj == SISLPOINT && po2_kreg->iobj == SISLPOINT) 46841 { 46842 /* Control the dimension of the two points. */ 46843 46844 if (po1_kreg->p1->idim != po2_kreg->p1->idim) 46845 goto err106; 46846 46847 /* Computing the distanse beetween the points. */ 46848 46849 tpar = s6dist (po1_kreg->p1->ecoef, po2_kreg->p1->ecoef, po1_kreg->p1->idim); 46850 46851 if (tpar <= aepsge) 46852 { 46853 /* PFU, moved to top to fix memory leak: SISLIntpt *qt = SISL_NULL; */ 46854 46855 *jstat = 1; /* Mark intersection found. */ 46856 /* UJK , newi */ 46857 /* Making intersection point. */ 46858 46859 qt = hp_newIntpt (0, &tpar, DZERO, SI_ORD, 46860 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 46861 0, 0, nullp, nullp); 46862 if (qt == SISL_NULL) 46863 goto err101; 46864 46865 /* Uppdating pintdat. */ 46866 46867 sh6idnpt (pintdat, &qt, 1, &kstat); 46868 if (kstat < 0) 46869 goto error; 46870 46871 qt = SISL_NULL; /* PFU - to fix memory leak */ 46872 } 46873 else 46874 *jstat = 0; 46875 } 46876 else 46877 { 46878 /* Test if intersection is possible (perform box-test). */ 46879 46880 sh1790 (po1_kreg, po2_kreg, ktotal, aepsge, &kstat); 46881 if (kstat < 0) 46882 goto error; 46883 46884 /* We may have four different values on kstat. 46885 kstat = 0 : Intersection not possible. 46886 kstat = 1 : The two boxes overlap. 46887 kstat = 2 : The two "bezier" boxes is just touching. 46888 kstat = 3 : The two boxes is both inside a microbox of aepsge. */ 46889 46890 46891 if (kstat) 46892 { 46893 int ki, kj; /* Counters. */ 46894 int kedg = 0; /* Number of parameter direction. */ 46895 SISLObject *qo1 = SISL_NULL; /* Help pointer. */ 46896 SISLObject *qo2 = SISL_NULL; /* Help pointer. */ 46897 46898 /* PFU, moved to top to fix memory leak: 46899 * SISLEdge *qedge[2]; 46900 * SISLIntdat *qintdat = SISL_NULL; 46901 */ 46902 46903 qintdat = SISL_NULL; /* PFU to fix memory leak. */ 46904 qedge[0] = qedge[1] = SISL_NULL; 46905 *jstat = 0; 46906 46907 for (kj = 0, qo1 = po1_kreg, qo2 = po2_kreg; kj < 2; kj++, qo1 = po2_kreg, qo2 = po1_kreg) 46908 if (qo1->iobj == SISLPOINT) 46909 qedge[kj] = SISL_NULL; /* Not necessary to compute edge intersection.*/ 46910 else if (qo1->iobj == SISLCURVE) 46911 { 46912 if ((qedge[kj] = newEdge (2)) == SISL_NULL) 46913 goto err101; 46914 46915 for (ki = 0; ki < 2; ki++) 46916 { 46917 if (qo1->edg[ki] == SISL_NULL) 46918 { 46919 if ((qo1->edg[ki] = newObject (SISLPOINT)) == SISL_NULL) 46920 goto err101; 46921 46922 /* Pick out end point from a curve. */ 46923 46924 s1438 (qo1->c1, ki, &(qo1->edg[ki]->p1), &tpar, &kstat); 46925 if (kstat < 0) 46926 goto error; 46927 } 46928 else 46929 tpar = (ki == 0 ? qo1->c1->et[qo1->c1->ik - 1] : 46930 qo1->c1->et[qo1->c1->in]); 46931 46932 /* Recursiv computing of end intersection. */ 46933 46934 sh1761 (kj == 0 ? qo1->edg[ki] : qo2, kj == 0 ? qo2 : qo1->edg[ki], 46935 aepsge, &qintdat, &kstat); 46936 if (kstat < 0) 46937 goto error; 46938 46939 46940 if (kstat) 46941 { 46942 *jstat = 1; /* Mark intersection found. */ 46943 46944 /* Put intersection found on edges into pintdat. */ 46945 46946 46947 /* Get parameter border values of qo2. */ 46948 46949 /* UJK , newi */ 46950 sh1782 (po1_kreg, po2_kreg, aepsge, qintdat, kedg, tpar, 46951 pintdat, &idummy, &kstat); 46952 if (kstat < 0) 46953 goto error; 46954 46955 46956 /* Uppdate edge structure. */ 46957 s6idedg (po1_kreg, po2_kreg, kj + 1, 1, tpar, *pintdat, 46958 &qedge[kj]->prpt[ki], &qedge[kj]->ipoint, &kstat); 46959 if (kstat < 0) 46960 goto error; 46961 } 46962 46963 if (qintdat != SISL_NULL) 46964 freeIntdat (qintdat); 46965 qintdat = SISL_NULL; 46966 } 46967 kedg++; 46968 } 46969 46970 else if (qo1->iobj == SISLSURFACE) 46971 { 46972 int kpar; /* Parameter direction. */ 46973 46974 if ((qedge[kj] = newEdge (4)) == SISL_NULL) 46975 goto err101; 46976 46977 for (ki = 0; ki < 4; ki++) 46978 { 46979 if (qo1->edg[ki] == SISL_NULL) 46980 { 46981 if ((qo1->edg[ki] = newObject (SISLCURVE)) == SISL_NULL) 46982 goto err101; 46983 46984 /* Pick out edge curve from a surface. */ 46985 46986 s1435 (qo1->s1, ki, &(qo1->edg[ki]->c1), &tpar, &kstat); 46987 if (kstat < 0) 46988 goto error; 46989 } 46990 else 46991 tpar = (ki == 0 ? qo1->s1->et2[qo1->s1->ik2 - 1] : 46992 (ki == 1 ? qo1->s1->et1[qo1->s1->in1] : 46993 (ki == 2 ? qo1->s1->et2[qo1->s1->in2] : 46994 qo1->s1->et1[qo1->s1->ik1 - 1]))); 46995 46996 /* Recursiv computing of edge intersection. */ 46997 46998 if (kj == 0) 46999 sh1761 (qo1->edg[ki], qo2, aepsge, &qintdat, &kstat); 47000 else 47001 sh1761 (qo2, qo1->edg[ki], aepsge, &qintdat, &kstat); 47002 if (kstat < 0) 47003 goto error; 47004 47005 47006 if (kstat) 47007 { 47008 *jstat = 1; /* Mark intersection found. */ 47009 47010 /* Compute Parameter direction of edge. */ 47011 47012 kpar = ((ki == 0 || ki == 2) ? 2 : 1); 47013 47014 47015 /* Put intersection found on edges into pintdat. */ 47016 47017 /* UJK , newi */ 47018 sh1782 (po1_kreg, po2_kreg, aepsge, qintdat, kpar + kedg - 1, tpar, 47019 pintdat, &idummy, &kstat); 47020 if (kstat < 0) 47021 goto error; 47022 47023 47024 /* Uppdate edge structure. */ 47025 s6idedg (po1_kreg, po2_kreg, kj + 1, kpar, tpar, *pintdat, 47026 &qedge[kj]->prpt[ki], &qedge[kj]->ipoint, &kstat); 47027 if (kstat < 0) 47028 goto error; 47029 } 47030 47031 if (qintdat != SISL_NULL) 47032 freeIntdat (qintdat); 47033 qintdat = SISL_NULL; 47034 } 47035 kedg += 2; 47036 } 47037 47038 else 47039 goto err121; 47040 47041 /* Before we enter internal intersection and subdivision we 47042 initiate pointers to top level objects. */ 47043 47044 if (po1_kreg->o1 == SISL_NULL) 47045 po1_kreg->o1 = po1_kreg; 47046 if (po2_kreg->o1 == SISL_NULL) 47047 po2_kreg->o1 = po2_kreg; 47048 47049 /* Find the intersections in the inner of the object. */ 47050 47051 /* NEWI (ujk) Must treat helppoint on edges */ 47052 if (qedge[0] != SISL_NULL) 47053 freeEdge (qedge[0]); 47054 qedge[0] = SISL_NULL; 47055 if (qedge[1] != SISL_NULL) 47056 freeEdge (qedge[1]); 47057 qedge[1] = SISL_NULL; 47058 47059 if (po1_kreg->iobj == SISLPOINT) 47060 qedge[0] = SISL_NULL; 47061 else if ((qedge[0] = newEdge (2 * po1_kreg->iobj)) == SISL_NULL) 47062 goto err101; 47063 47064 if (po2_kreg->iobj == SISLPOINT) 47065 qedge[1] = SISL_NULL; 47066 else if ((qedge[1] = newEdge (2 * po2_kreg->iobj)) == SISL_NULL) 47067 goto err101; 47068 47069 sh6idalledg (po1_kreg, po2_kreg, *pintdat, qedge, &kstat); 47070 if (kstat < 0) 47071 goto error; 47072 47073 kstat = (kxintercept) ? 202 : 0; 47074 sh1762 (po1_kreg, po2_kreg, aepsge, pintdat, qedge, &kstat); 47075 if (kstat < 0) 47076 goto error; 47077 else if (kstat) 47078 *jstat = 1; 47079 47080 47081 /* Free the edges used in s1762. */ 47082 47083 if (qedge[0] != SISL_NULL) 47084 freeEdge (qedge[0]); 47085 qedge[0] = SISL_NULL; 47086 if (qedge[1] != SISL_NULL) 47087 freeEdge (qedge[1]); 47088 qedge[1] = SISL_NULL; 47089 47090 47091 /* UJK, edge reduction rules */ 47092 sh6edgred (po1_kreg, po2_kreg, (*pintdat), &kstat); 47093 47094 /* Organize the list in pintdat. */ 47095 sh6idlis (po1_kreg, po2_kreg, pintdat, aepsge, &kstat); 47096 if (kstat < 0) 47097 goto error; 47098 47099 /* Convert any degenerate intersection curves (Intlists) 47100 to intersection points (Intpts). 47101 This may be necessary when 47102 either of the intersection objects po1_kreg and po2_kreg 47103 are parametrically degenerate. */ 47104 /* 47105 sh6degen(po1_kreg,po2_kreg,pintdat,aepsge,&kstat); 47106 if (kstat < 0) goto error; 47107 */ 47108 if (qintdat) freeIntdat(qintdat); /* PFU */ 47109 qintdat = SISL_NULL; /* - to fix memory leak */ 47110 } 47111 else 47112 *jstat = 0; 47113 } 47114 47115 goto out; 47116 47117 /* Error in space allocation. */ 47118 47119 err101:*jstat = -101; 47120 s6err ("sh1761", *jstat, kpos); 47121 goto out; 47122 47123 /* Error. Dimensions conflicting. */ 47124 47125 err106:*jstat = -106; 47126 s6err ("sh1761", *jstat, kpos); 47127 goto out; 47128 47129 /* Error. Kind of object does not exist. */ 47130 47131 err121:*jstat = -121; 47132 s6err ("sh1761", *jstat, kpos); 47133 goto out; 47134 47135 /* Error in lower order routine. */ 47136 47137 error:*jstat = kstat; 47138 s6err ("sh1761", *jstat, kpos); 47139 goto out; 47140 47141 out: 47142 /* Kill kreg temporary geometry */ 47143 if (po1_kreg && po1_kreg != po1) 47144 { 47145 freeObject(po1_kreg); 47146 po1_kreg = SISL_NULL; 47147 } 47148 47149 if (po2_kreg && po2_kreg != po2) 47150 { 47151 freeObject(po2_kreg); 47152 po2_kreg = SISL_NULL; 47153 47154 } 47155 47156 if (qt) freeIntpt(qt); /* PFU */ 47157 if (qintdat) freeIntdat(qintdat); /* - to fix memory leak. */ 47158 if (qedge[0]) freeEdge(qedge[0]); 47159 if (qedge[1]) freeEdge(qedge[1]); 47160 47161 } 47162 47163 //=========================================================================== 47164 void int_join_per (SISLIntdat ** pintdat, 47165 SISLObject * po1, 47166 SISLObject * po2, 47167 double eimpli[], 47168 int ideg, 47169 double aepsge, 47170 int *jstat) 47171 //=========================================================================== 47172 { 47173 int kstat; /* Local status variable. */ 47174 int kpos = 0; /* Position of error. */ 47175 int ki=0, kj=0; /* Counter */ 47176 SISLIntpt *pcurr; /* to traverse list of points. */ 47177 SISLIntpt *pnext; /* to traverse list of points. */ 47178 SISLIntpt *pother; /* to traverse list of points. */ 47179 int logtest=0; /* used for constant crv test */ 47180 47181 SISLIntpt *pfirst_1; /* First point in a list, periodicity */ 47182 SISLIntpt *pfirst_2; /* First point in a list, periodicity */ 47183 SISLIntpt *plast_1; /* Last point in a list, periodicity */ 47184 SISLIntpt *plast_2; /* Last point in a list, periodicity */ 47185 double *curve_val_3d = SISL_NULL; /* Pos, tang and curvature ,3d */ 47186 double *curve_val_2d_1= SISL_NULL; /* Pos, tang and curvature ,2d */ 47187 double *curve_val_2d_2= SISL_NULL; /* Pos, tang and curvature ,2d */ 47188 double delta_par[4]; /* Delta vector in par space, periodicity */ 47189 double *delta_1=delta_par; /* Delta vector in par space, periodicity */ 47190 double *delta_2=delta_par+2; /* Delta vector in par space, periodicity */ 47191 double dot; /* Scalar product, periodicity */ 47192 double dist; /* Distance in 3D, periodicity */ 47193 double dist_a; /* Distance in 3D, periodicity */ 47194 double dist_b; /* Distance in 3D, periodicity */ 47195 double dist_c; /* Distance in 3D, periodicity */ 47196 double dist_d; /* Distance in 3D, periodicity */ 47197 double ang; /* Angel between tangents, periodicity */ 47198 int dimobj; /* Dimension 3, periodicity */ 47199 //int dim2=2; /* Dimension 2, periodicity */ 47200 int join=TRUE; /* Flag to kill int point, periodicity */ 47201 int const_crv_1; /* Constant parameter direction */ 47202 int const_crv_2; /* Constant parameter direction */ 47203 int same_curve; /* Flag */ 47204 int no_of_main; /* No of mainpts connected to curr pt */ 47205 int treat_2d; /* Flag, shifting of parameter values is 47206 only done in surf/surf cases. */ 47207 int cas; /* Flag, surf surf, surf analytic, other. */ 47208 double epar[2]; 47209 double *nullp = SISL_NULL; 47210 SISLIntpt *pturn=SISL_NULL; /* Last point in a list, periodicity */ 47211 int log_1, log_2; /* To test on an edge curve lies along 47212 the same parameter direction. */ 47213 int kp,no_par,index_1; 47214 double min_par[4],max_par[4],legal_min[4],legal_max[4]; 47215 SISLObject *qo=SISL_NULL; 47216 /* -------------------------------------------------------------------- */ 47217 47218 /* If we do not have any intersection data we just return. */ 47219 47220 if ((*pintdat) == SISL_NULL) 47221 goto out; 47222 if ((*pintdat)->ipoint <=1) 47223 goto out; 47224 47225 47226 if (po1->iobj == SISLSURFACE) dimobj = po1->s1->idim; 47227 else if (po1->iobj == SISLCURVE) dimobj = po1->c1->idim; 47228 else goto errinp; 47229 47230 /* UJK, 13.08.93 : Check periodicity flag.*/ 47231 no_par = (*pintdat)->vpoint[0]->ipar; 47232 if (no_par > 4) goto errinp; 47233 47234 for (kp=0;kp<4;kp++) 47235 { 47236 legal_min[kp] = -HUGE; 47237 legal_max[kp] = HUGE; 47238 } 47239 47240 for (ki=0,qo=po1,index_1=0;ki<2;ki++,qo=po2) 47241 if (qo) 47242 { 47243 if (qo->iobj == SISLSURFACE) 47244 { 47245 if (qo->s1->cuopen_1 != SISL_SURF_PERIODIC) 47246 { 47247 legal_min[index_1] = qo->s1->et1[qo->s1->ik1-1]; 47248 legal_max[index_1] = qo->s1->et1[qo->s1->in1]; 47249 } 47250 47251 index_1++; 47252 if (qo->s1->cuopen_2 != SISL_SURF_PERIODIC) 47253 { 47254 legal_min[index_1] = qo->s1->et2[qo->s1->ik2-1]; 47255 legal_max[index_1] = qo->s1->et2[qo->s1->in2]; 47256 } 47257 index_1++; 47258 } 47259 else if (qo->iobj == SISLCURVE) 47260 { 47261 if (qo->c1->cuopen != SISL_CRV_PERIODIC) 47262 { 47263 legal_min[index_1] = qo->c1->et[qo->c1->ik-1]; 47264 legal_max[index_1] = qo->c1->et[qo->c1->in]; 47265 } 47266 index_1++; 47267 } 47268 } 47269 47270 47271 /*________________________________________ */ 47272 /* UJK, TESTING !!!!!!!!!!!!!!!!!!! For the moment: */ 47273 if (dimobj == 3 && po2->iobj == SISLPOINT) goto out; 47274 /*________________________________________ */ 47275 47276 if (po1->iobj == SISLSURFACE && 47277 po2->iobj == SISLSURFACE && ideg == 0) 47278 /* Two B-spline surf's in 3D. */ 47279 cas = 1; 47280 else if (po1->iobj == SISLSURFACE && ideg != 2000 && ideg !=0) 47281 /* B-spline surf vs analytic. */ 47282 cas = 2; 47283 else 47284 cas = 0; 47285 47286 47287 47288 if (ideg != 2000 && po1->iobj == SISLSURFACE) treat_2d = TRUE; 47289 else treat_2d = FALSE; 47290 47291 for (ki=1;ki<5;ki++) logtest |= 1<< ki; 47292 47293 /* Ensure that object space information is in place. */ 47294 for (kj = 0; kj < (*pintdat)->ipoint; kj++) 47295 { 47296 pcurr = (*pintdat)->vpoint[kj]; 47297 sh6evalint (po1, po2, eimpli, ideg, pcurr, aepsge, 47298 &curve_val_3d, &curve_val_2d_1, 47299 &curve_val_2d_2, &kstat); 47300 if (kstat < 0) 47301 goto error; 47302 } 47303 47304 /* Check direction for const_crvs. */ 47305 if (cas) 47306 for (ki = 0; ki < (*pintdat)->ilist; ki++) 47307 { 47308 pfirst_1 = (*pintdat)->vlist[ki]->pfirst; 47309 plast_1 = (*pintdat)->vlist[ki]->plast; 47310 47311 if(((*pintdat)->vlist[ki]->inumb == 2) && 47312 (pfirst_1->curve_dir[(*pintdat)->vlist[ki]->ind_first] & logtest)) 47313 { 47314 if (cas == 1) 47315 { 47316 } 47317 else /*if (cas == 2)*/ 47318 { 47319 /* Select midpoint. */ 47320 epar[0] = (pfirst_1->epar[0] + plast_1->epar[0])/2.0; 47321 epar[1] = (pfirst_1->epar[1] + plast_1->epar[1])/2.0; 47322 pturn = hp_newIntpt (2, epar, DZERO, SI_ORD, 47323 SI_UNDEF, SI_UNDEF, SI_UNDEF, SI_UNDEF, 47324 0, 0, nullp, nullp); 47325 if (pturn == SISL_NULL) 47326 goto err101; 47327 47328 sh6evalint (po1, po2, eimpli, ideg, pturn, aepsge, 47329 &curve_val_3d, &curve_val_2d_1, 47330 &curve_val_2d_2, &kstat); 47331 if (kstat < 0) 47332 goto error; 47333 47334 if (pturn->iinter == SI_ORD) 47335 { 47336 double dot; 47337 dot = (plast_1->epar[0]-pfirst_1->epar[0])*curve_val_2d_1[2]+ 47338 (plast_1->epar[1]-pfirst_1->epar[1])*curve_val_2d_1[3]; 47339 if (dot < 0) 47340 { 47341 /* Turn direction. */ 47342 int ind_1, ind_2, dir_1, dir_2; 47343 47344 ind_1 = (*pintdat)->vlist[ki]->ind_first; 47345 ind_2 = (*pintdat)->vlist[ki]->ind_last; 47346 dir_1 = pfirst_1->curve_dir[ind_1]; 47347 dir_2 = plast_1->curve_dir[ind_2]; 47348 47349 (*pintdat)->vlist[ki]->pfirst = plast_1; 47350 (*pintdat)->vlist[ki]->plast = pfirst_1; 47351 (*pintdat)->vlist[ki]->ind_first = ind_2; 47352 (*pintdat)->vlist[ki]->ind_last = ind_1; 47353 pfirst_1->curve_dir[ind_1] = dir_2; 47354 plast_1->curve_dir[ind_2] = dir_1; 47355 47356 } 47357 } 47358 if (pturn) freeIntpt(pturn); 47359 pturn = SISL_NULL; 47360 47361 } 47362 } 47363 } 47364 47365 /* Traverse the lists to remove doubly represented curves along 47366 periodic edges. */ 47367 47368 for (ki = 0; ki < (*pintdat)->ilist; ki++) 47369 { 47370 pfirst_1 = (*pintdat)->vlist[ki]->pfirst; 47371 plast_1 = (*pintdat)->vlist[ki]->plast; 47372 47373 if(((*pintdat)->vlist[ki]->inumb == 2) && 47374 (pfirst_1->curve_dir[(*pintdat)->vlist[ki]->ind_first] & logtest)) 47375 const_crv_1 = TRUE; 47376 else 47377 const_crv_1 = FALSE; 47378 47379 47380 if (pfirst_1 == plast_1) continue; 47381 47382 for (kj = 0; kj < (*pintdat)->ilist; kj++) 47383 { 47384 47385 same_curve = (ki == kj); 47386 pfirst_2 = (*pintdat)->vlist[kj]->pfirst; 47387 plast_2 = (*pintdat)->vlist[kj]->plast; 47388 47389 if(((*pintdat)->vlist[kj]->inumb == 2) && 47390 (pfirst_2->curve_dir[(*pintdat)->vlist[kj]->ind_first] & logtest)) 47391 const_crv_2 = TRUE; 47392 else 47393 const_crv_2 = FALSE; 47394 47395 /* To treat the case when two curves are on an periodic edge */ 47396 if (const_crv_1 && const_crv_2 && !same_curve) 47397 { 47398 log_1 = pfirst_1->curve_dir[(*pintdat)->vlist[ki]->ind_first]; 47399 log_1 = log_1>>1; 47400 log_1 &= 15; 47401 log_2 = pfirst_2->curve_dir[(*pintdat)->vlist[kj]->ind_first]; 47402 log_2 = log_2>>1; 47403 log_2 &= 15; 47404 47405 if (log_1 & log_2) 47406 { 47407 dist_a = s6dist(plast_1->geo_track_3d, 47408 pfirst_2->geo_track_3d, 47409 dimobj); 47410 dist_b = s6dist(plast_1->geo_track_3d, 47411 plast_2->geo_track_3d, 47412 dimobj); 47413 dist_c = s6dist(pfirst_1->geo_track_3d, 47414 pfirst_2->geo_track_3d, 47415 dimobj); 47416 dist_d = s6dist(pfirst_1->geo_track_3d, 47417 plast_2->geo_track_3d, 47418 dimobj); 47419 if ((dist_a <aepsge && dist_d < aepsge) || 47420 (dist_b <aepsge && dist_c < aepsge) ) 47421 { 47422 /* Kill the two points */ 47423 sh6idkpt(pintdat, &pfirst_2, join=FALSE, &kstat); 47424 if (kstat < 0) goto error; 47425 47426 sh6idkpt(pintdat, &plast_2, join=FALSE, &kstat); 47427 if (kstat < 0) goto error; 47428 47429 /* Remove the curve list kj, and pack vlist array */ 47430 freeIntlist ((*pintdat)->vlist[kj]); 47431 (*pintdat)->ilist--; 47432 (*pintdat)->vlist[kj] = 47433 (*pintdat)->vlist[(*pintdat)->ilist]; 47434 47435 /* Reset to start */ 47436 ki = -1; 47437 break; /* kj loop */ 47438 } 47439 47440 } 47441 } 47442 } 47443 } 47444 47445 for (ki = 0; ki < (*pintdat)->ilist; ki++) 47446 { 47447 pfirst_1 = (*pintdat)->vlist[ki]->pfirst; 47448 plast_1 = (*pintdat)->vlist[ki]->plast; 47449 47450 if(((*pintdat)->vlist[ki]->inumb == 2) && 47451 (pfirst_1->curve_dir[(*pintdat)->vlist[ki]->ind_first] & logtest)) 47452 const_crv_1 = TRUE; 47453 else 47454 const_crv_1 = FALSE; 47455 47456 47457 if (pfirst_1 == plast_1) continue; 47458 47459 for (kj = 0; kj < (*pintdat)->ilist; kj++) 47460 { 47461 47462 same_curve = (ki == kj); 47463 pfirst_2 = (*pintdat)->vlist[kj]->pfirst; 47464 plast_2 = (*pintdat)->vlist[kj]->plast; 47465 47466 if(((*pintdat)->vlist[kj]->inumb == 2) && 47467 (pfirst_2->curve_dir[(*pintdat)->vlist[kj]->ind_first] & logtest)) 47468 const_crv_2 = TRUE; 47469 else 47470 const_crv_2 = FALSE; 47471 47472 /* Joining of curves */ 47473 if (plast_1 == pfirst_2 || 47474 plast_1->iinter == SI_TRIM || 47475 plast_1->iinter == SI_SING || 47476 plast_1->iinter == SI_TOUCH || 47477 pfirst_2->iinter == SI_TRIM || 47478 pfirst_2->iinter == SI_SING || 47479 pfirst_2->iinter == SI_TOUCH) 47480 { 47481 /* Test on edge ? */ 47482 continue; 47483 } 47484 else 47485 { 47486 dist = s6dist(plast_1->geo_track_3d, 47487 pfirst_2->geo_track_3d, 47488 dimobj); 47489 ang = s6ang(plast_1->geo_track_3d + dimobj, 47490 pfirst_2->geo_track_3d + dimobj, 47491 dimobj); 47492 dot = s6scpr(plast_1->geo_track_3d + dimobj, 47493 pfirst_2->geo_track_3d + dimobj, 47494 dimobj); 47495 47496 if (dist < aepsge && 47497 dot > 0 && 47498 ang < ANGULAR_TOLERANCE) 47499 { 47500 /* HIT, Join the two lists of curves */ 47501 if (same_curve) 47502 { 47503 /*sh6connect(pfirst_1, plast_1, &kstat); 47504 if (kstat != 0) goto error; 47505 sh6idkpt (pintdat, &plast_1, join=TRUE, &kstat); 47506 if (kstat < 0) goto error; 47507 47508 (*pintdat)->vlist[ki]->inumb -= 1; 47509 47510 periodic set to true ! 47511 47512 (*pintdat)->vlist[ki]->plast = 47513 pfirst_1; */ 47514 } 47515 else 47516 { 47517 /* Move 2D values of second part */ 47518 s6diff(plast_1->epar, 47519 pfirst_2->epar, 47520 no_par, 47521 delta_par); 47522 47523 /* Last check to see if we move outside legal area */ 47524 for(kp=0;kp<no_par;kp++) 47525 { 47526 min_par[kp] = HUGE; 47527 max_par[kp] = -HUGE; 47528 } 47529 47530 pcurr = pfirst_2; 47531 pnext = pfirst_2->pnext[(*pintdat)->vlist[kj]->ind_first]; 47532 while (pcurr != plast_2 && pcurr && pnext) 47533 { 47534 for(kp=0;kp<no_par;kp++) 47535 { 47536 min_par[kp] = min(pnext->epar[kp]+delta_par[kp],min_par[kp]); 47537 max_par[kp] = max(pnext->epar[kp]+delta_par[kp],max_par[kp]); 47538 } 47539 47540 sh6getother (pnext, pcurr, &pother, &kstat); 47541 if (kstat && pnext != plast_2) goto errinconsist; 47542 pcurr = pnext; 47543 pnext = pother; 47544 } 47545 47546 for(kp=0;kp<no_par;kp++) 47547 { 47548 if (min_par[kp] < legal_min[kp] && 47549 DNEQUAL(min_par[kp],legal_min[kp])) break; 47550 if (max_par[kp] > legal_max[kp] && 47551 DNEQUAL(max_par[kp],legal_max[kp])) break; 47552 47553 } 47554 47555 47556 /* _______________________ */ 47557 if (kp == no_par) 47558 { 47559 pcurr = pfirst_2; 47560 pnext = pfirst_2->pnext[(*pintdat)->vlist[kj]->ind_first]; 47561 while (pcurr != plast_2 && pcurr && pnext) 47562 { 47563 for(kp=0;kp<no_par;kp++) 47564 pnext->epar[kp] += delta_par[kp]; 47565 47566 if (treat_2d) 47567 { 47568 pnext->geo_track_2d_1[0] += delta_1[0]; 47569 pnext->geo_track_2d_1[1] += delta_1[1]; 47570 if (cas==1) 47571 { 47572 pnext->geo_track_2d_2[0] += delta_2[0]; 47573 pnext->geo_track_2d_2[1] += delta_2[1]; 47574 } 47575 } 47576 sh6getother (pnext, pcurr, &pother, &kstat); 47577 if (kstat && pnext != plast_2) goto errinconsist; 47578 pcurr = pnext; 47579 pnext = pother; 47580 } 47581 47582 sh6connect(plast_1, pfirst_2, &kstat); 47583 if (kstat != 0) goto error; 47584 sh6idkpt (pintdat, &pfirst_2, join=TRUE, &kstat); 47585 if (kstat < 0) goto error; 47586 47587 if (const_crv_1 && const_crv_2) 47588 { 47589 sh6idkpt (pintdat, &plast_1, join=TRUE, &kstat); 47590 if (kstat < 0) goto error; 47591 47592 sh6getlist(pfirst_1,plast_2, 47593 &((*pintdat)->vlist[ki]->ind_first), 47594 &((*pintdat)->vlist[ki]->ind_last), 47595 &kstat); 47596 kpos = 111; 47597 if (kstat != 0) goto errinconsist; 47598 (*pintdat)->vlist[ki]->inumb = 2; 47599 47600 (*pintdat)->vlist[ki]->plast = 47601 plast_2; 47602 47603 } 47604 else 47605 { 47606 47607 (*pintdat)->vlist[ki]->inumb += 47608 (*pintdat)->vlist[kj]->inumb -1; 47609 47610 (*pintdat)->vlist[ki]->plast = 47611 plast_2; 47612 (*pintdat)->vlist[ki]->ind_last = 47613 (*pintdat)->vlist[kj]->ind_last; 47614 } 47615 47616 /* Remove the curve list kj, and pack vlist array */ 47617 freeIntlist ((*pintdat)->vlist[kj]); 47618 (*pintdat)->ilist--; 47619 (*pintdat)->vlist[kj] = 47620 (*pintdat)->vlist[(*pintdat)->ilist]; 47621 47622 47623 /* Reset to start */ 47624 ki = -1; 47625 break; /* kj loop */ 47626 } 47627 } /* End of else not same curve */ 47628 47629 } /* if hit */ 47630 47631 } /* else */ 47632 } /* kj */ 47633 } /* ki */ 47634 47635 47636 /* Treat single points */ 47637 for (ki = 0; ki < (*pintdat)->ipoint; ki++) 47638 { 47639 kstat = 0; 47640 pcurr = (*pintdat)->vpoint[ki]; 47641 if (sh6ismain(pcurr)) no_of_main = sh6nmbmain(pcurr, &kstat); 47642 else no_of_main = -1; 47643 if (kstat < 0) goto error; 47644 47645 if (no_of_main == 0) 47646 for (kj = 0; kj < (*pintdat)->ipoint; kj++) 47647 { 47648 pother = (*pintdat)->vpoint[kj]; 47649 if (sh6ismain(pother) && pother != pcurr) 47650 { 47651 dist = s6dist(pcurr->geo_track_3d, 47652 pother->geo_track_3d, 47653 dimobj); 47654 if (dist < aepsge) 47655 { 47656 sh6idkpt(pintdat, &pcurr, join = FALSE, &kstat); 47657 if (kstat < 0) goto error; 47658 ki--; /* New point in array place no ki, redo the job */ 47659 break; /* kj loop */ 47660 } 47661 } 47662 } 47663 } 47664 47665 47666 47667 *jstat = 0; 47668 goto out; 47669 47670 /* _________________________ EXIT ____________________________ */ 47671 /* Error in alloc */ 47672 err101: 47673 *jstat = -101; 47674 s6err ("int_join_per", *jstat, kpos); 47675 goto out; 47676 47677 /* Error inconsistency */ 47678 errinconsist: 47679 *jstat = -500; 47680 s6err ("int_join_per", *jstat, kpos); 47681 goto out; 47682 47683 /* Error in input */ 47684 errinp: 47685 *jstat = -200; 47686 s6err ("int_join_per", *jstat, kpos); 47687 goto out; 47688 47689 /* Error in lower level function */ 47690 error: 47691 *jstat = kstat; 47692 s6err ("int_join_per", *jstat, kpos); 47693 goto out; 47694 47695 out: 47696 ; 47697 } 47698 47699 //=========================================================================== 47700 void make_tracks (SISLObject * po1, SISLObject * po2, int ideg, 47701 double eimpli[], int icrv, SISLIntlist ** vlist, 47702 int *jtrack,SISLTrack *** wcrv, double aepsge, int *jstat) 47703 //=========================================================================== 47704 { 47705 *jstat = 0; 47706 *jtrack = 0; 47707 } 47708 //=========================================================================== 47709 void hp_s1880(SISLObject * po1, SISLObject * po2, 47710 int ideg, 47711 int ipar1, int ipar2, SISLIntdat *pintdat, 47712 int *jpar, double **gpar1, double **gpar2, int **pretop, 47713 int *jcrv, SISLIntcurve *** wcrv, int *jsurf, SISLIntsurf *** wsurf, 47714 int *jstat) 47715 //=========================================================================== 47716 { 47717 int kstat; /* Local status */ 47718 int kpos = 0; /* Position of error. */ 47719 int ki, kj, kk; /* Counters. */ 47720 int kpoint; /* Number of points in an intersection list. */ 47721 int ktype; /* Kind of intersection curve. (See SISLIntcurve). */ 47722 int kpt; /* Used to find number of single intersection points.*/ 47723 int index; /* Array index for next point at start */ 47724 int sing_1, sing_2; /* Sing point flag at start and end */ 47725 double *spar1, *spar2; /* Values of points belonging to an intersection 47726 curve in the parameter area of the objects 47727 involved in the intersection. */ 47728 double *stpar1, *stpar2, *stpar3; /* Pointers used to travers arrays 47729 containing parameter values. */ 47730 int *top1; /* Pointers used to travers pretop. */ 47731 SISLIntcurve **ucrv; /* Pointer used to traverse *wcrv array. */ 47732 SISLIntsurf **usurf; /* Pointer used to traverse *wsurf array. */ 47733 SISLIntpt *qpt; /* Pointer to an intersection point. */ 47734 SISLIntpt *qprev; /* Pointer to an intersection point. */ 47735 SISLIntpt *qnext; /* Pointer to an intersection point. */ 47736 SISLIntpt *qpfirst; /* Pointer to first intersection point. */ 47737 SISLIntpt *qplast; /* Pointer to last intersection point. */ 47738 47739 int jpt = pintdat->ipoint; 47740 SISLIntpt **vpoint = pintdat->vpoint; 47741 int jlist = pintdat->ilist; 47742 SISLIntlist **vlist = pintdat->vlist; 47743 SISLObject *qo2 = SISL_NULL; 47744 int kdir,kdir1=-1,kdir2=-1; 47745 int exact=FALSE, exact_treat=FALSE; 47746 int log_test = 0; 47747 double dummy; 47748 /* ------------------------------------------------------------------ */ 47749 47750 for (ki = 1; ki < 5; ki++) 47751 log_test |= 1 << ki; 47752 47753 if (po1->iobj == SISLSURFACE && ideg != 0) 47754 { 47755 /* Surf vs Implicit geometry */ 47756 qo2 = newObject (SISLPOINT); 47757 exact_treat = TRUE; 47758 } 47759 else if (po1->iobj == SISLSURFACE && 47760 po2->iobj == SISLSURFACE && 47761 ideg ==0) 47762 { 47763 /* Surf vs Implicit geometry */ 47764 qo2 = po2; 47765 exact_treat = TRUE; 47766 } 47767 47768 47769 /* Initiate output. */ 47770 47771 *gpar1 = *gpar2 = SISL_NULL; 47772 *wcrv = SISL_NULL; 47773 *wsurf = SISL_NULL; 47774 47775 *jcrv = 0; 47776 *jsurf = 0; 47777 47778 /* Allocate space for intersection curve and surface array. */ 47779 47780 *wcrv = newarray (jlist, SISLIntcurve *); 47781 if (jlist > 0 && *wcrv == SISL_NULL) 47782 goto err101; 47783 *wsurf = newarray (jlist, SISLIntsurf *); 47784 if (jlist > 0 && *wcrv == SISL_NULL) 47785 goto err101; 47786 47787 /* Transfer curve-information from vlist array to wcrv and wsurf arrais. */ 47788 47789 ucrv = *wcrv; 47790 usurf = *wsurf; 47791 47792 for (kpt = ki = 0; ki < jlist; ki++) 47793 { 47794 qpfirst = qpt = (*vlist)->pfirst; 47795 qplast = (*vlist)->plast; 47796 index = (*vlist)->ind_first; 47797 kpoint = (*vlist)->inumb; 47798 if (kpoint == 0) 47799 goto err137; 47800 47801 if (qpfirst->iinter == SI_TRIM && qpfirst == qplast) 47802 { 47803 /* Create new intersection surf. */ 47804 47805 *usurf = newIntsurf(*vlist); 47806 if (*usurf == SISL_NULL) 47807 goto err101; 47808 47809 /* Copy pretopology 47810 memcopy((*usurf)->pretop,(*vlist)->pretop,4,int); */ 47811 47812 kpt += kpoint-1; 47813 usurf++; 47814 (*jsurf)++; 47815 } 47816 else 47817 { 47818 if (qpfirst->iinter == SI_SING || 47819 (sh6nmbmain (qpfirst,&kstat)) > 2) 47820 sing_1 = TRUE; 47821 else 47822 sing_1 = FALSE; 47823 47824 if (qplast->iinter == SI_SING || 47825 (sh6nmbmain (qplast,&kstat)) > 2) 47826 sing_2 = TRUE; 47827 else 47828 sing_2 = FALSE; 47829 47830 47831 /* Allocate space for arrays containing parameter values of points 47832 in intersection curves. */ 47833 47834 spar1 = newarray (ipar1 * kpoint, double); 47835 spar2 = newarray (ipar2 * kpoint, double); 47836 if ((ipar1 > 0 && spar1 == SISL_NULL) || 47837 (ipar2 > 0 && spar2 == SISL_NULL)) 47838 goto err101; 47839 47840 /* Collect parameter values of the points in this intersection list 47841 and distribute values to the objects in the intersection. */ 47842 47843 kj = 0; 47844 stpar1 = spar1; 47845 stpar2 = spar2; 47846 while (qpt != SISL_NULL && kj < kpoint) 47847 { 47848 stpar3 = qpt->epar; 47849 for (kk = 0; kk < ipar1; kk++) 47850 *(stpar1++) = *(stpar3++); 47851 for (kk = 0; kk < ipar2; kk++) 47852 *(stpar2++) = *(stpar3++); 47853 47854 /* Reduce no of single points */ 47855 if (qpt->marker != -99) 47856 { 47857 kpt++; 47858 47859 /* Flag point */ 47860 qpt->marker = -99; 47861 } 47862 if (qpt == qpfirst) 47863 { 47864 qprev = qpt; 47865 qpt = qpt->pnext[index]; 47866 } 47867 else 47868 { 47869 sh6getother (qpt, qprev, &qnext, &kstat); 47870 qprev = qpt; 47871 qpt = qnext; 47872 } 47873 kj++; 47874 } 47875 47876 /* Find type of intersection curve. */ 47877 47878 if (sing_1 && sing_2) 47879 /* Both ends junction */ 47880 ktype = 7; 47881 else if (qpfirst == qplast) 47882 /* Closed curve, not singular */ 47883 ktype = 2; 47884 else if (sing_1) 47885 /* Junction at start */ 47886 ktype = 5; 47887 else if (sing_2) 47888 /* Junction at end */ 47889 ktype = 6; 47890 else 47891 /* Open and clean */ 47892 ktype = 4; 47893 47894 47895 exact = FALSE; 47896 /* UJK, March 1995, when curve type is 9 and the curve is 47897 an iso-line in both surfaces, we want to return both 47898 ppar1 and ppar2. The logic is simple: 47899 kdir1 > -1 (ie eq 0 or 1) means constant in 1. surf. 47900 kdir2 > -1 (ie eq 2 or 3) means constant in 2. surf. 47901 The object space curve pgeom is picked from the 1. surf 47902 if kdir1 is set and from 2. surf if only kdir2 is set. */ 47903 47904 /* UJK, January 1993, if exact curve mark it with type 9. */ 47905 kdir1 = kdir2 = -1; 47906 if (exact_treat && 47907 kj == 2 && 47908 (qpfirst->curve_dir[(*vlist)->ind_first] & log_test)) 47909 { 47910 /* Constant parameter curve */ 47911 for (kdir = 0; kdir < qpfirst->ipar; kdir++) 47912 if (qpfirst->curve_dir[(*vlist)->ind_first] & 47913 (1 << (kdir + 1))) 47914 { 47915 exact = TRUE; 47916 ktype = 9; 47917 if (kdir >= po1->iobj) kdir2 = kdir; 47918 else kdir1 = kdir; 47919 } 47920 } 47921 47922 if (kdir1>-1) kdir = kdir1; 47923 else kdir = kdir2; 47924 47925 /* Create new intersection curve. */ 47926 *ucrv = newIntcurve (kj, ipar1, ipar2, spar1, spar2, ktype); 47927 if (*ucrv == SISL_NULL) 47928 goto err101; 47929 47930 /* Copy pretopology */ 47931 memcopy((*ucrv)->pretop,(*vlist)->pretop,4,int); 47932 47933 47934 /* UJK, January 1993, if exact curve mark it with type 9. */ 47935 if (exact) 47936 { 47937 47938 pick_crv_sf (po1, qo2, kdir, qpfirst, 47939 qplast, &(*ucrv)->pgeom, &kstat); 47940 if (kstat < 0) 47941 goto error; 47942 47943 /* UJK, Pick 2D line */ 47944 47945 if (kdir2 >= po1->iobj) 47946 { 47947 s1602(&(qpfirst->epar[po1->iobj]), 47948 &(qplast->epar[po1->iobj]), 47949 2, 47950 2, 47951 (*ucrv)->pgeom->et[(*ucrv)->pgeom->ik - 1], 47952 &dummy, 47953 &(*ucrv)->ppar2, 47954 &kstat); 47955 if (kstat < 0) goto error; 47956 } 47957 47958 if (kdir1 >= 0) 47959 { 47960 s1602(qpfirst->epar, 47961 qplast->epar, 47962 2, 47963 2, 47964 (*ucrv)->pgeom->et[(*ucrv)->pgeom->ik - 1], 47965 &dummy, 47966 &(*ucrv)->ppar1, 47967 &kstat); 47968 47969 if (kstat < 0) goto error; 47970 } 47971 47972 } 47973 47974 47975 ucrv++; 47976 (*jcrv)++; 47977 } 47978 vlist++; 47979 } 47980 47981 /* Find number of single intersection points. */ 47982 47983 kpt = jpt - kpt; 47984 if (kpt < 0) goto err137; 47985 47986 /* Create arrays to keep parameter values of intersection points. */ 47987 47988 *gpar1 = newarray (ipar1 * kpt, double); 47989 *gpar2 = newarray (ipar2 * kpt, double); 47990 *pretop = newarray (4 * kpt, int); 47991 if ((ipar1 * kpt > 0 && *gpar1 == SISL_NULL) 47992 || (ipar2 * kpt > 0 && *gpar2 == SISL_NULL) 47993 || (4 * kpt > 0 && *pretop == SISL_NULL)) 47994 goto err101; 47995 47996 /* Copy parameters of single intersection points into output-arrays. */ 47997 47998 kj = 0; 47999 stpar1 = *gpar1; 48000 stpar2 = *gpar2; 48001 top1 = *pretop; 48002 for (ki = 0; ki < jpt; ki++) 48003 { 48004 qpt = *vpoint; 48005 if (qpt != SISL_NULL) 48006 { 48007 if (sh6ismain(qpt) && qpt->marker != -99) 48008 { 48009 kj++; 48010 stpar3 = qpt->epar; 48011 for (kk = 0; kk < ipar1; kk++) 48012 *(stpar1++) = *(stpar3++); 48013 for (kk = 0; kk < ipar2; kk++) 48014 *(stpar2++) = *(stpar3++); 48015 *(top1++) = qpt->left_obj_1[0]; 48016 *(top1++) = qpt->right_obj_1[0]; 48017 *(top1++) = qpt->left_obj_2[0]; 48018 *(top1++) = qpt->right_obj_2[0]; 48019 } 48020 } 48021 48022 vpoint++; 48023 } 48024 48025 *jpar = kj; 48026 48027 /* Adjust output arrays to correct length. */ 48028 48029 if ((*jcrv) < jlist) 48030 { 48031 if ((*jcrv) > 0) 48032 { 48033 if (((*wcrv) = increasearray (*wcrv, *jcrv, SISLIntcurve *)) == SISL_NULL) 48034 goto err101; 48035 } 48036 else 48037 { 48038 if (*wcrv != SISL_NULL) 48039 freearray (*wcrv); 48040 *wcrv = SISL_NULL; 48041 } 48042 } 48043 if ((*jsurf) < jlist) 48044 { 48045 if ((*jsurf) > 0) 48046 { 48047 if (((*wsurf) = increasearray (*wsurf, *jsurf, SISLIntsurf *)) == SISL_NULL) 48048 goto err101; 48049 } 48050 else 48051 { 48052 if (*wsurf != SISL_NULL) 48053 freearray (*wsurf); 48054 *wsurf = SISL_NULL; 48055 } 48056 } 48057 if (kj * ipar1 > 0) 48058 { 48059 if ((*gpar1 = increasearray (*gpar1, kj * ipar1, double)) == SISL_NULL) 48060 goto err101; 48061 } 48062 else 48063 { 48064 if (*gpar1 != SISL_NULL) 48065 freearray (*gpar1); 48066 *gpar1 = SISL_NULL; 48067 } 48068 if (kj * ipar2 > 0) 48069 { 48070 if ((*gpar2 = increasearray (*gpar2, kj * ipar2, double)) == SISL_NULL) 48071 goto err101; 48072 } 48073 else 48074 { 48075 if (*gpar2 != SISL_NULL) 48076 freearray (*gpar2); 48077 *gpar2 = SISL_NULL; 48078 } 48079 if (kj > 0) 48080 { 48081 if ((*pretop= increasearray (*pretop, kj * 4, int)) == SISL_NULL) 48082 goto err101; 48083 } 48084 else 48085 { 48086 if (*pretop != SISL_NULL) 48087 freearray (*pretop); 48088 *pretop = SISL_NULL; 48089 } 48090 48091 /* Intersections copied to output format. */ 48092 48093 *jstat = 0; 48094 goto out; 48095 48096 /* Error in space allocation. */ 48097 48098 err101:*jstat = -101; 48099 s6err ("hp_s1880", *jstat, kpos); 48100 goto out; 48101 48102 /* Error in data-strucuture. Expected intersection point not found. */ 48103 48104 err137:*jstat = -137; 48105 s6err ("hp_s1880", *jstat, kpos); 48106 goto out; 48107 48108 /* Error in lower level routine. */ 48109 error: 48110 *jstat = kstat; 48111 s6err ("hp_s1880", *jstat, kpos); 48112 goto out; 48113 48114 48115 out: 48116 if (po1->iobj == SISLSURFACE && ideg != 0) 48117 freeObject (qo2); 48118 return; 48119 } 48120 48121 //=========================================================================== 48122 void freeObject(SISLObject *pobj) 48123 //=========================================================================== 48124 { 48125 int ki; 48126 48127 /* Free point, curve or surface represented by pobj. */ 48128 48129 if (pobj -> iobj == SISLPOINT) 48130 { if (pobj -> p1 != SISL_NULL) freePoint(pobj -> p1); } 48131 else if (pobj -> iobj == SISLCURVE) 48132 { if (pobj -> c1 != SISL_NULL) freeCurve(pobj -> c1); } 48133 else if (pobj -> iobj == SISLSURFACE) 48134 { if (pobj -> s1 != SISL_NULL) freeSurf(pobj -> s1); } 48135 48136 for (ki=0; ki<4; ki++) 48137 if (pobj->edg[ki] != SISL_NULL) freeObject(pobj->edg[ki]); 48138 48139 /* Free instance of object. */ 48140 48141 freearray(pobj); 48142 48143 return; 48144 } 48145 48146 //=========================================================================== 48147 void freeIntdat(SISLIntdat *pintdat) 48148 //=========================================================================== 48149 { 48150 int ki; /* Counter. */ 48151 48152 if (pintdat == SISL_NULL) goto out; 48153 48154 /* First free the space occupied by the Intpt's pointed at by 48155 the array vpoint. */ 48156 48157 for (ki=0; ki<pintdat->ipoint; ki++) 48158 if (pintdat -> vpoint[ki]) freeIntpt(pintdat -> vpoint[ki]); 48159 48160 /* Free the space occupied by the vpoint array. */ 48161 48162 freearray(pintdat -> vpoint); 48163 48164 /* Next free the space occupied by the Intlists pointed at by 48165 the array vlist. */ 48166 48167 for (ki=0; ki<pintdat->ilist; ki++) 48168 if (pintdat -> vlist[ki]) freeIntlist(pintdat -> vlist[ki]); 48169 48170 /* Free the space occupied by the vpoint array. */ 48171 48172 freearray(pintdat -> vlist); 48173 48174 /* Free the space occupied by the instance. */ 48175 48176 freearray(pintdat); 48177 48178 out: 48179 return; 48180 } 48181 48182 //=========================================================================== 48183 void sh1992su(SISLSurf *ps,int itype,double aepsge,int *jstat) 48184 //=========================================================================== 48185 { 48186 int kstat = 0; /* Status variable. */ 48187 int kdim = ps->idim; /* Dimension of geometry space. */ 48188 int ktype = itype % 10; /* Kind of box. */ 48189 int knum; /* Number of sides of box. */ 48190 int kbez = 0; /* Indicates if Bezier. */ 48191 double teps_inner; /* Tolerance with which to expand in the inner. */ 48192 double teps_edge; /* Tolerance with which to expand at the edge. */ 48193 48194 /* Set correct tolerances. */ 48195 48196 teps_inner = (ktype == 0) ? DZERO : (double)0.5*aepsge; 48197 teps_edge = (ktype == 2) ? -teps_inner : teps_inner; 48198 48199 /* Set number of box sides. */ 48200 48201 if (itype < 10 && kdim == 3) knum = 9; 48202 else if (itype < 10 && kdim == 2) knum = 4; 48203 else knum = kdim; 48204 48205 if (ps->pbox == SISL_NULL) 48206 if ((ps->pbox = newbox(ps->idim)) == SISL_NULL) goto err101; 48207 48208 if (s6existbox(ps->pbox,ktype,aepsge) < 1) 48209 { 48210 /* The box do not exist already. In the Bezier case, it 48211 is not necessary to expand in the inner of the surface. */ 48212 48213 /* Create the box. */ 48214 48215 s6newbox(ps->pbox,knum,ktype,aepsge,&kstat); 48216 if (kstat < 0) goto error; 48217 48218 if (ps->ik1 == ps->in1 && ps->ik2 == ps->in2) 48219 { 48220 teps_inner = DZERO; 48221 kbez = 1; 48222 } 48223 48224 /* Make the requested box. First allocate scratch for 48225 box arrays. */ 48226 48227 if (knum == 9) 48228 sh1992_s9mbox3(ps->ecoef,ps->in1,ps->in2,teps_inner,teps_edge, 48229 ps->pbox->e2max[ktype],ps->pbox->e2min[ktype]); 48230 else if (knum == 4) 48231 sh1992_s9mbox2(ps->ecoef,ps->in1,ps->in2,teps_inner,teps_edge, 48232 ps->pbox->e2max[ktype],ps->pbox->e2min[ktype]); 48233 else 48234 { 48235 sh1992_s9mbox(ps->ecoef,ps->in1,ps->in2,kdim, 48236 teps_inner,teps_edge,ps->pbox->e2max[ktype], 48237 ps->pbox->e2min[ktype],&kstat); 48238 if (kstat < 0) goto error; 48239 } 48240 } 48241 48242 *jstat = 0; 48243 goto out; 48244 48245 /* Error in space allocation. */ 48246 48247 err101 : *jstat = -101; 48248 goto out; 48249 48250 /* Error in lower level routine. */ 48251 48252 error : *jstat = kstat; 48253 goto out; 48254 48255 out: 48256 return; 48257 } 48258 48259 //=========================================================================== 48260 void s1304(double ep[],double eq[],double eparp[],double eparq[],double egeo3d[], 48261 double egeop[],double egeoq[],int *jstat) 48262 //=========================================================================== 48263 { 48264 int kdim = 3; /* Dimension of 3-D space */ 48265 int k2dim = 2; /* Dimension of the parameter planes */ 48266 int kstat = 0; /* Local status variable */ 48267 int ki; /* Control variable in loop */ 48268 double snpu[3]; /* Nomalized version of epu */ 48269 double snpv[3]; /* Nomalized version of epv */ 48270 double spn[3]; /* Vector snpu x snpv */ 48271 double snqs[3]; /* Nomalized version of eqs */ 48272 double snqt[3]; /* Nomalized version of eqt */ 48273 double sqn[3]; /* Vector snqs x snqt */ 48274 double sright[3]; /* Right hand side when finding s" */ 48275 double sdc[3]; /* Derivative of intersection curve by w */ 48276 double sddc[3]; /* Second Derivative of intersection curve by w*/ 48277 double *sqs; /* Pointer to first row of matrix */ 48278 double *sqt; /* Pointer to second row of matrix */ 48279 double *spu; /* Pointer to third row of matrix */ 48280 double *spw; /* Pointer to fourth row of matrix */ 48281 double *spuu; /* Pointer to renamed (2,0)-derivative */ 48282 double *spuw; /* Pointer to renamed (1,1)-derivative */ 48283 double *spww; /* Pointer to renamed (0,2)-derivative */ 48284 double *sqss; /* Pointer to renamed (2,0)-derivative */ 48285 double *sqst; /* Pointer to renamed (1,1)-derivative */ 48286 double *sqtt; /* Pointer to renamed (0,2)-derivative */ 48287 double tt; /* Value of det(snpu,snpv,snqs) */ 48288 double ts; /* Value of det(snpu,snpv,snqt) */ 48289 double tv; /* Value of det(snqs,snqt,snpu) */ 48290 double tu; /* Value of det(snqs,snqt,snpv) */ 48291 double tlpu; /* Length of epu */ 48292 double tlpv; /* Length of epv */ 48293 double tlqs; /* Length of eqs */ 48294 double tlqt; /* Length of eqt */ 48295 double tmax1; /* Variable used for maximal value */ 48296 double tmax2; /* Variable used for maximal value */ 48297 double tdum; /* Dummy variable */ 48298 double tdom; /* The denominator in an equation */ 48299 double tds; /* ds/dw */ 48300 double tdt; /* dt/dw */ 48301 double tdu; /* du/dw */ 48302 double tddu; /* ddu/dwdw */ 48303 double tdds; /* dds/dwdw */ 48304 double tddt; /* ddt/dwdw */ 48305 double twds; /* ds/dw after renaming variable second time */ 48306 double twdt; /* dt/dw after renaming variable second time */ 48307 double twdds; /* dds/dwdw after renaming variable second time*/ 48308 double twddt; /* ddt/dwdw after renaming variable second time*/ 48309 double twdu; /* du/dw after renaming variable second time */ 48310 double twdv; /* dv/dw after renaming variable second time */ 48311 double twddu; /* ddu/dwdw after renaming variable second time*/ 48312 double twddv; /* ddv/dwdw after renaming variable second time*/ 48313 48314 48315 /* Get input values into output. */ 48316 egeoq[0] = eparq[0]; 48317 egeoq[1] = eparq[1]; 48318 egeop[0] = eparp[0]; 48319 egeop[1] = eparp[1]; 48320 48321 for (ki=2;ki<7;ki++) 48322 { 48323 egeop[ki] = DZERO; 48324 egeoq[ki] = DZERO; 48325 } 48326 48327 /* Make position of intersection */ 48328 48329 for (ki=0;ki<3;ki++) 48330 { 48331 egeo3d[ki] = (double)0.5 * (ep[ki]+eq[ki]); 48332 } 48333 48334 for (ki=3;ki<10;ki++) egeo3d[ki] = DZERO; 48335 48336 48337 /* Nomalize derivative vectors */ 48338 48339 tlpu = s6norm(ep+3,kdim,snpu,&kstat); 48340 tlpv = s6norm(ep+6,kdim,snpv,&kstat); 48341 tlqs = s6norm(eq+3,kdim,snqs,&kstat); 48342 tlqt = s6norm(eq+6,kdim,snqt,&kstat); 48343 48344 /* Make normal vector for both derivative pairs */ 48345 48346 s6crss(snpu,snpv,spn); 48347 s6crss(snqs,snqt,sqn); 48348 48349 /* Make four scalar product to decide which of the 3 vectors snpu, snpv, 48350 * snqs, snqt spans the 3-D space best. (Have the biggest determinant) 48351 * Remember (axb)c = det(a,b,c). The naming convention is that the 48352 * name of the variable not present on the left hand side is used for 48353 * the naming of the determinants. The determinants tt, ts, tu and tv tells 48354 * which direction is most linearly dependent on the other directions 48355 */ 48356 48357 tt = fabs(s6scpr(spn,snqs,kdim)); 48358 ts = fabs(s6scpr(spn,snqt,kdim)); 48359 tv = fabs(s6scpr(sqn,snpu,kdim)); 48360 tu = fabs(s6scpr(sqn,snpv,kdim)); 48361 48362 /* We want to use the parameter direction names s, t and u on the left 48363 * hand side of the equation system, thus we want to express all derivatives 48364 * of the curve as functions of a new parameter value w, which is chosen 48365 * to be the parameter direction with partial first derivative most 48366 * lineary dependent of the other parameter directions 48367 */ 48368 48369 tmax1 = MAX(tt,ts); 48370 tmax2 = MAX(tv,tu); 48371 48372 if (tmax1 > tmax2) 48373 { 48374 48375 /* The s or t variable should not be used on the left hand side of 48376 * the equation system 48377 */ 48378 48379 if (ts>tt) 48380 { 48381 48382 /* The s variable should not be used on the left hand side of the 48383 * equation system 48384 * The renaming of variables is as follows s->w, t->u, u->s, v->t 48385 */ 48386 48387 spu = eq+6; 48388 spw = eq+3; 48389 spuu = eq+15; 48390 spuw = eq+12; 48391 spww = eq+9; 48392 sqs = ep+3; 48393 sqt = ep+6; 48394 sqss = ep+9; 48395 sqst = ep+12; 48396 sqtt = ep+15; 48397 } 48398 else 48399 { 48400 48401 /* The t variable should not be used on the left hand side of the 48402 * equation system 48403 * The renaming of variables is as follows s->u, t->w, u->s, v->t 48404 */ 48405 48406 spu = eq+3; 48407 spw = eq+6; 48408 spuu = eq+9; 48409 spuw = eq+12; 48410 spww = eq+15; 48411 sqs = ep+3; 48412 sqt = ep+6; 48413 sqss = ep+9; 48414 sqst = ep+12; 48415 sqtt = ep+15; 48416 } 48417 } 48418 else 48419 { 48420 48421 /* The u or v variable should not be used on the left hand side of 48422 * the equation system 48423 */ 48424 48425 if (tu>tv) 48426 48427 { 48428 48429 /* The u variable should not be used on the left hand side of the 48430 * equation system. 48431 * The renaming of variables is as follows s->s, t->t, u->w, v->u 48432 */ 48433 48434 spu = ep+6; 48435 spw = ep+3; 48436 spuu = ep+15; 48437 spuw = ep+12; 48438 spww = ep+9; 48439 sqs = eq+3; 48440 sqt = eq+6; 48441 sqss = eq+9; 48442 sqst = eq+12; 48443 sqtt = eq+15; 48444 48445 } 48446 48447 else 48448 48449 { 48450 /* The v variable should not be used on the left hand side of the 48451 * equation system. 48452 * The renaming of variables is as follows s->s, t->t, u->u, v->w 48453 */ 48454 48455 spu = ep+3; 48456 spw = ep+6; 48457 spuu = ep+9; 48458 spuw = ep+12; 48459 spww = ep+15; 48460 sqs = eq+3; 48461 sqt = eq+6; 48462 sqss = eq+9; 48463 sqst = eq+12; 48464 sqtt = eq+15; 48465 48466 } 48467 } 48468 48469 /* Now we can solve the equation systems for finding 48470 * ds/dw, dt/dw and du/dw and afterwards for 48471 * dds/(dwdw), ddt/(dwdw) and ddu/(dwdw), using Cramers Rule. 48472 * 48473 * This equation system is derived in the following way: 48474 * Our problem is defined as P(u,w) - Q(s,t) = 0. By taking the derivative 48475 * of this equation with repsect to w, we get: 48476 * 48477 * dP(u,w) du dP(u,w) dQ(s,t) ds dQ(s,t) dt 48478 * ------- -- + ------- - ------- -- - ------- -- = 0 48479 * du dw dw ds dw dt dw 48480 * 48481 * By using a simplified notation this can be written: 48482 * 48483 * P u' + P - Q s' - Q t' = 0 48484 * u w s t 48485 * 48486 * We can thus set up the equation system: 48487 * 48488 * s' 48489 * (Q Q -P ) (t') = P 48490 * s t u u' w 48491 * 48492 * 48493 * 48494 * By making one futher derivative we get an equation systen for s",t" and 48495 * u". 48496 * 48497 * s" 2 2 2 48498 * (Q Q -P ) (t") = P u' + 2P u' + P - Q s' - 2Q s't' - Q t' 48499 * s t u u" uu uw ww ss st tt 48500 * 48501 * 48502 */ 48503 48504 /* Prepare normal vectors for determinants */ 48505 48506 s6crss(spu,spw,spn); 48507 s6crss(sqs,sqt,sqn); 48508 48509 tdom = -s6scpr(sqn,spu,kdim); 48510 48511 if (DEQUAL(tdom,(double)0.0)) goto war101; 48512 48513 /* Lineary dependent vectors on left hand side if tdom = 0.0 */ 48514 48515 tds = -s6scpr(spn,sqt,kdim)/tdom; 48516 tdt = s6scpr(spn,sqs,kdim)/tdom; 48517 tdu = s6scpr(sqn,spw,kdim)/tdom; 48518 48519 for (ki=0;ki<3;ki++) 48520 { 48521 sright[ki] = (spuu[ki]*tdu + (double)2.0*spuw[ki])*tdu + spww[ki] 48522 - (sqss[ki]*tds + sqst[ki]*tdt)*tds 48523 - (sqtt[ki]*tdt + sqst[ki]*tds)*tdt; 48524 } 48525 48526 /* Calculate second derivatives of parameter direction with respect to 48527 * the w-direction 48528 */ 48529 48530 tddu = s6scpr(sqn,sright,kdim)/tdom; 48531 48532 /* Use sqn for temporary storage of cross products */ 48533 48534 s6crss(sright,sqt,sqn); 48535 tdds = -s6scpr(sqn,spu,kdim)/tdom; 48536 s6crss(sqs,sright,sqn); 48537 tddt = -s6scpr(sqn,spu,kdim)/tdom; 48538 48539 /* We will now express the intersection curve locally as a function 48540 * of the w-parameter. 48541 * 48542 * c(w) = p(u(w),w) 48543 * 48544 * This gives the derivative 48545 * 48546 * 48547 * c' = P u' + P 48548 * u w 48549 * 48550 * And the second derivative 48551 * 48552 * 2 48553 * c" = P u' + 2P u' + P + P u" 48554 * uu uw ww u 48555 * 48556 * The curvature vector is defined as the derivative of the unit tangent 48557 * vector with respect to the arc length a(w): 48558 * 48559 * d d c'(w) dw d c'(w) da 48560 * k(a) = -- T(a) = -- ---------- -- = -- ---------- / -- 48561 * da dw sqrt(c'c') da dw sqrt(c'c') dw 48562 * 48563 * 48564 * d c'(w) c" c' (c'c'') 48565 * -- ----------------- = ---------- - ------------- 48566 * dw sqrt(c'(w) c'(w)) sqrt(c'c') sqrt(c'c')**3 48567 * 48568 * 48569 * 48570 * da 48571 * -- = sqrt(c'c') 48572 * dw 48573 */ 48574 for (ki=0;ki<3;ki++) 48575 { 48576 sdc[ki] = spu[ki]*tdu + spw[ki]; 48577 sddc[ki] = (spuu[ki]*tdu+(double)2.0*spuw[ki])*tdu + 48578 spu[ki]*tddu + spww[ki]; 48579 } 48580 48581 /* To simplify futher calculations we want to normalize the tangent vector 48582 * and correspondingly divide the second derivative by the tangent length 48583 */ 48584 48585 tlpu = s6norm(sdc,kdim,egeo3d+3,&kstat); 48586 48587 if (DEQUAL(tlpu,(double)0.0)) goto war101; 48588 48589 for (ki=0;ki<3;ki++) 48590 { 48591 sddc[ki] = sddc[ki]/tlpu; 48592 } 48593 48594 /* Make curvature vector */ 48595 48596 tdum = s6scpr(sddc,egeo3d+3,kdim); 48597 for (ki=0;ki<3;ki++) 48598 { 48599 egeo3d[ki+6] = (sddc[ki] - egeo3d[ki+3]*tdum)/tlpu; 48600 } 48601 48602 /* TO CALCULATE UNIT TANGENT CURVATURE AND RADIUS OF CURVATURE OF THE 48603 * INTERSECTION POINT IN THE PARAMETER PLANES OF THE TWO SURFACES, WE 48604 * NOW WANT TO CALCULATE THE TRUE VALUES OF ds/dw, dt/dw, dds/dw, 48605 * ddt/dwdw, du/dw, dv/dw, ddu/dwdw, ddv/dwdw, where w is the parameter 48606 * direction we have chosen the other directions to be expressed in. 48607 * THUS UNDO the changing of parameter directions 48608 */ 48609 48610 if (tmax1 > tmax2) 48611 { 48612 48613 /* First and second row of the surface were originally interchanged 48614 * Thus change sequence of these back again 48615 */ 48616 48617 if (ts>tt) 48618 { 48619 /* We used the following renaming of variables: 48620 * s->w, t->u, u->s, v->t, now express the behavior in the parameter 48621 * plane with the original ordering 48622 */ 48623 48624 twds = (double)1.0; 48625 twdt = tdu; 48626 twdds = (double)0.0; 48627 twddt = tddu; 48628 twdu = tds; 48629 twdv = tdt; 48630 twddu = tdds; 48631 twddv = tddt; 48632 48633 } 48634 else 48635 { 48636 48637 /* We used the following renaming of variables: 48638 * s->u, t->w, u->s, v->t, now express the behavior in the parameter 48639 * plane with the original ordering 48640 */ 48641 48642 /* The renaming of variables is as follows s->v, t->u, u->s, v->t */ 48643 48644 twds = tdu; 48645 twdt = (double)1.0; 48646 twdds = tddu; 48647 twddt = (double)0.0; 48648 twdu = tds; 48649 twdv = tdt; 48650 twddu = tdds; 48651 twddv = tddt; 48652 48653 } 48654 } 48655 else 48656 { 48657 48658 /* Keep the sequence of surfaces */ 48659 48660 if (tu>tv) 48661 48662 { 48663 48664 /* We used the following renaming of variables: 48665 * s->s, t->t, u->w, v->u, now express the behavior in the parameter 48666 * plane with the original ordering 48667 */ 48668 48669 twds = tds; 48670 twdt = tdt; 48671 twdds = tdds; 48672 twddt = tddt; 48673 twdu = (double)1.0; 48674 twdv = tdu; 48675 twddu = (double)0.0; 48676 twddv = tddu; 48677 48678 } 48679 48680 else 48681 48682 { 48683 48684 /* We used the following renaming of variables: 48685 * s->s, t->t, u->u, v->w, now express the behavior in the parameter 48686 * plane with the original ordering */ 48687 48688 twds = tds; 48689 twdt = tdt; 48690 twdds = tdds; 48691 twddt = tddt; 48692 twdu = tdu; 48693 twdv = (double)1.0; 48694 twddu = tddu; 48695 twddv = (double)0.0; 48696 48697 } 48698 } 48699 48700 /* Now the variable twds, twdt, twdu, twdv contains derivatives of the 48701 * parameter directions with respect to the w-variable. Correspondingly 48702 * the second derivatives with respect to w are contained in twdds, twddt, 48703 * twddu and twddv. 48704 * 48705 * THE UNIT TANGENT, CURVATURE VECTOR AND RADIUS OF CURVATURE CAN NOW 48706 * BE CALCULATED IN BOTH PARAMETER PLANES 48707 */ 48708 48709 /* Make description of intersection curve in 48710 * parameter plane of first patch 48711 */ 48712 48713 48714 tdum = sqrt(twdu*twdu + twdv*twdv); 48715 if (DEQUAL(tdum,(double)0.0)) 48716 { 48717 egeop[2] = (double)0.0; 48718 egeop[3] = (double)0.0; 48719 egeop[4] = (double)0.0; 48720 egeop[5] = (double)0.0; 48721 egeop[6] = (double)0.0; 48722 } 48723 else 48724 { 48725 48726 /* Make unit tangent */ 48727 48728 egeop[2] = twdu/tdum; 48729 egeop[3] = twdv/tdum; 48730 48731 /* Make curvature vector */ 48732 48733 tdom = egeop[2]*twddu + egeop[3]*twddv; 48734 egeop[4] = (twddu/tdum - egeop[2]*tdom/tdum)/tdum; 48735 egeop[5] = (twddv/tdum - egeop[3]*tdom/tdum)/tdum; 48736 } 48737 48738 /* Make radius of curvature in parameter plane 1 */ 48739 48740 tdum = s6length(egeop+4,k2dim,&kstat); 48741 if (DNEQUAL(tdum,(double)0.0)) 48742 { 48743 egeop[6] = (double)1.0/tdum; 48744 } 48745 else 48746 { 48747 egeop[6] = (double)-1.0; 48748 } 48749 48750 /* Make description of intersection curve in parameter 48751 * plane of second patch 48752 */ 48753 tdum = sqrt(twds*twds + twdt*twdt); 48754 if (DEQUAL(tdum,(double)0.0)) 48755 { 48756 egeoq[2] = (double)0.0; 48757 egeoq[3] = (double)0.0; 48758 egeoq[4] = (double)0.0; 48759 egeoq[5] = (double)0.0; 48760 egeoq[6] = (double)0.0; 48761 } 48762 else 48763 { 48764 48765 /* Make unit tangent */ 48766 48767 egeoq[2] = twds/tdum; 48768 egeoq[3] = twdt/tdum; 48769 48770 /* Make curvature vector */ 48771 48772 tdom = egeoq[2]*twdds + egeoq[3]*twddt; 48773 egeoq[4] = (twdds/tdum - egeoq[2]*tdom/tdum)/tdum; 48774 egeoq[5] = (twddt/tdum - egeoq[3]*tdom/tdum)/tdum; 48775 } 48776 48777 /* Make radius of curvature in parameter plane 2 */ 48778 48779 tdum = s6length(egeoq+4,k2dim,&kstat); 48780 if (DNEQUAL(tdum,(double)0.0)) 48781 { 48782 egeoq[6] = (double)1.0/tdum; 48783 } 48784 else 48785 { 48786 egeoq[6] = (double)-1.0; 48787 } 48788 48789 /* Make 3-D radius of curvature */ 48790 48791 tdum = s6length(egeo3d+6,kdim,&kstat); 48792 48793 if (DNEQUAL(tdum,(double)0.0)) 48794 { 48795 egeo3d[9] = (double)1.0/tdum; 48796 } 48797 else 48798 { 48799 egeo3d[9] = (double)-1.0; 48800 goto war101; 48801 } 48802 48803 48804 *jstat = 0; 48805 goto out; 48806 48807 /* Infinit radius of curvature */ 48808 48809 war101: *jstat=1; 48810 goto out; 48811 48812 out: 48813 return; 48814 } 48815 48816 //=========================================================================== 48817 void s9iterate(double epoint[],double epnt1[],double epnt2[],double epar1[], 48818 double epar2[],SISLSurf *psurf1,SISLSurf *psurf2,double astep, 48819 double aepsge,double gpnt1[],double gpnt2[],double gpar1[], 48820 double gpar2[],int *jstat) 48821 //=========================================================================== 48822 { 48823 int ki; /* Variable used in loop */ 48824 int kcont; /* Indicator telling if iteration is not finished */ 48825 int kder = 2; /* Derivative indicator */ 48826 int klfu=0; /* Pointer into knot vector */ 48827 int klfv=0; /* Pointer into knot vector */ 48828 int klfs=0; /* Pointer into knot vector */ 48829 int klft=0; /* Pointer into knot vector */ 48830 int kstat; /* Status variable */ 48831 int knbit; /* Counter for number of iterations */ 48832 int kdim = 3; /* Set dimension to 3 */ 48833 int kmaxit = 100; /* Maximal number of iterations allowed */ 48834 int kpos=1; /* Position indicator ofr errors */ 48835 double spoint[3]; /* SISLPoint in intersection plane */ 48836 double *snorm; /* Pointer to normal vector of intersection plane */ 48837 double *sp,*spu,*spv,*spn; /* Pointers into gpnt1 */ 48838 double *sq,*sqs,*sqt,*sqn; /* Pointers into gpnt2 */ 48839 double ta11,ta12,ta21; /* Variables used in equation systems */ 48840 double ta22,tb1,tb2; /* Variables used in equation systems */ 48841 double sdiff[3]; /* Difference between two vectors */ 48842 double tdum1,tdum2; /* Dummy variables */ 48843 double tdum3,tdum; /* Dummy variables */ 48844 double tdist; /* Distance betweentwo points in iteration */ 48845 48846 48847 48848 /* Make description of intersection plane */ 48849 48850 for (ki=0;ki<3;ki++) 48851 { 48852 spoint[ki] = epoint[ki] + astep*epoint[ki+3]; 48853 } 48854 48855 snorm = epoint + 3; 48856 48857 /* Copy input variables to output variables */ 48858 48859 memcopy(gpnt1,epnt1,21,DOUBLE); 48860 memcopy(gpnt2,epnt2,21,DOUBLE); 48861 memcopy(gpar1,epar1,2,DOUBLE); 48862 memcopy(gpar2,epar2,2,DOUBLE); 48863 48864 /* At the start of the iteration the two point gpnt1 and gpnt2 might be 48865 very close since we in most cases start from a point on the intersection 48866 curve. */ 48867 48868 /* Set a number of local pointers that ar used often */ 48869 sp = gpnt1; 48870 spu = gpnt1 + 3; 48871 spv = gpnt1 + 6; 48872 spn = gpnt1 + 18; 48873 sq = gpnt2; 48874 sqs = gpnt2 + 3; 48875 sqt = gpnt2 + 6; 48876 sqn = gpnt2 + 18; 48877 48878 kcont = 1; 48879 knbit = 0; 48880 48881 while (kcont) 48882 48883 { 48884 48885 /* Put a parametric representation of the tangent 48886 plane of surface 1 into 48887 the implicit representation of the tangent 48888 plane of surface 2 and also 48889 into the implicit representation of 48890 the intersection plane */ 48891 48892 ta11 = s6scpr(spu,sqn,kdim); 48893 ta12 = s6scpr(spv,sqn,kdim); 48894 ta21 = s6scpr(spu,snorm,kdim); 48895 ta22 = s6scpr(spv,snorm,kdim); 48896 48897 s6diff(sq,sp,kdim,sdiff); 48898 tb1 = s6scpr(sdiff,sqn,kdim); 48899 48900 tdum = MAX(fabs(ta11),fabs(ta12)); 48901 tdum = MAX(tdum,fabs(tb1)); 48902 if (tdum == DZERO) tdum = (double)1.0; 48903 ta11 /= tdum; 48904 ta12 /= tdum; 48905 tb1 /= tdum; 48906 48907 s6diff(spoint,sp,kdim,sdiff); 48908 tb2 = s6scpr(sdiff,snorm,kdim); 48909 48910 tdum = MAX(fabs(ta21),fabs(ta22)); 48911 tdum = MAX(tdum,fabs(tb2)); 48912 if (tdum == DZERO) tdum = (double)1.0; 48913 ta21 /= tdum; 48914 ta22 /= tdum; 48915 tb2 /= tdum; 48916 48917 /* Calculate determinant of equation system */ 48918 48919 tdum1 = ta11*ta22 - ta12*ta21; 48920 tdum = MAX(fabs(ta11),fabs(ta22)); 48921 tdum = MAX(fabs(ta12),tdum); 48922 tdum = MAX(fabs(ta21),tdum); 48923 48924 if (DEQUAL((tdum+tdum1),tdum)) tdum1 =DZERO; 48925 48926 48927 /* If tdum1 = 0.0, then the equation system is singular, 48928 iteration not possible */ 48929 48930 if (DNEQUAL(tdum1,DZERO)) 48931 { 48932 gpar1[0] += (tb1*ta22-tb2*ta12)/tdum1; 48933 gpar1[1] += (ta11*tb2-ta21*tb1)/tdum1; 48934 } 48935 48936 /* Put a parametric representation of the 48937 tangent plane of surface 2 into 48938 the implicit representation of the 48939 tangent plane of surface 1 and also 48940 into the implicit representation 48941 of the intersection plane */ 48942 48943 ta11 = s6scpr(sqs,spn,kdim); 48944 ta12 = s6scpr(sqt,spn,kdim); 48945 ta21 = s6scpr(sqs,snorm,kdim); 48946 ta22 = s6scpr(sqt,snorm,kdim); 48947 48948 s6diff(sp,sq,kdim,sdiff); 48949 tb1 = s6scpr(sdiff,spn,kdim); 48950 48951 s6diff(spoint,sq,kdim,sdiff); 48952 tb2 = s6scpr(sdiff,snorm,kdim); 48953 48954 /*Calculate determinant of equation system */ 48955 48956 tdum2 = ta11*ta22 - ta12*ta21; 48957 48958 tdum2 = ta11*ta22 - ta12*ta21; 48959 tdum = MAX(fabs(ta11),fabs(ta22)); 48960 tdum = MAX(fabs(ta12),tdum); 48961 tdum = MAX(fabs(ta21),tdum); 48962 48963 if (DEQUAL((tdum+tdum2),tdum)) tdum2 =DZERO; 48964 48965 /* If tdum2 = 0.0, then the equation system is singular, 48966 iteration not possible */ 48967 48968 if (DNEQUAL(tdum2,DZERO)) 48969 { 48970 gpar2[0] += (tb1*ta22-tb2*ta12)/tdum2; 48971 gpar2[1] += (ta11*tb2-ta21*tb1)/tdum2; 48972 } 48973 48974 /* Calculate values of new points */ 48975 48976 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+18,&kstat); 48977 if (kstat<0) goto error; 48978 48979 /* If the surface normal has zero length no use in continuing */ 48980 48981 if (kstat == 2) goto war02; 48982 48983 s1421(psurf2,kder,gpar2,&klfs,&klft,gpnt2,gpnt2+18,&kstat); 48984 if (kstat<0) goto error; 48985 48986 /* If the surface normal has zero length no use in continuing */ 48987 48988 if (kstat == 2) goto war02; 48989 48990 /* Make difference between the two points, 48991 and calculate length of difference */ 48992 s6diff(gpnt1,gpnt2,kdim,sdiff); 48993 tdum3 = s6length(sdiff,kdim,&kstat); 48994 if (kstat==0) 48995 { 48996 /* Length is zero iteration has converged */ 48997 48998 kcont = 0; 48999 } 49000 49001 if (knbit==0) 49002 { 49003 /* First iteration intitate distance variable, if the equation 49004 systems were not singular */ 49005 49006 if (DEQUAL(tdum1,DZERO) || DEQUAL(tdum2,DZERO)) goto war02; 49007 tdist = tdum3; 49008 knbit = 1; 49009 } 49010 else 49011 { 49012 /* More than one iteration done, stop if distance is not decreasing. 49013 Then decide if we converge distance between the points is within 49014 the tolerance and the last step had singular or none singular 49015 equation systems. */ 49016 49017 knbit = knbit + 1; 49018 if (tdum3>=tdist) 49019 { 49020 /* Distance is not decreasing */ 49021 if (tdist <= aepsge) 49022 { 49023 /* Distance within tolerance */ 49024 if (DEQUAL(tdum1,DZERO) || DEQUAL(tdum2,DZERO)) 49025 { 49026 /* Singular equation system */ 49027 goto war01; 49028 } 49029 else 49030 { 49031 /* Nonsingular equation system */ 49032 goto war00; 49033 } 49034 } 49035 else 49036 { 49037 /* Distance is not within tolerance, divergence */ 49038 goto war02; 49039 } 49040 } 49041 /* Distance still decreasing */ 49042 49043 tdist = tdum3; 49044 } 49045 49046 /* Make sure that not to many iteration are being done */ 49047 if (knbit > kmaxit) goto war02; 49048 } 49049 49050 49051 /* Iteration converged */ 49052 war00: 49053 49054 *jstat = 0; 49055 goto out; 49056 49057 /* Iteration converged, singular point found */ 49058 war01: 49059 *jstat = 1; 49060 goto out; 49061 49062 /* To many iterations or iteration diverging */ 49063 war02: 49064 *jstat = 2; 49065 goto out; 49066 49067 /* Error in lower level routine. */ 49068 49069 error : 49070 *jstat = kstat; 49071 s6err("s9iterate",*jstat,kpos); 49072 goto out; 49073 49074 out: 49075 return; 49076 } 49077 49078 //=========================================================================== 49079 double s6dist(double epoint1[],double epoint2[],int idim) 49080 //=========================================================================== 49081 { 49082 register double *s1,*s2,*s3; /* Pointers used to travers epoint1 and epoint2 49083 arrays. */ 49084 register double tdist=DZERO; /* Distance between the points. */ 49085 49086 for (s1=epoint1,s2=epoint2,s3=epoint1+idim; s1<s3; s1++,s2++) 49087 tdist += (*s1 - *s2)*(*s1 - *s2); 49088 49089 return(sqrt(tdist)); 49090 } 49091 49092 //=========================================================================== 49093 double s1311(double arad,double aepsge,double amax,int *jstat) 49094 //=========================================================================== 49095 { 49096 int kpos=1; /* Position of error */ 49097 double tstep; /* Preliminary value for step length */ 49098 double t1sixth; /* The value of 1/6 */ 49099 double talfa; /* Angle */ 49100 49101 if (amax < DZERO) goto err177; 49102 49103 if (aepsge < DZERO) goto err120; 49104 49105 if (arad > DZERO) 49106 { 49107 t1sixth = (double)1.0/(double)6.0; 49108 /* Estimat the opening angle of the segments based on the error 49109 * formula. */ 49110 talfa = PI*pow(aepsge/arad,t1sixth)/((double)0.4879); 49111 49112 /* Estimate step length equal to curve length of this circular arc, 49113 * We limit the step length to half the radius of curvature */ 49114 49115 tstep = MIN(fabs(talfa*arad),fabs(arad/(double)2.0)); 49116 } 49117 else if (DEQUAL(arad,DZERO)) 49118 { 49119 /* Radius of curvature is zero */ 49120 tstep = (double)100.0*aepsge; 49121 } 49122 49123 else 49124 { 49125 /* Infinit radius of curvatur */ 49126 tstep = amax; 49127 } 49128 49129 if ( amax > DZERO && amax < tstep ) 49130 tstep = MAX(amax,aepsge); 49131 49132 tstep = MAX(tstep,aepsge); 49133 49134 *jstat = 0; 49135 goto out; 49136 49137 /* Negative tolerance */ 49138 49139 err120: *jstat = -120; 49140 s6err("s1311",*jstat,kpos); 49141 goto out; 49142 49143 /* Maximal step length zero are less than geometry tolerance */ 49144 49145 err177: *jstat = -177; 49146 s6err("s1311",*jstat,kpos); 49147 goto out; 49148 49149 out: 49150 return(tstep); 49151 } 49152 49153 //=========================================================================== 49154 double s9adstep(double epnt1[],double epar1[],double epnt2[],double epar2[], 49155 double egd1[],double epgd1[],double egd2[],double epgd2[], 49156 double etang[],double eptan1[],double eptan2[],double astep,int *jstat) 49157 //=========================================================================== 49158 { 49159 int kstat; /* Dummy status variable */ 49160 int kdim=3; /* This routine is only working in 3-D */ 49161 int k2dim=2; /* Dimension of parameter plane */ 49162 double tdum; /* Variable for storage of reals */ 49163 double tdist=DZERO; /* Distance between guide point and point */ 49164 double sdiff[3]; /* Vector for difference between two points*/ 49165 double scr1[3],scr2[3]; /* Normal vectors */ 49166 49167 49168 49169 /* First see that we are not turning direction in the parameter plane 1 49170 */ 49171 49172 s6diff(epgd1,epar1,k2dim,sdiff); 49173 if (s6scpr(sdiff,eptan1,k2dim) <= DZERO) goto dontstepthrough; 49174 49175 /* Then see that we are not turning direction in the parameter plane 2 49176 */ 49177 49178 s6diff(epgd2,epar2,k2dim,sdiff); 49179 if (s6scpr(sdiff,eptan2,k2dim) <= DZERO) goto dontstepthrough; 49180 49181 49182 s6diff(egd1,epnt1,kdim,sdiff); 49183 tdum = s6scpr(sdiff,etang,kdim); 49184 tdist = s6length(sdiff,kdim,&kstat); 49185 *jstat = 0; 49186 if (tdum > DZERO) 49187 { 49188 49189 /* Step onto point if it is within 2.0*astep */ 49190 49191 if (DZERO < tdist && tdist <= (double)2.0*astep) 49192 { 49193 /* Guide point lies within step length and in step direction, test 49194 if cross products of normal vectors at current point and guide point 49195 point in the same direction */ 49196 49197 /* Make cross product of normals in start point */ 49198 s6crss(epnt1+18,epnt2+18,scr1); 49199 49200 /* Make cross product of normals in guide point */ 49201 s6crss(egd1+18,egd2+18,scr2); 49202 49203 /* Make scalar product of these two vectors */ 49204 tdum = s6scpr(scr1,scr2,kdim); 49205 49206 /* If positive scalar product the curve at the two points point in 49207 the same direction, step through point */ 49208 if (tdum > DZERO) goto stepthrough; 49209 else if (tdum == DZERO) 49210 { 49211 49212 double tl1,tl2; 49213 49214 /* Vectors orthogonal or at least one has length zero */ 49215 49216 tl1 = s6length(scr1,kdim,&kstat); 49217 tl2 = s6length(scr2,kdim,&kstat); 49218 49219 if (tl1 != DZERO && tl2 != DZERO) 49220 goto dontstepthrough; 49221 else if (tl1 == DZERO && tl2 == DZERO) 49222 goto stepthrough; 49223 else if (tl2 == DZERO) 49224 goto stepthrough; 49225 else if (tl2 != DZERO) 49226 { 49227 /* Test if scr2 points in the direction from start */ 49228 49229 tl1 = s6scpr(sdiff,scr2,kdim); 49230 49231 if (tl1 < DZERO) 49232 goto dontstepthrough; 49233 else 49234 goto stepthrough; 49235 } 49236 } 49237 } 49238 } 49239 49240 dontstepthrough: 49241 49242 *jstat = 0; 49243 goto out; 49244 49245 stepthrough: 49246 *jstat = 1; 49247 goto out; 49248 49249 out: 49250 return(tdist); 49251 } 49252 49253 //=========================================================================== 49254 void s1361(double epnt1[],double epnt2[],int idim, 49255 double gmidd[],double gmtang[],int *jstat) 49256 //=========================================================================== 49257 { 49258 double tang1,tang2; /* Tangent lengths */ 49259 double tscal1,tscal2; /* The cosine of an angle */ 49260 double ta1,ta2; /* An angle */ 49261 double tlength; /* The length of a vector */ 49262 double tdiff; /* Difference between two numbers */ 49263 double tdist; /* Distance between points */ 49264 double tv2,tv3; /* Vertex compnents */ 49265 int ki; /* Variable in loop */ 49266 int kstat; /* Local status variable */ 49267 49268 /* Find angle between tangents of epnt1 and epnt2, we assume that 49269 the tangents are normalized */ 49270 49271 tscal1 = s6scpr(epnt1+idim,epnt2+idim,idim); 49272 49273 if (tscal1 >= DZERO) 49274 tscal1 = MIN((double)1.0,tscal1); 49275 else 49276 tscal1 = MAX((double)-1.0,tscal1); 49277 49278 ta1 = acos(tscal1); 49279 49280 if (fabs(ta1) < ANGULAR_TOLERANCE) ta1 = DZERO; 49281 49282 49283 /* Make distance between epnt1 and epnt2 */ 49284 49285 tdist = s6dist(epnt1,epnt2,idim); 49286 49287 /* Make tangent lengths for start and end points */ 49288 49289 if (DNEQUAL(ta1,DZERO)) 49290 { 49291 /* Make tangents based on radius of curvature */ 49292 49293 tang1 = s1325(epnt1[3*idim],ta1); 49294 tang2 = s1325(epnt2[3*idim],ta1); 49295 } 49296 49297 /* Make sure that the tangent does not explode due to numeric errors, and 49298 make a controlled tangent when the radius is zero or almost zero */ 49299 49300 /* UJK, October 90, must include the case negative curvature */ 49301 if (DEQUAL(ta1,DZERO) || tang1 > tdist || epnt1[3*idim] <= DZERO) 49302 tang1 = tdist/(double)3.0; 49303 if (DEQUAL(ta1,DZERO) || tang2 > tdist || epnt2[3*idim] <= DZERO) 49304 tang2 = tdist/(double)3.0; 49305 49306 49307 /* We now know the Bezier polygon of the Hermit curve. Make angles 49308 between line 1 and 2 and between line 2 and 3. Make length of line 3 49309 */ 49310 49311 tscal1 = DZERO; 49312 tscal2 = DZERO; 49313 tlength = DZERO; 49314 49315 for (ki=0;ki<idim;ki++) 49316 { 49317 /* Make difference between second and third vertex, and accumulte 49318 scalar products between polygon lines */ 49319 tv2 = epnt1[ki] + tang1*epnt1[ki+idim]; 49320 tv3 = epnt2[ki] - tang2*epnt2[ki+idim]; 49321 tdiff = tv3 - tv2 ; 49322 tlength += tdiff*tdiff; 49323 tscal1 += tdiff*epnt1[ki+idim]; 49324 tscal2 += tdiff*epnt2[ki+idim]; 49325 49326 /* Make midpoint and tangent at midpoint */ 49327 49328 gmidd[ki] = (epnt1[ki] + (double)3.0*(tv2+tv3) + epnt2[ki])/(double)8.0; 49329 gmtang[ki] = (epnt2[ki] + tv3 - tv2 - epnt1[ki])/(double)8.0; 49330 49331 } 49332 tlength = sqrt(tlength); 49333 if (DEQUAL(tlength,DZERO)) tlength = (double)1.0; 49334 49335 tscal1 = tscal1/tlength; 49336 tscal2 = tscal2/tlength; 49337 49338 if (tscal1 >= DZERO) 49339 tscal1 = MIN((double)1.0,tscal1); 49340 else 49341 tscal1 = MAX((double)-1.0,tscal1); 49342 49343 if (tscal2 >= DZERO) 49344 tscal2 = MIN((double)1.0,tscal2); 49345 else 49346 tscal2 = MAX((double)-1.0,tscal2); 49347 49348 ta1 = acos(tscal1); 49349 ta2 = acos(tscal2); 49350 49351 /* Normalize tangent at midpoint */ 49352 49353 (void)s6norm(gmtang,idim,gmtang,&kstat); 49354 49355 49356 /* Make total angular change of polygon */ 49357 49358 ta1 = fabs(ta1) + fabs(ta2); 49359 49360 /* If total angular change is greater than PI/3 or the length is greater 49361 than 0.45 x the distance don't accept. The last condition make sure 49362 that the middle span in the polygon is less that what we get when 49363 we have a 90 circular arc. The first condition makes sure that the 49364 polygon direction is not oscillating too much*/ 49365 49366 if (ta1 > (double)1.0 || tlength > (double)0.45*tdist) 49367 *jstat = 0; 49368 else 49369 *jstat = 1; 49370 } 49371 49372 //=========================================================================== 49373 double s6ang(double evec1[],double evec2[],int idim) 49374 //=========================================================================== 49375 { 49376 double tscpr,tang,tlength1,tlength2,tcos; 49377 int kstat1,kstat2; 49378 49379 tscpr = s6scpr(evec1,evec2,idim); 49380 49381 tlength1 = s6length(evec1,idim,&kstat1); 49382 tlength2 = s6length(evec2,idim,&kstat2); 49383 49384 if (!kstat1 || !kstat2) 49385 tang = DZERO; 49386 else 49387 { 49388 tcos = fabs(tscpr/(tlength1*tlength2)); 49389 tcos = MIN((double)1.0,tcos); 49390 tang = acos(tcos); 49391 } 49392 49393 return(tang); 49394 } 49395 49396 //=========================================================================== 49397 void s1330(double epar11[],double epar12[],double epar21[],double epar22[], 49398 double eval11[],double eval12[],double eval21[],double eval22[], 49399 int *jbound,double gpar1[],double gpar2[],int *jstat) 49400 //=========================================================================== 49401 { 49402 int kstat1,kstat2; /* Local status variable */ 49403 int kstat; /* Local status variable */ 49404 int kpos=0; /* Position of error */ 49405 int kins1; /* epar1 inside/outside SISLbox */ 49406 int kins2; /* epar2 inside/outside SISLbox */ 49407 int kbound1; /*Intersection indicator along boundary of surface 1*/ 49408 int kbound2; /*Intersection indicator along boundary of surface 2*/ 49409 49410 double tdom; /* Denominator of last intersection point */ 49411 double tfak1,tfak2; /* Distance to straight line */ 49412 double spar11[2]; /*Candidate intersection point two first coordinates*/ 49413 double spar12[2]; /*Candidate intersection point two last coordinates */ 49414 double spar21[2]; /*Candidate intersection point two first coordinates*/ 49415 double spar22[2]; /*Candidate intersection point two last coordinates */ 49416 49417 *jbound = 0; 49418 49419 /* Test if both ends are inside */ 49420 49421 kins1 = kins2 = 0; 49422 49423 if (eval11[0] <= epar11[0] && epar11[0] <= eval11[1] && 49424 eval12[0] <= epar11[1] && epar11[1] <= eval12[1] && 49425 eval21[0] <= epar12[0] && epar12[0] <= eval21[1] && 49426 eval22[0] <= epar12[1] && epar12[1] <= eval22[1]) kins1 = 1; 49427 49428 if (eval11[0] <= epar21[0] && epar21[0] <= eval11[1] && 49429 eval12[0] <= epar21[1] && epar21[1] <= eval12[1] && 49430 eval21[0] <= epar22[0] && epar22[0] <= eval21[1] && 49431 eval22[0] <= epar22[1] && epar22[1] <= eval22[1]) kins2 = 1; 49432 49433 49434 /* Test if we step from the boundary and out */ 49435 49436 if ((eval11[0] == epar11[0] && epar21[0] < eval11[0]) || 49437 (epar11[0] == eval11[1] && eval11[1] < epar21[0]) || 49438 (eval12[0] == epar11[1] && epar21[1] < eval12[0]) || 49439 (epar11[1] == eval12[1] && eval12[1] < epar21[1]) || 49440 (eval21[0] == epar12[0] && epar22[0] < eval21[0]) || 49441 (epar12[0] == eval21[1] && eval21[1] < epar22[0]) || 49442 (eval22[0] == epar12[1] && epar22[1] < eval22[0]) || 49443 (epar12[1] == eval22[1] && eval22[1] < epar22[1])) goto war04; 49444 49445 if (kins1==1 && kins2==1) goto war01; 49446 49447 /* Test if both ends are to the left, right, below or above */ 49448 49449 if ( (epar11[0] < eval11[0] && epar21[0] < eval11[0]) || 49450 (eval11[1] < epar11[0] && eval11[1] < epar21[0] ) || 49451 (epar11[1] < eval12[0] && epar21[1] < eval12[0]) || 49452 (eval12[1] < epar11[1] && eval12[1] < epar21[1] ) || 49453 (epar12[0] < eval21[0] && epar22[0] < eval21[0]) || 49454 (eval21[1] < epar12[0] && eval21[1] < epar22[0] ) || 49455 (epar12[1] < eval22[0] && epar22[1] < eval22[0]) || 49456 (eval22[1] < epar12[1] && eval22[1] < epar22[1] ) ) goto war00; 49457 49458 49459 49460 /* Check if intersection in first two dimensions */ 49461 49462 s1305(epar11,epar21,eval11,eval12,&kbound1,spar11,&kstat); 49463 49464 if (kstat<0) goto error; 49465 kstat1 = kstat; 49466 if (kstat1==0) goto war00; 49467 49468 /* Calculate two last coefficients */ 49469 49470 if (kstat1==2 || kstat1==3) 49471 { 49472 tfak1 = fabs(spar11[0]-epar11[0]) + fabs(spar11[1]-epar11[1]); 49473 tfak2 = fabs(epar21[0]-spar11[0]) + fabs(epar21[1]-spar11[1]); 49474 tdom = tfak1 + tfak2; 49475 if (DNEQUAL(tdom,DZERO)) 49476 { 49477 spar12[0] = (tfak2*epar12[0] + tfak1*epar22[0])/tdom; 49478 spar12[1] = (tfak2*epar12[1] + tfak1*epar22[1])/tdom; 49479 49480 /* If the two last coefficients are zero, then then this intersection 49481 point must be discarded */ 49482 49483 if (spar12[0]<eval21[0] || eval21[1]<spar12[0] || 49484 spar12[1]<eval22[0] || eval22[1]<spar12[1]) 49485 { 49486 /* Intersection point outside */ 49487 49488 kbound1 = 0; 49489 } 49490 } 49491 else 49492 { 49493 /* epar1, spar and epar2 has equal first coordinates, since there 49494 is an intersection all must lie on the boundary, thus all are 49495 inside */ 49496 49497 kbound1 = 0; 49498 } 49499 } 49500 else if (kstat1==4 && kins1==1) 49501 { 49502 /* On boundary and stepping out */ 49503 goto war04; 49504 } 49505 49506 /* Check if intersection in last two dimensions */ 49507 49508 s1305(epar12,epar22,eval21,eval22,&kbound2,spar22,&kstat); 49509 49510 if (kstat<0) goto error; 49511 kstat2 = kstat; 49512 if (kstat2==0) goto war00; 49513 49514 if (kstat1==1 && kstat2==1) goto war01; 49515 49516 49517 /* Calculate two last coefficients */ 49518 49519 if (kstat2==2 || kstat2==3) 49520 { 49521 tfak1 = fabs(spar22[0]-epar12[0]) + fabs(spar22[1]-epar12[1]); 49522 tfak2 = fabs(epar22[0]-spar22[0]) + fabs(epar22[1]-spar22[1]); 49523 tdom = tfak1 + tfak2; 49524 if (DNEQUAL(tdom,DZERO)) 49525 { 49526 spar21[0] = (tfak2*epar11[0] + tfak1*epar21[0])/tdom; 49527 spar21[1] = (tfak2*epar11[1] + tfak1*epar21[1])/tdom; 49528 49529 /* If the two last coefficients are zero, then then this intersection 49530 point must be discarded */ 49531 49532 if (spar21[0]<eval11[0] || eval11[1]<spar21[0] || 49533 spar21[1]<eval12[0] || eval12[1]<spar21[1]) 49534 { 49535 /* Intersection point outside */ 49536 49537 kbound2 = 0; 49538 } 49539 } 49540 else 49541 { 49542 /* epar1, spar and epar2 has equal last coordinates, since there 49543 is an intersection all must lie on the boundary, thus all are 49544 inside */ 49545 49546 kbound2 = 0; 49547 } 49548 } 49549 else if (kstat2==4 && kins1==1) 49550 { 49551 /* On boundary and stepping out */ 49552 goto war04; 49553 } 49554 49555 /* kbound1 and kbound2 tells if we have got and intersection with the 49556 boundary */ 49557 49558 49559 /* If intersections along both boundaries then find which intersection 49560 is closest to epar1 */ 49561 49562 if (kbound1!=0 && kbound2!=0) 49563 { 49564 /*guen int t1,t2,t3,t4;*/ /* temporary varuiables */ 49565 /*guen changed to */ 49566 double t1,t2,t3,t4; /* temporary variables */ 49567 49568 t1 = s6dist(spar11,epar11,2); 49569 t2 = s6dist(spar12,epar12,2); 49570 t3 = s6dist(spar21,epar11,2); 49571 t4 = s6dist(spar22,epar12,2); 49572 49573 if ((t1*t1+t2*t2) < (t3*t3+t4*t4) ) 49574 kbound2 = 0; 49575 else 49576 kbound1 = 0; 49577 } 49578 49579 if (kbound1==0 && kbound2 ==0) 49580 { 49581 /* No intersection */ 49582 goto war00; 49583 } 49584 else if (kbound1!=0 && kbound2==0) 49585 { 49586 /* Intersection with boundary of first patch */ 49587 memcopy(gpar1,spar11,2,DOUBLE); 49588 memcopy(gpar2,spar12,2,DOUBLE); 49589 *jbound = kbound1; 49590 } 49591 else if (kbound1==0 && kbound2!=0) 49592 { 49593 /* Intersection with boundary of second patch */ 49594 memcopy(gpar1,spar21,2,DOUBLE); 49595 memcopy(gpar2,spar22,2,DOUBLE); 49596 *jbound = kbound2+4; 49597 } 49598 49599 if (kins1 == 1) 49600 { 49601 if (eval11[0] == epar11[0] || epar11[0] == eval11[1] || 49602 eval12[0] == epar11[1] || epar11[1] == eval12[1] || 49603 eval21[0] == epar12[0] || epar12[0] == eval21[1] || 49604 eval22[0] == epar12[1] || epar12[1] == eval22[1]) 49605 { 49606 goto war04; 49607 } 49608 else 49609 { 49610 goto war02; 49611 } 49612 } 49613 49614 if (kins2 == 1) goto war03; 49615 49616 goto war05; 49617 49618 /* Line outside */ 49619 49620 war00: 49621 *jstat = 0; 49622 goto out; 49623 49624 /* Line inside */ 49625 49626 war01: 49627 *jstat = 1; 49628 goto out; 49629 49630 /* epar1 inside epar2 outside */ 49631 war02: 49632 *jstat = 2; 49633 goto out; 49634 49635 /* epar2 inside epar1 outside */ 49636 war03: 49637 *jstat = 3; 49638 goto out; 49639 49640 /* epar1 on boundary, epar2 outside */ 49641 war04: 49642 *jstat = 4; 49643 goto out; 49644 49645 /* Special error */ 49646 war05: 49647 *jstat = 5; 49648 goto out; 49649 49650 /* Error in lower leve function */ 49651 error: 49652 *jstat = kstat; 49653 s6err("s1330",*jstat,kpos); 49654 goto out; 49655 49656 49657 out: 49658 return; 49659 } 49660 49661 //=========================================================================== 49662 void s9clipit(double epar11[],double epar12[],double epar21[],double epar22[], 49663 SISLSurf *psurf1,SISLSurf *psurf2,double euval[],double evval[], 49664 double esval[], double etval[],double aepsge,double gpnt1[], 49665 double gpnt2[], double gpar1[],double gpar2[],int *jstat) 49666 //=========================================================================== 49667 { 49668 int kpos=0; /* Position of error */ 49669 int klfu=0; /* Variable used as pointer in knot vector */ 49670 int klfv=0; /* Variable used as pointer in knot vector */ 49671 int klfs=0; /* Variable used as pointer in knot vector */ 49672 int klft=0; /* Variable used as pointer in knot vector */ 49673 int kder=2; /* Number of derivatives to be calculated */ 49674 int kstat; /* Local status variable */ 49675 int kdir; /* Parameter direction of tpar */ 49676 int kcross; /* Control variable in while loop */ 49677 int knbit; /* Number of iterations */ 49678 int krem; /* Remember status */ 49679 int kbound; /* Numbering of boundary */ 49680 double tpar; /* Constant parameter value */ 49681 double spnt1[21]; /* Coordinates of point */ 49682 double spnt2[21]; /* Coordinates of point */ 49683 double spar11[2],spar12[2]; /* Local parameter values */ 49684 double spar21[2],spar22[2]; /* Local parameter values */ 49685 double spar31[2],spar32[2]; /* Local parameter values */ 49686 49687 /* Make local copy of parameters */ 49688 49689 memcopy(spar11,epar11,2,DOUBLE); 49690 memcopy(spar12,epar12,2,DOUBLE); 49691 memcopy(spar21,epar21,2,DOUBLE); 49692 memcopy(spar22,epar22,2,DOUBLE); 49693 49694 kcross = 1; 49695 knbit = 0; 49696 49697 while(kcross && knbit<8) 49698 { 49699 49700 /* Find intersection between boundary of parameter area and patch */ 49701 49702 s1330(spar11,spar12,spar21,spar22,euval,evval,esval,etval, 49703 &kbound,spar31,spar32,&kstat); 49704 if (kstat<0) goto error; 49705 49706 /* Remember status so that the line can be updated properly */ 49707 49708 krem = kstat; 49709 49710 if (kstat<2 || kbound == 0) 49711 { 49712 /* No intersection */ 49713 49714 kcross = 0; 49715 } 49716 else 49717 { 49718 49719 /* Calculate start point for iteration */ 49720 49721 s1421(psurf1,kder,spar31,&klfu,&klfv,spnt1,spnt1+18,&kstat); 49722 if (kstat<0) goto error; 49723 49724 s1421(psurf2,kder,spar32,&klfs,&klft,spnt2,spnt2+18,&kstat); 49725 if (kstat<0) goto error; 49726 49727 if (kbound==1) 49728 { 49729 kdir = 1; 49730 tpar = euval[0]; 49731 } 49732 else if (kbound==2) 49733 { 49734 kdir = 2; 49735 tpar = evval[1]; 49736 } 49737 else if (kbound==3) 49738 { 49739 kdir = 1; 49740 tpar = euval[1]; 49741 } 49742 else if (kbound==4) 49743 { 49744 kdir = 2; 49745 tpar = evval[0]; 49746 } 49747 else if (kbound==5) 49748 { 49749 kdir = 3; 49750 tpar = esval[0]; 49751 } 49752 else if (kbound==6) 49753 { 49754 kdir = 4; 49755 tpar = etval[1]; 49756 } 49757 else if (kbound==7) 49758 { 49759 kdir = 3; 49760 tpar = esval[1]; 49761 } 49762 else if (kbound==8) 49763 { 49764 kdir = 4; 49765 tpar = etval[0]; 49766 } 49767 49768 49769 /* Iterate to boundary intersection */ 49770 49771 s9boundit(spnt1,spnt2,spar31,spar32,psurf1,psurf2,tpar,kdir,aepsge, 49772 gpnt1,gpnt2,gpar1,gpar2,&kstat); 49773 if (kstat<0) goto error; 49774 if (kstat==2) goto war02; 49775 49776 /* Iteration converged, copy output if new loop necessary */ 49777 49778 if (krem == 2) 49779 { 49780 /* spar1 was inside, update spar2 */ 49781 49782 memcopy(spar21,gpar1,2,double); 49783 memcopy(spar22,gpar2,2,double); 49784 } 49785 else 49786 { 49787 /* spar2 was inside, update spar1 */ 49788 49789 memcopy(spar11,gpar1,2,double); 49790 memcopy(spar12,gpar2,2,double); 49791 } 49792 49793 /* Update number of iterations */ 49794 49795 knbit++; 49796 } 49797 } 49798 49799 49800 49801 /* Problem solved if kcross==0. In this case we might have two cases: 49802 - iteration not used: Then knbit=0 49803 - iteration used : Then knbit>0 49804 49805 if kcross==1, then we have stopped on the condition knbit>7, and we 49806 have no success. */ 49807 49808 if (kcross==0 && knbit ==0) 49809 { 49810 /* Iteration not used because boundary not crossed */ 49811 49812 *jstat = 0; 49813 } 49814 else if (kcross==0 && knbit > 0) 49815 { 49816 /* Boundary crossed, point found, more than one intersection point 49817 is possible, check which to return */ 49818 49819 if (spar11[0] == epar11[0] && spar11[1] == epar11[1] && 49820 spar12[0] == epar12[0] && spar12[1] == epar12[1] ) 49821 { 49822 memcopy(gpar1,spar21,2,double); 49823 memcopy(gpar2,spar22,2,double); 49824 } 49825 else 49826 { 49827 memcopy(gpar1,spar11,2,double); 49828 memcopy(gpar2,spar12,2,double); 49829 49830 /* Calculate crossing point, only necessary when we step into 49831 the patch since we already could have stepped out and this 49832 point is recorded in gpnt1 */ 49833 49834 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+18,&kstat); 49835 if (kstat<0) goto error; 49836 49837 s1421(psurf2,kder,gpar2,&klfu,&klfv,gpnt2,gpnt2+18,&kstat); 49838 if (kstat<0) goto error; 49839 } 49840 49841 *jstat = 1; 49842 } 49843 else 49844 { 49845 /* To many tries */ 49846 goto war02; 49847 } 49848 goto out; 49849 49850 /* Iteration without success */ 49851 49852 war02: 49853 *jstat = 2; 49854 goto out; 49855 49856 /* Error in lower level routine. */ 49857 49858 error : 49859 *jstat = kstat; 49860 s6err("s9clipit",*jstat,kpos); 49861 goto out; 49862 49863 out: 49864 return; 49865 } 49866 49867 //=========================================================================== 49868 void s6move(double epoint[]) 49869 //=========================================================================== 49870 { 49871 printf("\n s6move: %f %f %f ",epoint[0],epoint[1],epoint[2]); 49872 } 49873 49874 //=========================================================================== 49875 void s6line(double epoint[]) 49876 //=========================================================================== 49877 { 49878 printf("\n s6line: %f %f %f ",epoint[0],epoint[1],epoint[2]); 49879 } 49880 49881 49882 //=========================================================================== 49883 void s1310_s9constline(SISLSurf *ps1,SISLSurf *ps2,SISLIntcurve *pintcr, 49884 double aepsge,int icur,int igraph,int *jstat) 49885 //=========================================================================== 49886 { 49887 int kguide1,kguide2,kguide3,kguide4; /* Pointers to guide points */ 49888 /*int kderc=2; Number of derivatives to be claculated on curve */ 49889 int kders=1; /* Number of derivatives to be calculated on surface*/ 49890 int ki,kj,kl; /* Control variables in for loops */ 49891 int kk,kn,kk1,kn1,kk2,kn2;/* Orders and numbers of knots */ 49892 int kk3,kn3,kk4,kn4;/* Orders and numbers of knots */ 49893 int kpoint; /* Number of points in guide curve */ 49894 int kleft = 0; /* Pointer into knot vector */ 49895 int kpar1; /* Number of parameter direction in 1st. obj */ 49896 int kpar2; /* Number of parameter direction in 2st. obj */ 49897 int ktype; /* Type of intersection curve */ 49898 int kpos=0; /* Position of error */ 49899 int kstat; /* Status variable returned form routine */ 49900 int kdir=0; /* constant parameter line direction */ 49901 int knbpnt; /* Number of points on constant parameter line */ 49902 int kleft1=0,kleft2=0; /* Pointers into knot vectors */ 49903 int kstop; /* Stop value in loop */ 49904 double *sp=SISL_NULL; /* Array for storage of points in 49905 parameter plane */ 49906 double *sv=SISL_NULL; /* Array for storage of tangents in 49907 parameter plane*/ 49908 double *spar=SISL_NULL; /* Array for storage of parameter values */ 49909 double *stp,*stv,*stpar; /* Pointers to sp,sv and spar */ 49910 double tdistp,tdistc; /* Distances between points */ 49911 double tfak; /* Scaling factor */ 49912 double sstart[4]; /* Lower boundary of parameter intervals */ 49913 double send[4]; /* Upper bounadry of parameter intervals */ 49914 double snext[3]; /* Existing iteration point on surface */ 49915 double tmax1,tmin1; /* Minimum and maximum of 1.rst comp of 49916 guide points */ 49917 double tmax2,tmin2; /* Minimum and maximum of 2.nd. comp of 49918 guide points */ 49919 double tmax3,tmin3; /* Minimum and maximum of 3.rd. comp of 49920 guide points */ 49921 double tmax4,tmin4; /* Minimum and maximum of 4.th comp of 49922 guide points */ 49923 double tmax; /* Maximum 3-D SISLbox side */ 49924 double tdist,tang; /* Distance and angle error */ 49925 double *st,*st1,*st2; /* Pointers to knot vectors */ 49926 double *st3,*st4; /* Pointers to knot vectors */ 49927 double *spoint; /* Pointer to points on constant parameter line */ 49928 double *sp1; /* Pointer into array */ 49929 double tsize1,tsize2; /* Length of knot intervals */ 49930 double tsize3,tsize4; /* Length of knot intervals */ 49931 double sval1[2]; /* Limits of parameter plane in first SISLdir */ 49932 double sval2[2]; /* Limits of parameter plane in second SISLdir */ 49933 double sval3[2]; /* Limits of parameter plane in third SISLdir */ 49934 double sval4[2]; /* Limits of parameter plane in fourth SISLdir */ 49935 double sderc[6]; /* SISLPoint and derivative on curve */ 49936 double sders[9]; /* SISLPoint and derivative on curve */ 49937 double snorm[3]; /* Normal on implicit surface */ 49938 double tsumold,tsum,tval;/* Parameter values */ 49939 double ta11,ta12,ta22; /* Coefficients in equation system */ 49940 double tb1,tb2,tdom; /* Left side of eq.syst. and determinant */ 49941 double t1,t2; /* Derivatives in parameter plane */ 49942 double *sgpar1=SISL_NULL; /* Parameter pairs of guide point in surf 1 */ 49943 double *sgpar2=SISL_NULL; /* Parameter pairs of guide point in surf 2 */ 49944 SISLCurve *qc1=SISL_NULL; /* Pointer to 3-D curve */ 49945 SISLCurve *qc2=SISL_NULL; /* Pointer to 3-D curve */ 49946 49947 SISLCurve *qp1cur=SISL_NULL;/* Pointer to curve in first parameter plane*/ 49948 SISLCurve *qp2cur=SISL_NULL;/* Pointer to curve in second parameter plane*/ 49949 SISLSurf *qsurf =SISL_NULL; 49950 SISLPoint *qpoint=SISL_NULL; 49951 49952 49953 /* Make maximal step length based on box-size of surface */ 49954 49955 sh1992su(ps1,0,aepsge,&kstat); 49956 if (kstat < 0) goto error; 49957 49958 tmax = MAX(ps1->pbox->e2max[0][0] - ps1->pbox->e2min[0][0], 49959 ps1->pbox->e2max[0][1] - ps1->pbox->e2min[0][1]); 49960 tmax = MAX(tmax,ps1->pbox->e2max[0][2] - ps1->pbox->e2min[0][2]); 49961 49962 sh1992su(ps2,0,aepsge,&kstat); 49963 if (kstat < 0) goto error; 49964 49965 tmax = MAX(tmax,ps1->pbox->e2max[0][0] - ps1->pbox->e2min[0][0]); 49966 tmax = MAX(tmax,ps1->pbox->e2max[0][1] - ps1->pbox->e2min[0][1]); 49967 tmax = MAX(tmax,ps1->pbox->e2max[0][2] - ps1->pbox->e2min[0][2]); 49968 49969 /* Find a none singular start point for the marching process */ 49970 49971 kpoint = pintcr->ipoint; 49972 kpar1 = pintcr->ipar1; 49973 kpar2 = pintcr->ipar2; 49974 sgpar1 = pintcr->epar1; 49975 sgpar2 = pintcr->epar2; 49976 ktype = pintcr->itype; 49977 49978 49979 /* Initiate pointers to intersection curve and intersection curve in 49980 parameter plane */ 49981 49982 pintcr -> pgeom = SISL_NULL; 49983 pintcr -> ppar1 = SISL_NULL; 49984 pintcr -> ppar2 = SISL_NULL; 49985 49986 49987 49988 /* Test that both objects has 2 parameter direction */ 49989 49990 if (kpar1 == 2 && kpar2 == 2) 49991 { 49992 /* Everything is ok */ 49993 ; 49994 } 49995 else 49996 { 49997 goto err123; 49998 } 49999 50000 50001 /* Run through the parameter pairs to decide if a constant parameter line 50002 is possible */ 50003 50004 tmax1 = tmin1 = sgpar1[0]; 50005 tmax2 = tmin2 = sgpar1[1]; 50006 tmax3 = tmin3 = sgpar2[0]; 50007 tmax4 = tmin4 = sgpar2[1]; 50008 50009 /* Remember which guide point have minimum value in a specific parameter 50010 direction */ 50011 50012 kguide1 = kguide2 = kguide3 = kguide4 = 0; 50013 50014 for (ki=1,kj=2,kl=3 ; ki < kpoint ; ki++,kj+=2,kl+=2) 50015 { 50016 if (tmin1>sgpar1[kj]) 50017 { 50018 tmin1 = sgpar1[kj]; 50019 kguide1 = ki; 50020 } 50021 if (tmin2>sgpar1[kl]) 50022 { 50023 tmin2 = sgpar1[kl]; 50024 kguide2 = ki; 50025 } 50026 if (tmin3>sgpar2[kj]) 50027 { 50028 tmin3 = sgpar2[kj]; 50029 kguide3 = ki; 50030 } 50031 if (tmin4>sgpar2[kl]) 50032 { 50033 tmin4 = sgpar2[kl]; 50034 kguide4 = ki; 50035 } 50036 tmax1 = MAX(tmax1,sgpar1[kj]); 50037 tmax2 = MAX(tmax2,sgpar1[kl]); 50038 tmax3 = MAX(tmax3,sgpar2[kj]); 50039 tmax4 = MAX(tmax4,sgpar2[kl]); 50040 } 50041 50042 /* Initiate parameter direction boundaries */ 50043 kk1 = ps1 -> ik1; 50044 kn1 = ps1 -> in1; 50045 st1 = ps1 -> et1; 50046 sval1[0] = st1[kk1-1]; 50047 sval1[1] = st1[kn1]; 50048 kk2 = ps1 -> ik2; 50049 kn2 = ps1 -> in2; 50050 st2 = ps1 -> et2; 50051 sval2[0] = st2[kk2-1]; 50052 sval2[1] = st2[kn2]; 50053 50054 /* Initiate parameter direction boundaries */ 50055 kk3 = ps2 -> ik1; 50056 kn3 = ps2 -> in1; 50057 st3 = ps2 -> et1; 50058 sval3[0] = st3[kk3-1]; 50059 sval3[1] = st3[kn3]; 50060 kk4 = ps2 -> ik2; 50061 kn4 = ps2 -> in2; 50062 st4 = ps2 -> et2; 50063 sval4[0] = st4[kk4-1]; 50064 sval4[1] = st4[kn4]; 50065 50066 tsize1 = st1[kn1] - st1[kk1-1]; 50067 tsize2 = st2[kn2] - st2[kk2-1]; 50068 tsize3 = st3[kn3] - st3[kk3-1]; 50069 tsize4 = st4[kn4] - st4[kk4-1]; 50070 50071 /* Check if constant parameter value within tolerance */ 50072 50073 if (DEQUAL((tmin1+tsize1),(tmax1+tsize1)) ) 50074 { 50075 /* Intersection possible constant parameter line with first parameter 50076 constant value constant. 50077 50078 1. Pick out curve from surface 50079 2. Pick out relevant part of curve */ 50080 50081 kdir = 1; 50082 50083 s1437(ps1,((tmin1+tmax1)/(double)2.0),&qc1,&kstat); 50084 if (kstat < 0) goto error; 50085 50086 s1712(qc1,tmin2,tmax2,&qc2,&kstat); 50087 if (kstat < 0) goto error; 50088 50089 /* Copy start point of iteration in surface */ 50090 50091 memcopy(snext,sgpar2+2*kguide1,2,DOUBLE); 50092 } 50093 else if (DEQUAL((tmin2+tsize2),(tmax2+tsize2)) ) 50094 { 50095 /* Intersection possible constant parameter line with first parameter 50096 constant value constant. 50097 50098 1. Pick out curve from surface 50099 2. Pick out relevant part of curve 50100 */ 50101 50102 kdir = 2; 50103 50104 s1436(ps1,((tmin2+tmax2)/(double)2.0),&qc1,&kstat); 50105 if (kstat < 0) goto error; 50106 50107 s1712(qc1,tmin1,tmax1,&qc2,&kstat); 50108 if (kstat < 0) goto error; 50109 50110 /* Copy start point of iteration in surface */ 50111 50112 memcopy(snext,sgpar2+2*kguide2,2,DOUBLE); 50113 50114 } 50115 else if (DEQUAL((tmin3+tsize3),(tmax3+tsize3)) ) 50116 { 50117 /* Intersection possible constant parameter line with first parameter 50118 constant value constant from second surface. 50119 50120 1. Pick out curve from surface 50121 2. Pick out relevant part of curve */ 50122 50123 kdir = 3; 50124 50125 s1437(ps2,((tmin3+tmax3)/(double)2.0),&qc1,&kstat); 50126 if (kstat < 0) goto error; 50127 50128 s1712(qc1,tmin4,tmax4,&qc2,&kstat); 50129 if (kstat < 0) goto error; 50130 50131 /* Copy start point of iteration in surface */ 50132 50133 memcopy(snext,sgpar1+2*kguide3,2,DOUBLE); 50134 50135 } 50136 else if (DEQUAL((tmin4+tsize4),(tmax4+tsize4)) ) 50137 { 50138 /* Intersection possible constant parameter line with first parameter 50139 constant value constant. 50140 50141 1. Pick out curve from surface 50142 2. Pick out relevant part of curve */ 50143 50144 kdir = 4; 50145 50146 s1436(ps2,((tmin4+tmax4)/(double)2.0),&qc1,&kstat); 50147 if (kstat < 0) goto error; 50148 50149 s1712(qc1,tmin3,tmax3,&qc2,&kstat); 50150 if (kstat < 0) goto error; 50151 50152 /* Copy start point of iteration in surface */ 50153 50154 memcopy(snext,sgpar1+2*kguide4,2,DOUBLE); 50155 50156 } 50157 else 50158 goto war00; 50159 50160 st = qc2 -> et; 50161 kk = qc2 -> ik; 50162 kn = qc2 -> in; 50163 50164 /* Set boundaries of surface to be iterated in */ 50165 50166 if (kdir==3 || kdir ==4) 50167 { 50168 sstart[0] = sval1[0]; 50169 sstart[1] = sval2[0]; 50170 send[0] = sval1[1]; 50171 send[1] = sval2[1]; 50172 qsurf = ps1; 50173 50174 } 50175 else 50176 { 50177 sstart[0] = sval3[0]; 50178 sstart[1] = sval4[0]; 50179 send[0] = sval3[1]; 50180 send[1] = sval4[1]; 50181 qsurf = ps2; 50182 } 50183 50184 /* Allocate array for storage of points, tangents and parameter values of 50185 curve in the parameter plane of the surface we test */ 50186 50187 if ((sp=newarray(4*kn,DOUBLE)) == SISL_NULL) goto err101; 50188 if ((sv=newarray(4*kn,DOUBLE)) == SISL_NULL) goto err101; 50189 if ((spar=newarray(2*kn,DOUBLE)) == SISL_NULL) goto err101; 50190 50191 50192 /* Run through 2*kn points of the curve and check that they lie in the 50193 implicit surface by calculating the 2*kn points. */ 50194 50195 tsumold = st[kk-1]; 50196 50197 for (ki=0,stp=sp,stv=sv,stpar=spar ; ki <kn ; ki++) 50198 { 50199 if (kk>1) 50200 { 50201 /* Make parameter value to use for calculation of curve point */ 50202 50203 for (kl=1,kj=ki+1,tsum=DZERO ; kl<kk ; kl++) 50204 tsum += st[kj++]; 50205 50206 tsum = tsum/(double)(kk-1); 50207 } 50208 else 50209 tsum = st[ki]; 50210 50211 tval = (tsum+tsumold)/(double)2.0; 50212 50213 for (kj=0 ; kj<2 ; kj++,stp+=2,stv+=2,stpar++) 50214 { 50215 50216 /* Calculate point on curve */ 50217 50218 s1221(qc2,1,tval,&kleft,sderc,&kstat); 50219 if (kstat < 0) goto error; 50220 50221 /* Remember the parameter value */ 50222 50223 *stpar = tval; 50224 50225 /* Find closest point on surface to sderc */ 50226 50227 qpoint = newPoint(sderc,3,0); 50228 if (qpoint==SISL_NULL) goto err101; 50229 50230 /* Calculate closest point to surface */ 50231 50232 s1773(qpoint,qsurf,aepsge,sstart,send,snext,stp,&kstat); 50233 if(kstat<0) goto error; 50234 50235 freePoint(qpoint); 50236 50237 /* Calculate point and derivatives in surface */ 50238 50239 s1421(qsurf,kders,stp,&kleft1,&kleft2,sders,snorm,&kstat); 50240 50241 if (kstat<0) goto error; 50242 50243 /* Find tangent of curve in parameter plane */ 50244 50245 ta11 = s6scpr(sders+3,sders+3,3); 50246 ta12 = s6scpr(sders+3,sders+6,3); 50247 ta22 = s6scpr(sders+6,sders+6,3); 50248 tb1 = s6scpr(sders+3,sderc+3,3); 50249 tb2 = s6scpr(sders+6,sderc+3,3); 50250 50251 tdom = ta11*ta22 - ta12*ta12; 50252 if (tdom != DZERO) 50253 { 50254 t1 = (ta22*tb1-ta12*tb2)/tdom; 50255 t2 = (ta11*tb2-ta12*tb1)/tdom; 50256 50257 tdom = sqrt(t1*t1+t2*t2); 50258 if (tdom != DZERO) 50259 { 50260 t1 /= tdom; 50261 t2 /= tdom; 50262 } 50263 } 50264 else 50265 t1 = t2 = DZERO; 50266 50267 /* Remember the tangent */ 50268 50269 *stv = t1; 50270 *(stv+1) = t2; 50271 50272 50273 /*Both the position of the two points should be within the relative 50274 computer resolution for the point to be accepted. 50275 Correspondingly the direction of the intersection curve and the 50276 constant parameter line should be within the computer 50277 resolution to be accepted. */ 50278 50279 tdist = s6dist(sders,sderc,3); 50280 50281 if (DNEQUAL(tdist+tmax,tmax)) 50282 goto war00; 50283 50284 /* Distance within tolerance, check that the angle between surface 50285 normal and curve tangent is PIHALF, if both these vectors have a 50286 nonzero length. */ 50287 50288 if (s6length(snorm,3,&kstat) != DZERO && 50289 s6length(sderc+3,3,&kstat) != DZERO ) 50290 { 50291 tang = s6ang(snorm,sderc+3,3); 50292 if (DNEQUAL(fabs(tang),PIHALF) ) goto war00; 50293 } 50294 tval = tsum; 50295 50296 /* Remember start point of iteration */ 50297 50298 memcopy(snext,stp,2,DOUBLE); 50299 } 50300 tsumold = tsum; 50301 } 50302 50303 /* Intersection curve along constant parameter line, make right actions 50304 concerning drawing and/or creation of the curve */ 50305 50306 if (igraph == 1) 50307 { 50308 /* Draw curve, first break into straight line segments */ 50309 50310 s1605(qc2,aepsge,&spoint,&knbpnt,&kstat); 50311 if (kstat < 0) goto error; 50312 50313 if (knbpnt>1) 50314 { 50315 /* Draw curve */ 50316 50317 s6move(spoint); 50318 for (ki=1,sp1=spoint+3 ; ki<knbpnt ; ki++,sp1+=3) 50319 s6line(sp1); 50320 } 50321 freearray(spoint); 50322 } 50323 50324 if (icur >= 1) 50325 { 50326 /* Set pointer to 3-D curve */ 50327 50328 pintcr -> pgeom = qc2; 50329 qc2 = SISL_NULL; 50330 } 50331 50332 if (icur == 2) 50333 { 50334 /* Make curves in parameter planes */ 50335 50336 double svert[4],sknot[4]; 50337 50338 50339 /* Adjust the tangent lengths to match distance between adjacent points, 50340 remember that first and second points are equal and that first point 50341 is not used futher on */ 50342 50343 tdistp = s6dist(sp+2,sp+4,2); 50344 *(sv+2) *= tdistp; 50345 *(sv+3) *= tdistp; 50346 50347 for (ki=2,stp=sp+4,stv=sv+4,kstop=kn+kn-1 ; ki < kstop ; 50348 ki++,stp+=2,stv+=2) 50349 { 50350 tdistc = s6dist(stp,stp+2,2); 50351 tfak = (tdistp+tdistc)/(double)2.0; 50352 *stv *= tfak, 50353 *(stv+1) *= tfak; 50354 tdistp = tdistc; 50355 } 50356 *stv *= tdistp; 50357 *(stv+1) *= tdistp; 50358 50359 50360 /* The first parameter pair is doubly represented */ 50361 50362 stp = sp+2; 50363 stv = sv+2; 50364 stpar = spar+1; 50365 50366 if (kdir==1) 50367 { 50368 svert[0] = svert[2] = (tmin1+tmax1)/(double)2.0; 50369 svert[1] = tmin2; 50370 svert[3] = tmax2; 50371 sknot[0] = sknot[1] = tmin2; 50372 sknot[2] = sknot[3] = tmax2; 50373 qp1cur = newCurve(2,2,sknot,svert,1,2,1); 50374 if (qp1cur==SISL_NULL) goto err101; 50375 s1379(stp,stv,stpar,2*kn-1,2,&qp2cur,&kstat); 50376 if (kstat<0) goto error; 50377 } 50378 else if (kdir==2) 50379 { 50380 svert[0] = tmin1; 50381 svert[2] = tmax1; 50382 svert[1] = svert[3] = (tmin2+tmax2)/(double)2.0; 50383 sknot[0] = sknot[1] = tmin1; 50384 sknot[2] = sknot[3] = tmax1; 50385 qp1cur = newCurve(2,2,sknot,svert,1,2,1); 50386 if (qp1cur==SISL_NULL) goto err101; 50387 s1379(stp,stv,stpar,2*kn-1,2,&qp2cur,&kstat); 50388 if (kstat<0) goto error; 50389 } 50390 else if (kdir==3) 50391 { 50392 svert[0] = svert[2] = (tmin3+tmax3)/(double)2.0; 50393 svert[1] = tmin4; 50394 svert[3] = tmax4; 50395 sknot[0] = sknot[1] = tmin4; 50396 sknot[2] = sknot[3] = tmax4; 50397 qp2cur = newCurve(2,2,sknot,svert,1,2,1); 50398 if (qp2cur==SISL_NULL) goto err101; 50399 s1379(stp,stv,stpar,2*kn-1,2,&qp1cur,&kstat); 50400 if (kstat<0) goto error; 50401 } 50402 else 50403 { 50404 svert[0] = tmin3; 50405 svert[2] = tmax3; 50406 svert[1] = svert[3] = (tmin4+tmax4)/(double)2.0; 50407 sknot[0] = sknot[1] = tmin3; 50408 sknot[2] = sknot[3] = tmax3; 50409 qp2cur = newCurve(2,2,sknot,svert,1,2,1); 50410 if (qp2cur==SISL_NULL) goto err101; 50411 s1379(stp,stv,stpar,2*kn-1,2,&qp1cur,&kstat); 50412 if (kstat<0) goto error; 50413 } 50414 pintcr -> ppar1 = qp1cur; 50415 pintcr -> ppar2 = qp2cur; 50416 } 50417 50418 *jstat = 1; 50419 goto out; 50420 50421 /* Iteration can not continue */ 50422 war00: *jstat = 0; 50423 goto out; 50424 50425 50426 /* Error in space allocation */ 50427 err101: *jstat = -101; 50428 s6err("s1310_s9constline",*jstat,kpos); 50429 goto out; 50430 50431 /* Error in surface description parameter direction does not exist */ 50432 err123: *jstat = -123; 50433 s6err("s1310_s9constline",*jstat,kpos); 50434 goto out; 50435 50436 /* Error in lower leve function */ 50437 error: 50438 *jstat = kstat; 50439 s6err("s1310_s9constline",*jstat,kpos); 50440 goto out; 50441 50442 out:; 50443 if (qc1 != SISL_NULL) freeCurve(qc1); 50444 if (qc2 != SISL_NULL) freeCurve(qc2); 50445 if (sp != SISL_NULL) freearray(sp); 50446 if (sv != SISL_NULL) freearray(sv); 50447 if (spar != SISL_NULL) freearray(spar); 50448 } 50449 50450 //=========================================================================== 50451 void make_sf_kreg (SISLSurf * ps, SISLSurf ** rsnew, int *jstat) 50452 //=========================================================================== 50453 { 50454 int kn1=ps->in1; /* Number of vertices in 1. par. dir. */ 50455 int kn2=ps->in2; /* Number of vertices in 2. par. dir. */ 50456 int kk1=ps->ik1; /* Order in 1. par. dir. */ 50457 int kk2=ps->ik2; /* Order in 2. par. dir. */ 50458 /* --------------------------------------------------------- */ 50459 50460 s1001 (ps, ps->et1[kk1-1], ps->et2[kk2-1], 50461 ps->et1[kn1], ps->et2[kn2], rsnew, jstat); 50462 if (*jstat < 0) goto error; 50463 50464 goto out; 50465 50466 /* Error in lower level routine */ 50467 error: 50468 s6err ("make_sf_kreg", *jstat, 0); 50469 50470 out:; 50471 50472 } 50473 50474 //=========================================================================== 50475 void s1329(SISLSurf *psold,double epoint[],double enorm[],int idim, 50476 SISLSurf **rsnew,int *jstat) 50477 //=========================================================================== 50478 { 50479 int kpos = 0; /* Position of error. */ 50480 int kdim; /* Dimension of the space in which the output 50481 surface lies. */ 50482 int kn1,kn2; /* Number of coefficients of surface. */ 50483 int kk1,kk2; /* Order of surface. */ 50484 int ikind; /* kind of surface psold is */ 50485 double *scoef = SISL_NULL; /* Coeffecient array of new surface. */ 50486 double *s1,*s2; /* Pointers used to traverse scoef. */ 50487 double *sc=SISL_NULL; /* Pointer used to traverse psold->ecoef. */ 50488 double *scSave=SISL_NULL; /* Pointer to vertices in rational case. */ 50489 double *rscoef; /* Scaled coefficients if psold is rational */ 50490 double *s3; /* Stop pointer for each vertex in psold->ecoef. */ 50491 double *spoint; /* Pointer used to traverse the point epoint. */ 50492 double *snorm; /* Pointer used to traverse the normal enorm. */ 50493 double wmin,wmax;/* min and max values of the weights if rational */ 50494 double scale; /* factor for scaling weights if rational */ 50495 int i; /* loop variable */ 50496 int idimp1; /* idim+1 */ 50497 50498 /* Test input. */ 50499 50500 if (idim != psold -> idim) goto err106; 50501 50502 /* Set simple variables of the new surface. */ 50503 50504 kdim = 1; 50505 kn1 = psold -> in1; 50506 kn2 = psold -> in2; 50507 kk1 = psold -> ik1; 50508 kk2 = psold -> ik2; 50509 ikind = psold -> ikind; 50510 50511 /* rational surfaces are a special case */ 50512 if(ikind == 2 || ikind == 4) 50513 { 50514 /* scale the coeffs so that min. weight * max. weight = 1 */ 50515 idimp1=idim+1; 50516 rscoef = psold -> rcoef; 50517 wmin=rscoef[idim]; 50518 wmax=rscoef[idim]; 50519 for(i=idim; i< kn1*kn2*idimp1; i+=idimp1) 50520 { 50521 if(rscoef[i] < wmin) wmin=rscoef[i]; 50522 if(rscoef[i] > wmax) wmax=rscoef[i]; 50523 } 50524 scale=1.0/sqrt(wmin*wmax); 50525 if ((sc = newarray(idimp1*kn1*kn2,DOUBLE)) == SISL_NULL) goto err101; 50526 for(i=0; i< kn1*kn2*idimp1; i++) 50527 { 50528 sc[i]=rscoef[i]*scale; 50529 } 50530 50531 scSave = sc; 50532 } 50533 else 50534 { 50535 sc = psold -> ecoef; 50536 } 50537 50538 /* Allocate space for coeffecient of the new surface. */ 50539 50540 if ((scoef = newarray(kdim*kn1*kn2,DOUBLE)) == SISL_NULL) goto err101; 50541 50542 /* Compute coefficients of new surface. */ 50543 50544 for (s1=scoef,s2=s1+kn1*kn2; s1<s2; s1++) 50545 { 50546 *s1 = (double)0.0; 50547 if(ikind == 2 || ikind == 4) 50548 { 50549 /* surface is rational so we're using idim+1 - d homogeneous coords */ 50550 for (s3=sc+idim,spoint=epoint,snorm=enorm; sc<s3; sc++,spoint++,snorm++) 50551 { 50552 /* UJK, Turned direction to get right sign in 1D*/ 50553 /* *s1 += ((*s3)*(*spoint) - *sc)*(*snorm); */ 50554 *s1 += (*sc - (*s3)*(*spoint))*(*snorm); 50555 } 50556 sc++; 50557 } 50558 else 50559 { 50560 /* surface is not rational so we're using ordinary idim - d coords */ 50561 for (s3=sc+idim,spoint=epoint,snorm=enorm; sc<s3; sc++,spoint++,snorm++) 50562 /* UJK, Turned direction to get right sign in 1D*/ 50563 /* *s1 += (*spoint - *sc)*(*snorm); */ 50564 *s1 += (*sc - *spoint)*(*snorm); 50565 } 50566 } 50567 50568 if(ikind == 2 || ikind == 4) freearray(scSave); 50569 50570 /* Create output surface. */ 50571 50572 *rsnew = newSurf(kn1,kn2,kk1,kk2,psold->et1,psold->et2,scoef,1,kdim,1); 50573 if (*rsnew == SISL_NULL) goto err101; 50574 50575 /* Task done. */ 50576 50577 *jstat = 0; 50578 goto out; 50579 50580 /* Error in space allocation. */ 50581 50582 err101: 50583 *jstat = -101; 50584 s6err("s1329",*jstat,kpos); 50585 goto out; 50586 50587 /* Error in input. Confliction dimensions. */ 50588 50589 err106 : 50590 *jstat = -106; 50591 s6err("s1329",*jstat,kpos); 50592 goto out; 50593 50594 out: 50595 /* Free space allocated for local array. */ 50596 50597 if (scoef != SISL_NULL) freearray(scoef); 50598 return; 50599 } 50600 50601 //=========================================================================== 50602 SISLPoint *newPoint (double *ecoef, int idim, int icopy) 50603 //=========================================================================== 50604 { 50605 SISLPoint *qnew; /* Local pointer to new point. */ 50606 double *scoef = SISL_NULL; /* Copy of coordinates */ 50607 50608 50609 /* Allocate space for point. */ 50610 50611 if ((qnew = newarray (1, SISLPoint)) == SISL_NULL) 50612 goto err101; 50613 50614 50615 if (icopy == 1) 50616 { 50617 50618 /* Copy input array. First allocate space for new array. */ 50619 50620 if (idim < 4) scoef = qnew->ec; 50621 else if ((scoef = newarray (idim, double)) == SISL_NULL) goto err101; 50622 50623 /* Copy contents of arrays. */ 50624 50625 memcopy (scoef, ecoef, idim, double); 50626 } 50627 else 50628 { 50629 scoef = ecoef; 50630 } 50631 50632 /* Initialize new point. */ 50633 50634 qnew->idim = idim; 50635 qnew->icopy = icopy; 50636 qnew->ecoef = scoef; 50637 qnew->pbox = SISL_NULL; 50638 50639 /* Task done. */ 50640 50641 goto out; 50642 50643 /* Error in space allocation. Return zero. */ 50644 50645 err101:if (qnew != SISL_NULL) 50646 freearray (qnew); 50647 qnew = SISL_NULL; 50648 goto out; 50649 out:return qnew; 50650 } 50651 50652 //=========================================================================== 50653 void freePoint(SISLPoint *ppoint) 50654 //=========================================================================== 50655 { 50656 int ki; /* Counter. */ 50657 50658 if (ppoint != SISL_NULL) 50659 { 50660 if (ppoint -> pbox != SISL_NULL) 50661 { 50662 if (ppoint->pbox->emax) freearray(ppoint->pbox->emax); 50663 if (ppoint->pbox->emin) freearray(ppoint->pbox->emin); 50664 50665 for (ki=0; ki<3; ki++) 50666 { 50667 if (ppoint->pbox->e2max[ki]) freearray(ppoint->pbox->e2max[ki]); 50668 if (ppoint->pbox->e2min[ki]) freearray(ppoint->pbox->e2min[ki]); 50669 } 50670 freearray(ppoint->pbox); 50671 } 50672 50673 if ((ppoint -> idim > 3) && 50674 (ppoint -> icopy != 0) && 50675 (ppoint -> ecoef != SISL_NULL)) 50676 freearray(ppoint -> ecoef); /* Free array. */ 50677 50678 freearray(ppoint); /* Free instance of point. */ 50679 } 50680 return; 50681 } 50682 50683 //=========================================================================== 50684 void sh6degen_geom(SISLObject *po1,SISLObject *po2,double epar[], 50685 double geom[],int *jstat) 50686 //=========================================================================== 50687 { 50688 int kstat = 0; /* Local status variable. */ 50689 int kdim; /* Dimension. */ 50690 int kder = 0; /* Evaluate position. */ 50691 int kleft1 = 0; /* Parameter to the evaluator. */ 50692 int kleft2 = 0; /* Parameter to the evaluator. */ 50693 int keval = *jstat; /* Indicates which object to evaluate. */ 50694 double sder[3]; /* Position and derivatives. */ 50695 double snorm[3]; /* Dummy normal in surf. evalutation. */ 50696 50697 *jstat = 0; 50698 if (keval == 0) 50699 { 50700 if (po1->iobj == SISLSURFACE) 50701 { 50702 /* Evaluate the surface. */ 50703 50704 kdim = po1->s1->idim; 50705 s1421(po1->s1,kder,epar,&kleft1,&kleft2,sder,snorm,&kstat); 50706 if (kstat < 0) goto error; 50707 } 50708 50709 else if (po1->iobj == SISLCURVE) 50710 { 50711 50712 /* Evaluate the curve. */ 50713 50714 kdim = po1->c1->idim; 50715 s1221(po1->c1,kder,epar[0],&kleft1,sder,&kstat); 50716 if (kstat < 0) goto error; 50717 } 50718 50719 else if (po1->iobj == SISLPOINT) 50720 { 50721 50722 /* Copy the value of the point. */ 50723 50724 kdim = po1->p1->idim; 50725 memcopy(sder,po1->p1->ecoef,kdim,DOUBLE); 50726 } 50727 } 50728 else if (keval == 1) 50729 { 50730 if (po2->iobj == SISLSURFACE) 50731 { 50732 /* Evaluate the surface. */ 50733 50734 kdim = po2->s1->idim; 50735 s1421(po2->s1,kder,epar+po1->iobj,&kleft1,&kleft2,sder,snorm,&kstat); 50736 if (kstat < 0) goto error; 50737 } 50738 50739 else if (po2->iobj == SISLCURVE) 50740 { 50741 50742 /* Evaluate the curve. */ 50743 50744 kdim = po2->c1->idim; 50745 s1221(po2->c1,kder,epar[po1->iobj],&kleft1,sder,&kstat); 50746 if (kstat < 0) goto error; 50747 } 50748 50749 else if (po2->iobj == SISLPOINT) 50750 { 50751 50752 /* Copy the value of the point. */ 50753 50754 kdim = po2->p1->idim; 50755 memcopy(sder,po1->p1->ecoef,kdim,DOUBLE); 50756 } 50757 } 50758 50759 50760 /* Copy result to output. */ 50761 50762 memcopy(geom,sder,kdim,DOUBLE); 50763 50764 *jstat = 0; 50765 goto out; 50766 50767 /* Error in lower level function. */ 50768 50769 error : 50770 *jstat = kstat; 50771 goto out; 50772 50773 out : 50774 return; 50775 } 50776 50777 //=========================================================================== 50778 void sh6degen(SISLObject * po1, SISLObject * po2, SISLIntdat ** pintdat, 50779 double aepsge, int *jstat) 50780 //=========================================================================== 50781 { 50782 int kstat; /* Local status variable. */ 50783 int kpos = 0; /* Position of error. */ 50784 int ki,kj, kl; /* Loop variables. */ 50785 int kpoint; /* Number of points in list. */ 50786 int kstoremark; /* Save marker of point. */ 50787 int knumbpt; /* Number of points in intersection list. */ 50788 int knpar; /* Number of parameter directions. */ 50789 int kexact; /* Indicates which parameter direction is exact. */ 50790 SISLIntpt** vpoint; /* Array of Int points. */ 50791 int ipoint; /* Number of Intpoints. */ 50792 int ipmax; /* Size of vpoint array. */ 50793 SISLIntlist** vlist; /* Array of Intlists. */ 50794 int ilist; /* Number of Intlists. */ 50795 int ilmax; /* Size of vlist array. */ 50796 int isdegen; /* Flag. Is curve degenerate? */ 50797 double spar[4]; /* Parameter value on intersection curve of 50798 the objects. */ 50799 SISLIntpt *pprev, *pcurr, *pnext; /* Pointers to Intpts. */ 50800 SISLIntpt *pfirst, *plast; /* Pointers to Intpts. */ 50801 SISLIntpt *qpt; 50802 SISLObject *qo2=SISL_NULL; /* Either po2 or dummy point. */ 50803 int newilist; /* New number of Intlists. */ 50804 int idim; /* Dimension of space. */ 50805 double geomfirst[3]; /* geometric info --- position etc. */ 50806 double geomcurr[3]; /* geometric info --- position etc. */ 50807 double geommid[3]; /* geometric info --- position etc. */ 50808 double len; /* Distance between two vectors. */ 50809 50810 knpar = po1->iobj + po2->iobj; 50811 *jstat = 0; 50812 50813 if(*pintdat == SISL_NULL) goto out; 50814 50815 /* Set up local variables. */ 50816 50817 vpoint = (*pintdat) -> vpoint; 50818 ipoint = (*pintdat) -> ipoint; 50819 ipmax = (*pintdat) -> ipmax; 50820 vlist = (*pintdat) -> vlist; 50821 ilist = (*pintdat) -> ilist; 50822 ilmax = (*pintdat) -> ilmax; 50823 50824 if(ipoint == 0 && ilist == 0) goto out; 50825 50826 /* Make dimension of geometry space. */ 50827 50828 if (po1->iobj == SISLPOINT) idim = po1->p1->idim; 50829 else if (po1->iobj == SISLCURVE) idim = po1->c1->idim; 50830 else idim = po1->s1->idim; 50831 50832 /* UJK, feb 93, often po1 and po2 is the same geometry ie po2 50833 is a dummy, so let create a dummy point in those cases. */ 50834 if ((*pintdat) -> vpoint[0]->ipar == po1->iobj) 50835 { 50836 if ((qo2 = newObject(SISLPOINT)) == SISL_NULL) goto err101; 50837 knpar = po1->iobj; 50838 } 50839 else qo2 = po2; 50840 50841 50842 for(ki=0; ki<ilist; ki++) 50843 { 50844 /* Find out whether the curve vlist[ki] is degenerate. 50845 We assume that if all the guide points in vlist[ki] 50846 are equal then it is degenerate. This should be 50847 correct if SISL has done its job properly before 50848 reaching this stage of the intersection algorithm. 50849 Otherwise it clearly is not degenerate. */ 50850 50851 50852 isdegen = TRUE; 50853 50854 pfirst = vlist[ki]->pfirst; 50855 plast = vlist[ki]->plast; 50856 knumbpt = vlist[ki]->inumb; 50857 50858 /* VSK, 02-93. Check if the list describes a trimming area. 50859 In that case no reduction is to be performed. */ 50860 50861 if (pfirst->iinter == SI_TRIM) continue; 50862 50863 kstat = 0; 50864 sh6degen_geom(po1,qo2,pfirst->epar,geomfirst,&kstat); 50865 if(kstat < 0) goto error; 50866 50867 pprev = pfirst; 50868 50869 pcurr = sh6getnext(pprev,vlist[ki]->ind_first); 50870 50871 /* Loop through the guide points and compare with pfirst. */ 50872 50873 while(pcurr != plast) 50874 { 50875 kstat = 0; 50876 sh6degen_geom(po1,qo2,pcurr->epar,geomcurr,&kstat); 50877 if(kstat < 0) goto error; 50878 50879 len = s6dist(geomcurr,geomfirst,idim); 50880 if(len > aepsge) 50881 { 50882 isdegen = FALSE; 50883 break; 50884 } 50885 50886 sh6getother(pcurr,pprev,&pnext,&kstat); 50887 if(kstat < 0) goto error; 50888 50889 pprev = pcurr; 50890 pcurr = pnext; 50891 } 50892 50893 /* Compare plast with pfirst. */ 50894 50895 if(isdegen == TRUE) 50896 { 50897 kstat = 0; 50898 sh6degen_geom(po1,qo2,plast->epar,geomcurr,&kstat); 50899 if(kstat < 0) goto error; 50900 50901 len = s6dist(geomcurr,geomfirst,idim); 50902 if(len > aepsge) 50903 { 50904 isdegen = FALSE; 50905 } 50906 } 50907 50908 /* Test if it is only 2 points in the intersection list. In that 50909 case it may be a cyclic constant parameter curve, and it is 50910 necessary to check in an internal point. */ 50911 50912 if (isdegen && knumbpt == 2) 50913 { 50914 for (kexact=0, kj=0; kj<knpar; kj++) 50915 { 50916 if (pfirst->curve_dir[vlist[ki]->ind_first] & 50917 (1 << (kj + 1))) 50918 kexact = kj + 1; 50919 spar[kj] = (double)0.5*(pfirst->epar[kj]+plast->epar[kj]); 50920 50921 } 50922 50923 /* UJK, 930811: 50924 kstat = (kexact == 0 || kexact > po1->iobj) ? 1 : 0; */ 50925 kstat = (kexact > po1->iobj) ? 1 : 0; 50926 sh6degen_geom(po1,qo2,spar,geommid,&kstat); 50927 50928 len = s6dist(geommid,geomfirst,idim); 50929 if(len > aepsge) 50930 { 50931 isdegen = FALSE; 50932 } 50933 else 50934 { 50935 len = s6dist(geommid,geomcurr,idim); 50936 if(len > aepsge) 50937 { 50938 isdegen = FALSE; 50939 } 50940 } 50941 50942 } 50943 50944 if(isdegen == TRUE) 50945 { 50946 /* Curve vlist[ki] is degenerate, i.e. it's just a point. 50947 Free the list in pintdat, but make sure that there is one 50948 point left. If there is a point that is an endpoint of an 50949 other list, and that are equal to this degenerate list, 50950 this endpoint should represent these point. 50951 50952 First pass through the list and mark all points as removed. */ 50953 50954 pcurr = pfirst; 50955 kstoremark = pfirst->marker; 50956 pnext = sh6getnext(pcurr,vlist[ki]->ind_first); 50957 kpoint = vlist[ki]->inumb; 50958 50959 for (kl=0; kl<kpoint; kl++) 50960 { 50961 /* Mark the point as removed. */ 50962 50963 pcurr->marker = -99; 50964 50965 pprev = pcurr; 50966 pcurr = pnext; 50967 50968 if (kl < kpoint-1) 50969 { 50970 sh6getother(pcurr,pprev,&pnext,&kstat); 50971 if (kstat < 0) goto error; 50972 } 50973 } 50974 50975 /* Free the list. */ 50976 50977 freeIntlist(vlist[ki]); 50978 vlist[ki] = SISL_NULL; 50979 50980 /* Check the intersection points. If no point represent the 50981 degenerated curve,restore the first point of the curve. */ 50982 50983 for(kj=0; kj<ipoint; kj++) 50984 { 50985 qpt = vpoint[kj]; 50986 if (qpt->marker == -99) continue; 50987 kstat = 0; 50988 sh6degen_geom(po1,qo2,qpt->epar,geomcurr,&kstat); 50989 if(kstat < 0) goto error; 50990 50991 len = s6dist(geomfirst,geomcurr,idim); 50992 if(len <= aepsge) break; 50993 } 50994 if (kj >= ipoint) pfirst->marker = kstoremark; 50995 50996 } 50997 } 50998 50999 /* Tidy up the vlist array afterwards since some of the 51000 lists have been freed. */ 51001 51002 newilist = 0; 51003 51004 for(ki=0; ki<ilist; ki++) 51005 { 51006 if(vlist[ki] != SISL_NULL) 51007 { 51008 newilist++; 51009 if(newilist < ki+1) 51010 { 51011 vlist[newilist-1] = vlist[ki]; 51012 vlist[ki] = SISL_NULL; 51013 } 51014 } 51015 } 51016 51017 ilist = newilist; 51018 51019 /* Pass through the points and remove all marked points. */ 51020 51021 for (kj=0; kj<(*pintdat) -> ipoint; ) 51022 { 51023 qpt = (*pintdat)->vpoint[kj]; 51024 if (qpt->marker == -99) 51025 { 51026 /* Remove point. */ 51027 51028 sh6idkpt (pintdat, &qpt, 0, &kstat); 51029 if (kstat < 0) goto error; 51030 } 51031 else kj++; 51032 } 51033 51034 /* Reset the integer pintdat variables with the local 51035 ones in case they have changed. */ 51036 51037 (*pintdat)->ipmax = ipmax; 51038 (*pintdat)->ilist = ilist; 51039 (*pintdat)->ilmax = ilmax; 51040 51041 51042 /* Degeneracies removed. Finish. */ 51043 51044 *jstat = 0; 51045 goto out; 51046 51047 /* Error in alloc. */ 51048 err101: 51049 *jstat = -101; 51050 s6err ("sh6degen", *jstat, kpos); 51051 goto out; 51052 51053 /* Error in lower level routine. */ 51054 error: 51055 *jstat = kstat; 51056 s6err ("sh6degen", *jstat, kpos); 51057 goto out; 51058 51059 out: 51060 if (qo2 && qo2 != po2) freeObject(qo2); 51061 51062 } 51063 51064 //=========================================================================== 51065 void refine_all (SISLIntdat ** pintdat, SISLObject * po1, SISLObject * po2, 51066 double eimpli[], int ideg, double aepsge, int *jstat) 51067 //=========================================================================== 51068 { 51069 *jstat = 0; 51070 } 51071 51072 //=========================================================================== 51073 void s1227(SISLCurve *pc1,int ider,double ax,int *ileft,double eder[],int *jstat) 51074 //=========================================================================== 51075 { 51076 int kind; /* Type of curve */ 51077 int kstat=0; /* Local status variable. */ 51078 int kpos=0; /* The position of the error. */ 51079 int kn; /* The number of B-splines, i.e., the dimension of 51080 the spline space associated with the knot 51081 vector. */ 51082 int kk; /* The polynomial order of the curve. */ 51083 int kmult; /* Multiplicity of knot value */ 51084 int kdim; /* The dimension of the space in which the curve 51085 lies. Equivalently, the number of components 51086 of each B-spline coefficient. */ 51087 int kleft=0; /* Local version of ileft which is used in order to 51088 avoid the pointer. */ 51089 int kder; /* Local version of ider. Since derivatives of order 51090 higher than kk-1 are all zero, we set 51091 kder = min(kk-1,ider). */ 51092 int ki,kj,kih,kjh; /* Control variables in for loops and for stepping 51093 through arrays. */ 51094 int kl,kl1,kl2; /* Control variables in for loops and for stepping 51095 through arrays. */ 51096 double *st; /* Pointer to the first element of the knot vector 51097 of the curve. The knot vector has [kn+kk] 51098 elements. */ 51099 double *scoef; /* Pointer to the first element of the curve's 51100 B-spline coefficients. This is assumed to be an 51101 array with [kn*kdim] elements stored in the 51102 following order: 51103 First the kdim components of the first B-spline 51104 coefficient, then the kdim components of the 51105 second B-spline coefficient and so on. */ 51106 double tt; /* Dummy variable used for holding an array element 51107 in a for loop. */ 51108 double *ebder=SISL_NULL; /* Pointer to an array of dimension [kk*(ider+1)] 51109 which will contain the values and ider first derivatives 51110 of the kk nonzero B-splines at ax. 51111 These are stored in the following order: 51112 First the value, 1. derivative etc. of the 51113 first nonzero B-spline, then the same for the 51114 second nonzero B-spline and so on. */ 51115 double *sder=SISL_NULL; /* Pointer to array used for storage of points, if 51116 non rational sder points to eder, if rational sder 51117 has to be allocated to make room for the homogenous 51118 coordinate */ 51119 51120 /* Copy curve attributes to local parameters. */ 51121 51122 kn = pc1 -> in; 51123 kk = pc1 -> ik; 51124 st = pc1 -> et; 51125 scoef = pc1 -> ecoef; 51126 kdim = pc1 -> idim; 51127 kind = pc1 ->ikind; 51128 51129 if (kind == 2 || kind == 4) 51130 { 51131 scoef = pc1 -> rcoef; 51132 kdim +=1; 51133 sder = newarray(kdim*(ider+1),DOUBLE); 51134 if (sder==SISL_NULL) goto err101; 51135 } 51136 else 51137 { 51138 scoef = pc1 -> ecoef; 51139 sder = eder; 51140 } 51141 51142 /* Check the input. */ 51143 51144 if (kdim < 1) goto err102; 51145 51146 if (kk < 1) goto err110; 51147 51148 if (kn < kk) goto err111; 51149 51150 /* Find in which interval ax lies */ 51151 51152 s1219(st,kk,kn,&kleft,ax,&kstat); 51153 if (kstat<0) goto error; 51154 51155 /* To force the derivative to be taken from the left we artificially 51156 shorten the curve if ax==st[kleft] */ 51157 51158 kmult = s6knotmult(st,kk,kn,&kleft,ax,&kstat); 51159 if (kstat < 0) goto error; 51160 51161 51162 if (ax == st[kleft] && kleft > kk-1) kn = kleft-kmult+1; 51163 if (st[kk-1] == st[kk] || st[kn-1] == st[kn]) goto err112; 51164 51165 if (ider < 0) goto err178; 51166 51167 if (pc1->ikind == 1 || pc1->ikind == 3) 51168 kder = min(kk-1,ider); 51169 else 51170 kder = ider; 51171 51172 /* Allocate space for B-spline values and derivatives. */ 51173 51174 ebder = newarray(kk*(kder+1),DOUBLE); 51175 if (ebder == SISL_NULL) goto err101; 51176 51177 /* Set all the elements of sder to 0. */ 51178 51179 for (ki=0; ki<(ider+1)*kdim; ki++) sder[ki] = (double)0.0; 51180 51181 /* Compute the values and derivatives of the nonzero B-splines and 51182 update ileft if necessary. */ 51183 51184 s1220(st,kk,kn,ileft,ax,kder,ebder,&kstat); 51185 51186 if (kstat < 0) goto error; 51187 51188 kleft = *ileft; 51189 51190 /* Multiply together as indicated above. */ 51191 51192 /* ki steps through the appropriate kk B-spline coefficients while kih steps 51193 through the B-spline value and derivatives for the B-spline given by ki.*/ 51194 51195 kih = 0; 51196 for (ki=kleft-kk+1; ki<=kleft; ki++) 51197 { 51198 51199 /* kj counts through the kder+1 derivatives to be computed. 51200 kjh steps through sder once for each ki to accumulate the contribution 51201 from the different B-splines. 51202 kl1 points to the first component of B-spline coefficient no. ki. */ 51203 51204 kjh = 0; kl1 = kdim*ki; 51205 for (kj=0; kj<=kder; kj++) 51206 { 51207 51208 /* The value of the B-spline derivative is stored in tt while 51209 kl2 steps through the idim components of this B-spline 51210 coefficient. */ 51211 51212 tt = ebder[kih++]; kl2 = kl1; 51213 for (kl=0; kl<kdim; kl++,kjh++,kl2++) 51214 { 51215 sder[kjh] += scoef[kl2]*tt; 51216 } 51217 } 51218 } 51219 51220 /* Free memory. */ 51221 51222 /* If rational curve calculate the derivatives based on derivatives in 51223 homogenous coordinates */ 51224 51225 if (kind == 2 || kind == 4) 51226 { 51227 s6ratder(sder,pc1->idim,ider,eder,&kstat); 51228 if (kstat<0) goto error; 51229 freearray(sder); 51230 } 51231 51232 freearray(ebder); 51233 51234 /* Successful computations. */ 51235 51236 *jstat = 0; 51237 goto out; 51238 51239 /* Not enough memory. */ 51240 err101: *jstat = -101; 51241 s6err("S1227",*jstat,kpos); 51242 goto out; 51243 51244 /* kdim less than 1. */ 51245 err102: *jstat = -102; 51246 s6err("S1227",*jstat,kpos); 51247 goto out; 51248 51249 /* Polynomial order less than 1. */ 51250 err110: *jstat = -110; 51251 s6err("S1227",*jstat,kpos); 51252 goto out; 51253 51254 /* Fewer B-splines than the order. */ 51255 err111: *jstat = -111; 51256 s6err("S1227",*jstat,kpos); 51257 goto out; 51258 51259 /* Error in knot vector. 51260 (The first or last interval of the knot vector is empty.) */ 51261 err112: *jstat = -112; 51262 s6err("S1227",*jstat,kpos); 51263 goto out; 51264 51265 /* Illegal derivative requested. */ 51266 err178: *jstat = -178; 51267 s6err("S1227",*jstat,kpos); 51268 goto out; 51269 51270 /* Error in lower level routine. */ 51271 51272 error: *jstat = kstat; 51273 s6err("S1227",*jstat,kpos); 51274 goto out; 51275 51276 out: return; 51277 } 51278 51279 //=========================================================================== 51280 void s6lufacp(double ea[],int nl[],int im,int *jstat) 51281 //=========================================================================== 51282 { 51283 int kpos = 0; /* Position of error. */ 51284 int ki,kj,kk; /* Counters. */ 51285 int kmax = 0; /* Number of row with maximum greates element. */ 51286 int kchange; /* Help variable to change order of two rows. */ 51287 double tmult; /* Factor with which to multiply a row before it is 51288 added to another. */ 51289 double t1; /* Help variabel to find maximum of a number of elements.*/ 51290 double tmax; /* Maximum of a number of elements. */ 51291 double tdiv; /* Dividend in expression. */ 51292 double *smax = SISL_NULL; /* Maximum elements in the rows of ea. */ 51293 51294 /* Allocate space for local array. */ 51295 51296 if ((smax = new0array(im,double)) == SISL_NULL) goto err101; 51297 51298 /* Find largest element in each row. */ 51299 51300 for (ki=0; ki<im; ki++) 51301 { 51302 nl[ki] = ki; 51303 for (kj=0; kj<im; kj++) 51304 smax[ki] = MAX(smax[ki],fabs(ea[ki*im+kj])); 51305 } 51306 51307 for (ki=0; ki<im-1; ki++) 51308 { 51309 51310 /* Find row with maximum greates element to treat now. */ 51311 51312 tmax = DZERO; 51313 for (kj=ki; kj<im; kj++) 51314 { 51315 tdiv = smax[nl[kj]]; 51316 if (DEQUAL(tdiv,DZERO)) goto warn1; 51317 t1 = fabs(ea[nl[kj]*im+ki]/tdiv); 51318 if (t1 > tmax) 51319 { 51320 tmax = t1; 51321 kmax = kj; 51322 } 51323 } 51324 kchange = nl[kmax]; 51325 nl[kmax] = nl[ki]; 51326 nl[ki] = kchange; 51327 51328 /* Add a multiplum of current row to all later rows in order to 51329 get an upper triangular matrix ea. */ 51330 51331 for (kj=ki+1; kj<im; kj++) 51332 { 51333 tdiv = ea[ki+kchange*im]; 51334 if (DEQUAL(tdiv,DZERO)) goto warn1; 51335 tmult = ea[ki+nl[kj]*im]/tdiv; 51336 ea[ki+nl[kj]*im] = tmult; 51337 51338 for (kk=ki+1; kk<im; kk++) 51339 ea[kk+nl[kj]*im] -= ea[kk+kchange*im]*tmult; 51340 } 51341 } 51342 51343 /* LU-factorizing performed. */ 51344 51345 *jstat = 0; 51346 goto out; 51347 51348 /* Singular equation system. */ 51349 51350 warn1 : *jstat = 1; 51351 goto out; 51352 51353 /* Error in space allocation. */ 51354 51355 err101: *jstat = -101; 51356 s6err("s6lufacp",*jstat,kpos); 51357 goto out; 51358 51359 out: 51360 51361 /* Free space occupied by local array. */ 51362 51363 if (smax != SISL_NULL) freearray(smax); 51364 51365 return; 51366 } 51367 51368 //=========================================================================== 51369 void s6lusolp(double ea[],double eb[],int nl[],int im,int *jstat) 51370 //=========================================================================== 51371 { 51372 int kpos = 0; /* Position of error. */ 51373 int ki,kj; /* Counters. */ 51374 double *sx = SISL_NULL; /* Array used to keep solution of equation system 51375 internally. */ 51376 double tdiv; /* Dividend in expression. */ 51377 51378 /* Allocate space for local array. */ 51379 51380 if ((sx = newarray(im,double)) == SISL_NULL) goto err101; 51381 51382 for (ki=0; ki<im-1; ki++) 51383 { 51384 /* Gauss on right side of equation */ 51385 51386 for (kj=ki+1; kj<im; kj++) 51387 eb[nl[kj]] -= eb[nl[ki]]*ea[ki+nl[kj]*im]; 51388 } 51389 51390 tdiv = ea[im-1+nl[im-1]*im]; 51391 if (DEQUAL(tdiv,DZERO)) goto warn1; 51392 sx[im-1] = eb[nl[im-1]]/tdiv; 51393 51394 for (ki=im-2; ki>=0; ki--) 51395 { 51396 /* Backwards substitution. */ 51397 51398 for (kj=ki+1; kj<im; kj++) 51399 eb[nl[ki]] -= sx[kj]*ea[kj+nl[ki]*im]; 51400 51401 tdiv = ea[ki+nl[ki]*im]; 51402 if (DEQUAL(tdiv,DZERO)) goto warn1; 51403 sx[ki] = eb[nl[ki]]/tdiv; 51404 } 51405 for (ki=0; ki<im; ki++) eb[ki] = sx[ki]; 51406 51407 /* Equation system solved. */ 51408 51409 *jstat = 0; 51410 goto out; 51411 51412 /* Singular equation system. */ 51413 51414 warn1 : *jstat = 1; 51415 goto out; 51416 51417 /* Error in space allocation. */ 51418 51419 err101: *jstat = -101; 51420 s6err("s6lusolp",*jstat,kpos); 51421 goto out; 51422 51423 out: 51424 51425 /* Free space occupied by local array. */ 51426 51427 if (sx != SISL_NULL) freearray(sx); 51428 51429 return; 51430 } 51431 51432 51433 //=========================================================================== 51434 void s1771_s9point(SISLCurve *pcurve,double eval1[],double eval2[],double ediff[], 51435 double astart,double aend,int max_it,double *cnext,double *ad, 51436 double adel,double *cdist,double aprev,int ileft,int *jstat) 51437 //=========================================================================== 51438 { 51439 int kstat = 0; /* Local status variable. */ 51440 int kdim = pcurve->idim; /* Dimension of space the curves lie in */ 51441 int knbit; /* Number of iterations */ 51442 int kdiv = 0; /* Counts number of diverging steps. */ 51443 int kdiv2 = 0; /* Counts number of almost divergence. */ 51444 51445 /* Correct if we are not inside the parameter intervall. */ 51446 51447 if (*cnext + *ad < astart) *ad = astart - *cnext; 51448 else if (*cnext + *ad > aend) *ad = aend - *cnext; 51449 51450 for (knbit=0;knbit<max_it;knbit++) 51451 { 51452 /* Evaluate 0-2.st derivatives of the curve. */ 51453 51454 s1221(pcurve,2,*cnext + *ad,&ileft,eval2,&kstat); 51455 if (kstat < 0) goto error; 51456 51457 s6diff(eval1,eval2,kdim,ediff); 51458 51459 *cdist = s6length(ediff,kdim,&kstat); 51460 51461 if (*cdist -aprev <= REL_COMP_RES) 51462 { 51463 if (kdiv2 > 4) break; 51464 if (*cdist -aprev >= DZERO) kdiv2++; 51465 51466 kdiv = 0; 51467 aprev = *cdist; 51468 *cnext += *ad; 51469 51470 *ad = s1771_s9del(ediff,eval2+kdim,eval2+kdim+kdim,kdim); 51471 51472 /* Correct if we are not inside the parameter intervall. */ 51473 51474 if (*cnext + *ad < astart) *ad = astart - *cnext; 51475 else if (*cnext + *ad > aend) *ad = aend - *cnext; 51476 } 51477 else 51478 { 51479 kdiv++; 51480 if (kdiv > 3) break; 51481 (*ad) /= (double)2; 51483 } 51484 if (fabs((*ad)/MAX(fabs(*cnext),adel)) <= REL_COMP_RES) break; 51485 } 51486 51487 goto out; 51488 51489 /* Error in lower level routine. */ 51490 51491 error : *jstat = kstat; 51492 s6err("s1771_s9point",*jstat,0); 51493 goto out; 51494 51495 out: ; 51496 } 51497 51498 //=========================================================================== 51499 double s1771_s9del(double *eco,double *eco1,double *eco2,int idim) 51500 //=========================================================================== 51501 { 51502 double t1,t2,t3,t4,t5,t6; /* Constants in equation. */ 51503 double tmax,tmax1; /* Max values in equation. */ 51504 double ttol=(double)1e-10; /* Relative tolerance in equation. */ 51505 51506 t1 = s6scpr(eco,eco1,idim); 51507 t3 = s6scpr(eco1,eco1,idim); 51508 t2 = t3 - s6scpr(eco,eco2,idim); 51509 t4 = -(double)2 * s6scpr(eco1,eco2,idim); 51510 51511 tmax = max(fabs(t1),fabs(t2)); 51512 tmax1 = max(fabs(t3),fabs(t4)); 51513 tmax = max(tmax1,tmax); 51514 51515 if (DEQUAL(tmax,DZERO)) return DZERO; 51516 51517 else if (fabs(t4)/tmax < ttol) /* The second degree part is degenerated. */ 51518 { 51519 if (fabs(t2)/tmax < ttol) 51520 { 51521 if (fabs(t3)/tmax < ttol) return DZERO; 51522 else return (t1/t3); 51523 } 51524 else return (t1/t2); 51525 } 51526 else /* An ordinary second degree equation. */ 51527 { 51528 t5 = t2*t2 - (double)2*t4*t1; 51529 if (t5 < DZERO) return (t1/t3); 51530 else 51531 { 51532 t6 = sqrt(t5); 51533 t5 = (t2 + t6)/t4; 51534 t6 = (t2 - t6)/t4; 51535 t1 *= t3; 51536 51537 51538 /* We have two solutions and we want to use the one 51539 with the same sign as we get while using an other 51540 metode t1/t3. If both solutions have the same 51541 sign we use the one with smallest value. */ 51542 51543 if (t1 < DZERO) 51544 { 51545 if (t5 <= DZERO && t6 <= DZERO) 51546 { 51547 if (t5 > t6) return t5; 51548 else return t6; 51549 } 51550 else if (t5 <= DZERO) return t5; 51551 else if (t6 <= DZERO) return t6; 51552 else return min(t5,t6); 51553 } 51554 else if (t1 > DZERO) 51555 { 51556 if (t5 >= DZERO && t6 >= DZERO) 51557 { 51558 if (t5 < t6) return t5; 51559 else return t6; 51560 } 51561 else if (t5 >= DZERO) return t5; 51562 else if (t6 >= DZERO) return t6; 51563 else return max(t5,t6); 51564 } 51565 else return min(fabs(t5),fabs(t6)); 51566 } 51567 } 51568 } 51569 51570 //=========================================================================== 51571 void s6ratder(double eder[],int idim,int ider,double gder[],int *jstat) 51572 //=========================================================================== 51573 { 51574 int kpos=0; /* Position of error. */ 51575 double w0; /* The denominator. */ 51576 int ki; /* Count through dimensions. */ 51577 int id; /* Count through derivatives. */ 51578 int *binom = SISL_NULL; /* Array for binomial coefficients. */ 51579 double sum; /* Binomial (Leibnitz) expansion. */ 51580 int idimp1; /* idim + 1. */ 51581 int iw; /* Pointer to a weight. */ 51582 int igder; /* Pointer to already calculated derivs. */ 51583 int i,j,k; /* Counters. */ 51584 int iwfix; /* Initial value of iw in Leibnitz loop. */ 51585 51586 if (ider<0) goto err178; 51587 if (idim<1) goto err102; 51588 51589 idimp1 = idim + 1; 51590 51591 /* Find denominator. */ 51592 51593 w0 = eder[idim]; 51594 if (DEQUAL(w0,DZERO)) w0 = (double)1.0; 51595 51596 /* Set up initial binomial coefficient (1). */ 51597 51598 binom = newarray(ider+1, INT); 51599 if(binom == SISL_NULL) goto err179; 51600 51601 binom[0] = 1; 51602 51603 51604 /* Calculate position first. */ 51605 51606 for(ki=0; ki<idim; ki++) 51607 { 51608 gder[ki] = eder[ki] / w0; 51609 } 51610 51611 51612 51613 /* Then derivatives if there are any. */ 51614 51615 for(id=1,j=idim,k=idimp1; id<=ider; id++,k++) 51616 { 51617 /* Calculate the new row of binomial coefficients. */ 51618 51619 binom[id] = 1; 51620 51621 for(i=id-1; i>=1; i--) 51622 { 51623 binom[i] += binom[i-1]; 51624 } 51625 51626 51627 /* Run through the idim dimensions, calculating each 51628 coefficient of the id'th derivative of 51629 the rational curve (in gder). */ 51630 51631 iwfix = k + idim; 51632 51633 for(ki=0; ki<idim; ki++,j++,k++) 51634 { 51635 /* Calculate the Leibnitz sum (the binomial 51636 coefficient in the first term is always 1). */ 51637 51638 sum = eder[iwfix] * gder[ki]; 51639 51640 for(i=1,igder=idim+ki,iw=iwfix-idimp1; 51641 i<id; 51642 i++,igder+=idim,iw-=idimp1) 51643 { 51644 sum += (double)binom[i] * eder[iw] * gder[igder]; 51645 } 51646 51647 gder[j] = (eder[k] - sum) / w0; 51648 51649 } 51650 51651 } 51652 51653 /* Done. */ 51654 51655 51656 *jstat = 0; 51657 goto out; 51658 51659 /* idim less than 1. */ 51660 err102: *jstat = -102; 51661 s6err("s6ratder",*jstat,kpos); 51662 goto out; 51663 51664 /* Derivative negative */ 51665 err178: *jstat = -178; 51666 s6err("s6ratder",*jstat,kpos); 51667 goto out; 51668 51669 51670 /* Not enough memory */ 51671 err179: *jstat = -179; 51672 s6err("s6ratder",*jstat,kpos); 51673 goto out; 51674 51675 51676 out: 51677 if (binom != SISL_NULL) freearray(binom); 51678 51679 return; 51680 } 51681 51682 //=========================================================================== 51683 void s1771(SISLPoint *ppoint,SISLCurve *pcurve,double aepsge, 51684 double astart,double aend,double anext,double *cpos,int *jstat) 51685 //=========================================================================== 51686 { 51687 int kstat = 0; /* Local status variable. */ 51688 int kpos = 0; /* Position of error. */ 51689 int kleft=0; /* Variables used in the evaluator. */ 51690 int kdim; /* Dimension of space the curves lie in */ 51691 double tdelta; /* Parameter interval of the curve. */ 51692 double tdist; /* Distance between position and origo. */ 51693 double td; /* Distances between old and new parameter value in 51694 the two parameter directions. */ 51695 double tprev; /* Previous difference between the curves. */ 51696 double *sval=SISL_NULL; /* Value ,first and second derivatie on curve 1 */ 51697 double *sdiff; /* Difference between the curves */ 51698 int quick = (*jstat); /* Indicates if the exactness requirement is 51699 relaxed. */ 51700 int max_it = 20; /* Maximum number of iterations. */ 51701 51702 if (quick) max_it = 10; 51703 51704 /* Test input. */ 51705 51706 if (ppoint->idim != pcurve->idim) goto err106; 51707 51708 kdim = pcurve -> idim; 51709 51710 /* Fetch endpoints and the intervals of parameter interval of curves. */ 51711 51712 tdelta = pcurve->et[pcurve->in] - pcurve->et[pcurve->ik - 1]; 51713 51714 /* Allocate local used memory */ 51715 51716 sval = newarray(4*kdim,double); 51717 if (sval == SISL_NULL) goto err101; 51718 51719 sdiff = sval + 3*kdim; 51720 51721 /* Initiate variable. */ 51722 51723 tprev = (double)HUGE; 51724 51725 /* Evaluate 0-2.st derivatives of the curve. */ 51726 51727 s1221(pcurve,2,anext,&kleft,sval,&kstat); 51728 if (kstat < 0) goto error; 51729 51730 s6diff(ppoint->ecoef,sval,kdim,sdiff); 51731 51732 tdist = s6length(sdiff,kdim,&kstat); 51733 51734 td = s1771_s9del(sdiff,sval+kdim,sval+kdim+kdim,kdim); 51735 51736 /* Correct if we are not inside the parameter intervall. */ 51737 51738 if (anext + td < astart) td = astart - anext; 51739 else if (anext + td > aend) td = aend - anext; 51740 51741 s1771_s9point(pcurve,ppoint->ecoef,sval,sdiff,astart,aend,max_it,&anext, 51742 &td,tdelta,&tdist,tprev,kleft,&kstat); 51743 if (kstat < 0) goto error; 51744 51745 /* Iteration stopped, test if point found is within resolution */ 51746 51747 if (tdist <= aepsge) 51748 *jstat = 1; 51749 else 51750 *jstat = 2; 51751 51752 *cpos = anext; 51753 51754 /* Iteration completed. */ 51755 51756 goto out; 51757 51758 /* Error in allocation */ 51759 51760 err101: *jstat = -101; 51761 s6err("s1771",*jstat,kpos); 51762 goto out; 51763 51764 /* Error in input. Conflicting dimensions. */ 51765 51766 err106: *jstat = -106; 51767 s6err("s1771",*jstat,kpos); 51768 goto out; 51769 51770 /* Error in lower level routine. */ 51771 51772 error : *jstat = kstat; 51773 s6err("s1771",*jstat,kpos); 51774 goto out; 51775 51776 out: if (sval != SISL_NULL) freearray(sval); 51777 } 51778 51779 //=========================================================================== 51780 void s1306(double ep[],double eparp[],double eimpli[],int ideg, 51781 double egeo3d[],double egeop[],int *jstat) 51782 //=========================================================================== 51783 { 51784 int fuzzy_sing = FALSE; 51785 int sing = FALSE; 51786 int kstat = 0; /* Local status variable */ 51787 int ki,kj,kl; /* Control variables in loop */ 51788 int kpos = 0; /* Position of error */ 51789 int ksize; /* Number of doubles for storage of derivateves 51790 and normal vector */ 51791 int ksizem3; /* ksize - 3 */ 51792 double *sps; /* Pointer to dP/ds */ 51793 double *spt; /* Pointer to dP/dt */ 51794 double *spss; /* Pointer to ddP/(dsds) */ 51795 double *spst; /* Pointer to ddP/(dsdt) */ 51796 double *sptt; /* Pointer to ddP/(dtdt) */ 51797 double tfs,tft,tfss; /* Derivatives of parametric surface put into */ 51798 double tfst,tftt; /* the implicit equation */ 51799 double tsu,ttu,tsuu,ttuu;/* Derivatives of parameter direction */ 51800 double sder[6]; /* Derivatives of parametric surface */ 51801 double snorm[3]; /* Normal vector of implicit surface at ep */ 51802 double sp[9]; /* Points, first and second deriv. of intcur */ 51803 51804 51805 /* If ideg=1,2 or 1001 then only derivatives up to second order 51806 are calculated, then 18 doubles for derivatives and 3 for the 51807 normal vector are to be used for calculation of points in the 51808 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 51809 derivatives up to the third are to be calculated, 51810 thus 30 +3 a total of 33 doubles are to be calculated */ 51811 51812 if (ideg==1003 || ideg==1004 || ideg==1005) 51813 { 51814 ksize = 33; 51815 } 51816 else 51817 { 51818 ksize = 21; 51819 } 51820 ksizem3 = ksize -3; 51821 51822 /* Calculated derivatives of the parametric surface put into the implicit 51823 surface at the point ep */ 51824 51825 s1331(ep,eimpli,ideg,2,sder,snorm,&kstat); 51826 if (kstat<0) goto error; 51827 51828 tfs = sder[1]; 51829 tft = sder[2]; 51830 tfss = sder[3]; 51831 tfst = sder[4]; 51832 tftt = sder[5]; 51833 51834 51835 /* Calculate ds/du and dt/du */ 51836 /* UJK, aug.92 */ 51837 51838 /* if (DEQUAL(tfs,(double)0.0) && 51839 DEQUAL(tft,(double)0.0) ) */ 51840 51841 /* UJK, 13.08.93, save suzzy singular information. */ 51842 if (fabs(tfs) < 0.000001 && 51843 fabs(tft) < 0.000001) fuzzy_sing = TRUE; 51844 else 51845 fuzzy_sing = FALSE; 51846 51847 if (DEQUAL((double)1.0 + tfs,(double)1.0) && 51848 DEQUAL((double)1.0 + tft,(double)1.0) ) 51849 { 51850 double tdum1,tdum2,tafss,tafst,taftt; 51851 51852 /* Singular point found, copy position and derivative value of input to 51853 output, if not second order derivatives uniqely describes a tangent*/ 51854 51855 memcopy(egeo3d,ep,3,DOUBLE); 51856 memcopy(egeop,eparp,2,DOUBLE); 51857 51858 tafss = fabs(tfss); 51859 tafst = fabs(tfst); 51860 taftt = fabs(tftt); 51861 51862 tdum1 = tfst*tfst - tfss*tftt; 51863 tdum2 = MAX(tafss,taftt); 51864 tdum2 = MAX(tafst,tdum2); 51865 51866 for (ki=3 ; ki<10 ; ki++) egeo3d[ki] = DZERO; 51867 for (ki=2 ; ki<7 ; ki++) egeop[ki] = DZERO; 51868 51869 if (DEQUAL(tdum2+tdum1,tdum2) && 51870 (DNEQUAL(tafss+tafst,tafst) || DNEQUAL(taftt+tafst,tafst)) ) 51871 { 51872 /* A unique tangent can be calculated */ 51873 51874 if (tafss>taftt) 51875 { 51876 tsu = -tfst/tfss; 51877 ttu = 1; 51878 } 51879 else 51880 { 51881 tsu = 1; 51882 ttu = -tfst/tftt; 51883 } 51884 tsuu = 0.0; 51885 ttuu = 0.0; 51886 /* Flag singular case */ 51887 sing = TRUE; 51888 } 51889 else 51890 { 51891 /* A tangent can not be calulated */ 51892 goto war02; 51893 } 51894 } 51895 else 51896 { 51897 /* A noneisngular point found */ 51898 if (fabs(tfs) > fabs(tft)) 51899 { 51900 /* Use u=t */ 51901 51902 tsu = -tft/tfs; 51903 ttu = (double)1.0; 51904 51905 tsuu = -(tfss*tsu*tsu + (double)2.0*tfst*tsu*ttu + tftt*ttu*ttu)/tfs; 51906 ttuu = (double)0.0; 51907 } 51908 else 51909 { 51910 /* Use u=t */ 51911 51912 tsu = (double)1.0; 51913 ttu = -tfs/tft; 51914 51915 tsuu = (double)0.0; 51916 ttuu = -(tfss*tsu*tsu + (double)2.0*tfst*tsu*ttu + tftt*ttu*ttu)/tft; 51917 } 51918 } 51919 51920 /* The calculation of the derivatives of one parameter direction with 51921 respect to the other is dependent on the degree of the implicit equation*/ 51922 51923 /* Set local pointers */ 51924 51925 sps = ep + 3; 51926 spt = ep + 6; 51927 spss = ep + 9; 51928 spst = ep + 12; 51929 sptt = ep + 15; 51930 51931 /* Make description of intersection point in 3-D including 51932 curvature and radius of curvature, first make description of 51933 intersection point in parameter plane */ 51934 51935 /* We will now express the intersection curve locally as a function 51936 * of a w-parameter. 51937 * 51938 * c(w) = p(s(w),t(w)) 51939 * 51940 * This gives the derivative 51941 * 51942 * 51943 * c' = P s' + P t' 51944 * s t 51945 * 51946 * And the second derivative 51947 * 51948 * 2 2 51949 * c" = P s' + 2P s't' + P t' + P s" + P t" 51950 * ss st tt s t 51951 */ 51952 51953 for (ki=0,kj=3,kl=6 ; ki<3 ; ki++,kj++,kl++) 51954 { 51955 51956 /* Copy position */ 51957 51958 sp[ki] = ep[ki]; 51959 51960 /* Make tangent */ 51961 51962 sp[kj] = sps[ki]*tsu + spt[ki]*ttu; 51963 51964 /* Make curvature */ 51965 51966 sp[kl] = spss[ki]*tsu*tsu + (double)2.0*spst[ki]*tsu*ttu + 51967 sptt[ki]*ttu*ttu + sps[ki]*tsuu + spt[ki]*ttuu; 51968 } 51969 51970 /* Make 3-D curvature and radius of curvature */ 51971 51972 s1307(sp,3,egeo3d,&kstat); 51973 if (kstat < 0 )goto error; 51974 51975 /* Make description of intersection point in parameter plane including 51976 curvature and radius of curvature, first make description of 51977 intersection point in parameter plane */ 51978 51979 sp[0] = eparp[0]; 51980 sp[1] = eparp[1]; 51981 sp[2] = tsu; 51982 sp[3] = ttu; 51983 sp[4] = tsuu; 51984 sp[5] = ttuu; 51985 51986 s1307(sp,2,egeop,&kstat); 51987 if (kstat < 0) goto error; 51988 51989 /* Everyting is ok */ 51990 51991 *jstat = 0; 51992 goto out; 51993 51994 51995 /* SISLPoint lying on torus axis */ 51996 51997 war02: *jstat=2; 51998 goto out; 51999 52000 /* Error in lower level function */ 52001 error: 52002 *jstat = kstat; 52003 s6err("s1306",*jstat,kpos); 52004 goto out; 52005 52006 out: 52007 if (sing && *jstat>=0) *jstat = 10; 52008 else if (fuzzy_sing && *jstat>=0) *jstat = 11; 52009 return; 52010 } 52011 52012 //=========================================================================== 52013 void s1313_s9constline(SISLSurf *ps1,double eimpli[],int ideg, 52014 double aepsge,SISLIntcurve *pintcr,int icur, 52015 int igraph,int *jstat) 52016 //=========================================================================== 52017 { 52018 int ki,kj,kl; /* Control variables in for loops */ 52019 int kk,kn,kk1,kn1,kk2,kn2;/* Orders and numbers of knots */ 52020 int kpoint; /* Number of points in guide curve */ 52021 int kleft = 0; /* Pointer into knot vector */ 52022 int kpar1; /* Number of parameter direction in 1st. obj */ 52023 int kpar2; /* Number of parameter direction in 2st. obj */ 52024 int ktype; /* Type of intersection curve */ 52025 int kpos=0; /* Position of error */ 52026 int kstat; /* Status variable returned form routine */ 52027 int kdir=0; /* constant parameter line direction */ 52028 int knbpnt; /* Number of points on constant parameter line */ 52029 double tmax1,tmin1; /* Minimum and maximum of first comp of guide points */ 52030 double tmax2,tmin2; /* Minimum and maximum of first comp of guide points */ 52031 double tmax; /* Maximum 3-D SISLbox side */ 52032 double tdist,tang; /* Distance and angle error */ 52033 double *st,*st1,*st2; /* Pointers to knot vectors */ 52034 double *spoint; /* Pointer to points on constant parameter line */ 52035 double *sp1; /* Pointer into array */ 52036 double tsize1,tsize2; /* Length of knot intervals */ 52037 double sval1[2]; /* Limits of parameter plane in first SISLdir */ 52038 double sval2[2]; /* Limits of parameter plane in second SISLdir */ 52039 double sder[6]; /* SISLPoint and derivative on curve */ 52040 double sider[3]; /* SISLPoint on implicit surface */ 52041 double snorm[3]; /* Normal on implicit surface */ 52042 double tsumold,tsum,tval;/* Parameter values */ 52043 double *sgpar1=SISL_NULL; /* Parameter pairs of guide point in surf 1 */ 52044 double *sgpar2=SISL_NULL; /* Parameter pairs of guide point in surf 2 */ 52045 SISLCurve *qc1=SISL_NULL; /* Pointer to 3-D curve */ 52046 SISLCurve *qc2=SISL_NULL; /* Pointer to 3-D curve */ 52047 52048 SISLCurve *qp1cur=SISL_NULL; /* Pointer to curve in first parameter plane*/ 52049 52050 52051 52052 /* Make maximal step length based on box-size of surface */ 52053 52054 sh1992su(ps1,0,aepsge,&kstat); 52055 if (kstat < 0) goto error; 52056 52057 tmax = MAX(ps1->pbox->e2max[0][0] - ps1->pbox->e2min[0][0], 52058 ps1->pbox->e2max[0][1] - ps1->pbox->e2min[0][1]); 52059 tmax = MAX(tmax,ps1->pbox->e2max[0][2] - ps1->pbox->e2min[0][2]); 52060 52061 /* Find a none singular start point for the marching process */ 52062 52063 kpoint = pintcr->ipoint; 52064 kpar1 = pintcr->ipar1; 52065 kpar2 = pintcr->ipar2; 52066 sgpar1 = pintcr->epar1; 52067 sgpar2 = pintcr->epar2; 52068 ktype = pintcr->itype; 52069 52070 52071 /* Initiate pointers to intersection curve and intersection curve in 52072 parameter plane */ 52073 52074 pintcr -> pgeom = SISL_NULL; 52075 pintcr -> ppar1 = SISL_NULL; 52076 pintcr -> ppar2 = SISL_NULL; 52077 52078 52079 /* Initiate parameter direction boundaries */ 52080 kk1 = ps1 -> ik1; 52081 kn1 = ps1 -> in1; 52082 st1 = ps1 -> et1; 52083 sval1[0] = st1[kk1-1]; 52084 sval1[1] = st1[kn1]; 52085 kk2 = ps1 -> ik2; 52086 kn2 = ps1 -> in2; 52087 st2 = ps1 -> et2; 52088 sval2[0] = st2[kk2-1]; 52089 sval2[1] = st2[kn2]; 52090 52091 52092 /* Test that first object has 2 parameter 52093 direction and second object 0 */ 52094 52095 if (kpar1 == 2 && kpar2 == 0) 52096 { 52097 /* Everithing is ok */ 52098 ; 52099 } 52100 else if (kpar1 == 0 && kpar2 == 2) 52101 { 52102 sgpar1 = sgpar2; 52103 } 52104 else 52105 { 52106 goto err123; 52107 } 52108 52109 52110 /* Run through the parameter pairs to decide if a constant parameter line 52111 is possible */ 52112 52113 tmax1 = tmin1 = sgpar1[0]; 52114 tmax2 = tmin2 = sgpar1[1]; 52115 52116 for (ki=1,kj=2,kl=3 ; ki < kpoint ; ki++,kj+=2,kl+=2) 52117 { 52118 tmin1 = MIN(tmin1,sgpar1[kj]); 52119 tmax1 = MAX(tmax1,sgpar1[kj]); 52120 tmin2 = MIN(tmin2,sgpar1[kl]); 52121 tmax2 = MAX(tmax2,sgpar1[kl]); 52122 } 52123 52124 tsize1 = st1[kn1] - st1[kk1-1]; 52125 tsize2 = st2[kn2] - st2[kk2-1]; 52126 52127 /* Check if constant parameter value within tolerance */ 52128 52129 if (DEQUAL((tmin1+tsize1),(tmax1+tsize1)) ) 52130 { 52131 /* Intersection possible constant parameter line with first parameter 52132 constant value constant. 52133 52134 1. Pick out curve from surface 52135 2. Pick out relevant part of curve */ 52136 52137 kdir = 1; 52138 52139 s1437(ps1,(tmin1+tmax1)/2.0,&qc1,&kstat); 52140 if (kstat < 0) goto error; 52141 52142 s1712(qc1,tmin2,tmax2,&qc2,&kstat); 52143 if (kstat < 0) goto error; 52144 } 52145 else if (DEQUAL((tmin2+tsize2),(tmax2+tsize2)) ) 52146 { 52147 /* Intersection possible constant parameter line with first parameter 52148 constant value constant. 52149 52150 1. Pick out curve from surface 52151 2. Pick out relevant part of curve */ 52152 52153 kdir = 2; 52154 52155 s1436(ps1,(tmin2+tmax2)/2.0,&qc1,&kstat); 52156 if (kstat < 0) goto error; 52157 52158 s1712(qc1,tmin1,tmax1,&qc2,&kstat); 52159 if (kstat < 0) goto error; 52160 } 52161 else 52162 goto war00; 52163 52164 st = qc2 -> et; 52165 kk = qc2 -> ik; 52166 kn = qc2 -> in; 52167 52168 /* Run through 2*kn points of the curve and check that they lie in the 52169 implicit surface by calculating the 2*kn points. */ 52170 52171 tsumold = st[kk-1]; 52172 52173 for (ki=0 ; ki <kn ; ki++) 52174 { 52175 if (kk>1) 52176 { 52177 /* Make parameter value to use for calculation of curve point */ 52178 52179 for (kl=1,kj=ki+1,tsum=(double)0.0 ; kl<kk ; kl++) 52180 tsum += st[kj++]; 52181 52182 tsum = tsum/(kk-1); 52183 } 52184 else 52185 tsum = st[ki]; 52186 52187 tval = tsum; 52188 52189 for (kj=0 ; kj<2 ; kj++) 52190 { 52191 /* Calculate point on curve */ 52192 52193 s1221(qc2,1,tval,&kleft,sder,&kstat); 52194 if (kstat < 0) goto error; 52195 52196 /* Calculate normal to implicit surface */ 52197 52198 s1331(sder,eimpli,ideg,-1,sider,snorm,&kstat); 52199 if (kstat < 0) goto error; 52200 52201 /* Project point onto implicit surface */ 52202 52203 tdist = fabs(s1309(sder,snorm,eimpli,ideg,&kstat)); 52204 if (kstat<0) goto error; 52205 if (kstat==2) goto war00; 52206 52207 /* Both the position of the two points should be within the relative 52208 computer resolution for the point to be accepted. Correspondingly the 52209 direction of the intersection curve and the constant parameter line 52210 should be within the computer resolution to be accepted. */ 52211 52212 if (DNEQUAL(tdist+tmax,tmax)) 52213 goto war00; 52214 52215 /* Distance within tolerance, check that the angle between surface 52216 normal and curve tangent is PIHALF, if both these vectors have a 52217 nonzero length. */ 52218 52219 if (s6length(snorm,3,&kstat) != (double)0.0 && 52220 s6length(sder+3,3,&kstat) != (double)0.0 ) 52221 { 52222 tang = s6ang(snorm,sder+3,3); 52223 if (DNEQUAL(fabs(tang),PIHALF) ) goto war00; 52224 } 52225 tval = (tsumold+tsum)/(double)2.0; 52226 } 52227 tsumold = tsum; 52228 } 52229 52230 /* Intersection curve along constant parameter line, make right actions 52231 concerning drawing and/or creation of the curve */ 52232 52233 if (igraph == 1) 52234 { 52235 /* Draw curve, first break into straight line segments */ 52236 52237 s1605(qc2,aepsge,&spoint,&knbpnt,&kstat); 52238 if (kstat < 0) goto error; 52239 52240 if (knbpnt>1) 52241 { 52242 /* Draw curve */ 52243 52244 s6move(spoint); 52245 for (ki=1,sp1=spoint+3 ; ki<knbpnt ; ki++,sp1+=3) 52246 s6line(sp1); 52247 } 52248 freearray(spoint); 52249 } 52250 52251 if (icur >= 1) 52252 { 52253 /* Set pointer to 3-D curve */ 52254 52255 pintcr -> pgeom = qc2; 52256 qc2 = SISL_NULL; 52257 } 52258 52259 if (icur == 2) 52260 { 52261 /* Make curve in parameter plane */ 52262 52263 double svert[4],sknot[4]; 52264 52265 if (kdir==1) 52266 { 52267 svert[0] = svert[2] = (tmin1+tmax1)/(double)2.0; 52268 svert[1] = tmin2; 52269 svert[3] = tmax2; 52270 sknot[0] = sknot[1] = tmin2; 52271 sknot[2] = sknot[3] = tmax2; 52272 } 52273 else 52274 { 52275 svert[0] = tmin1; 52276 svert[2] = tmax1; 52277 svert[1] = svert[3] = (tmin2+tmax2)/(double)2.0; 52278 sknot[0] = sknot[1] = tmin1; 52279 sknot[2] = sknot[3] = tmax1; 52280 } 52281 qp1cur = newCurve(2,2,sknot,svert,1,2,1); 52282 if (qp1cur==SISL_NULL) goto err101; 52283 pintcr -> ppar1 = qp1cur; 52284 } 52285 52286 /* war01: */ 52287 *jstat = 1; 52288 goto out; 52289 52290 /* Iteration can not continue */ 52291 war00: *jstat = 0; 52292 goto out; 52293 52294 52295 /* Error in space allocation */ 52296 err101: *jstat = -101; 52297 s6err("s1313",*jstat,kpos); 52298 goto out; 52299 52300 /* Error in surface description parameter direction does not exist */ 52301 err123: *jstat = -123; 52302 s6err("s1313_s9constline",*jstat,kpos); 52303 goto out; 52304 52305 /* Error in lower leve function */ 52306 error: 52307 *jstat = kstat; 52308 s6err("s1313_s9constline",*jstat,kpos); 52309 goto out; 52310 52311 out:; 52312 if (qc1 != SISL_NULL) freeCurve(qc1); 52313 if (qc2 != SISL_NULL) freeCurve(qc2); 52314 } 52315 52316 52317 //=========================================================================== 52318 void s9iterimp(double epoint[],double epnt1[],double epar1[],SISLSurf *psurf1, 52319 double eimpli[],int ideg,double astep,double aepsge, 52320 double gpnt1[],double gpar1[],int *jstat) 52321 //=========================================================================== 52322 { 52323 int ki; /* Variable used in loop */ 52324 int kcont; /* Indicator telling if iteration is not finished */ 52325 int kder = 1; /* Derivative indicator */ 52326 int klfu=0; /* Pointer into knot vector */ 52327 int klfv=0; /* Pointer into knot vector */ 52328 int kstat; /* Status variable */ 52329 int knbit; /* Counter for number of iterations */ 52330 int kdim = 3; /* Set dimension to 3 */ 52331 int kmaxit = 100; /* Maximal number of iterations allowed */ 52332 int kpos=1; /* Position indicator ofr errors */ 52333 int ksing; /* Singularity indicator */ 52334 int ksize; /* Number of doubles for storage of derivateves 52335 and normal vector */ 52336 int ksizem3; /* ksize - 3 */ 52337 double spoint[3]; /* SISLPoint in intersection plane */ 52338 double *snorm; /* Pointer to normal vector of intersection plane */ 52339 double sbinorm[3]; /* Vector normal tu curve tangent */ 52340 double *sp,*spu,*spv,*spn; /* Pointers into gpnt1 */ 52341 double sprev[3]; /* Coordinates of previous point in iteration */ 52342 double ta11,ta12,ta21; /* Variables used in equation systems */ 52343 double ta22,tb1,tb2; /* Variables used in equation systems */ 52344 double sdiff[3]; /* Difference between two vectors */ 52345 double tdum,tdum1; /* Dummy variables */ 52346 double tdist; /* Error so fare in iteration */ 52347 double tcurdst; /* Error at current step in the iteration */ 52348 double sder[3]; /* Derivatives of comb. of impl. surf and par.surf*/ 52349 double sproj[3]; /* Projection direction */ 52350 double tlnorm; /* Length of normal vector of step plane */ 52351 double tdiststep; /* Distance from step plane */ 52352 double titer; /* Iteration criteria */ 52353 52354 /* If ideg=1,2 or 1001 then only derivatives up to second order 52355 are calculated, then 18 doubles for derivatives and 3 for the 52356 normal vector are to be used for calculation of points in the 52357 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 52358 derivatives up to the third are to be calculated, 52359 thus 30 +3 a total of 33 doubles are to be calculated */ 52360 52361 if (ideg==1003 || ideg==1004 || ideg==1005) 52362 { 52363 kder = 3; 52364 ksize = 33; 52365 } 52366 else 52367 { 52368 ksize = 21; 52369 kder =2; 52370 } 52371 ksizem3 = ksize -3; 52372 52373 /* Make description of intersection plane */ 52374 52375 tlnorm = s6length(epoint+3,3,&kstat); 52376 if (kstat<0) goto error; 52377 if (DEQUAL(tlnorm,DZERO)) tlnorm = (double)1.0; 52378 52379 for (ki=0;ki<3;ki++) 52380 { 52381 spoint[ki] = epoint[ki] + astep*epoint[ki+3]/tlnorm; 52382 } 52383 52384 snorm = epoint + 3; 52385 52386 /* Copy input variables to output variables */ 52387 52388 memcopy(gpnt1,epnt1,ksize,DOUBLE); 52389 memcopy(gpar1,epar1,2,DOUBLE); 52390 52391 /* At the start of the iteration the point gpnt1 is put into both implicit 52392 equations */ 52393 52394 /* Set a number of local pointers that are used often */ 52395 sp = gpnt1; 52396 spu = gpnt1 + 3; 52397 spv = gpnt1 + 6; 52398 spn = gpnt1 + ksizem3; 52399 52400 kcont = 1; 52401 knbit = 0; 52402 52403 while (kcont) 52404 52405 { 52406 52407 /* For all degrees we have to put the B-spline surface into the plane 52408 determining the step length before we branch degree on the degree 52409 of the implicit surface. */ 52410 52411 ta21 = s6scpr(spu,snorm,kdim); 52412 ta22 = s6scpr(spv,snorm,kdim); 52413 s6diff(spoint,sp,kdim,sdiff); 52414 tb2 = s6scpr(sdiff,snorm,kdim); 52415 tdum = max(fabs(ta21),fabs(ta22)); 52416 tdum = max(tdum,fabs(tb2)); 52417 if (DEQUAL(tdum,DZERO)) tdum = (double)1.0; 52418 ta21 /= tdum; 52419 ta22 /= tdum; 52420 tb2 /= tdum; 52421 52422 52423 /* Calculate value and derivatives of the parametric surface put into 52424 the equation of the implicit surface */ 52425 52426 s1331(gpnt1,eimpli,ideg,1,sder,sproj,&kstat); 52427 52428 ta11 = sder[1]; 52429 ta12 = sder[2]; 52430 tb1 = -sder[0]; 52431 52432 tdum = max(fabs(ta11),fabs(ta12)); 52433 tdum = max(tdum,fabs(tb1)); 52434 if (DEQUAL(tdum,DZERO)) tdum = (double)1.0; 52435 ta11 /= tdum; 52436 ta12 /= tdum; 52437 tb1 /= tdum; 52438 52439 52440 /* Calculate determinant of equation system */ 52441 52442 tdum1 = ta11*ta22 - ta12*ta21; 52443 tdum = MAX(fabs(ta11),fabs(ta22)); 52444 tdum = MAX(fabs(ta12),tdum); 52445 tdum = MAX(fabs(ta21),tdum); 52446 52447 if (DEQUAL((tdum+tdum1),tdum)) tdum1 =DZERO; 52448 52449 52450 /* If tdum1 = 0.0, then the equation system is singular, try an 52451 alternative setup of the equation system */ 52452 52453 if (tdum1 == DZERO && ideg < 1003) 52454 { 52455 s6crss(sproj,snorm,sbinorm); 52456 ta11 = s6scpr(spu,sbinorm,kdim); 52457 ta12 = s6scpr(spv,sbinorm,kdim); 52458 tb1 = s6scpr(sdiff,sbinorm,kdim); 52459 52460 tdum = max(fabs(ta11),fabs(ta12)); 52461 tdum = max(tdum,fabs(tb1)); 52462 if (DEQUAL(tdum,DZERO)) tdum = (double)1.0; 52463 ta11 /= tdum; 52464 ta12 /= tdum; 52465 tb1 /= tdum; 52466 52467 /* Calculate determinant of equation system */ 52468 52469 tdum1 = ta11*ta22 - ta12*ta21; 52470 tdum = MAX(fabs(ta11),fabs(ta22)); 52471 tdum = MAX(fabs(ta12),tdum); 52472 tdum = MAX(fabs(ta21),tdum); 52473 52474 if (DEQUAL((tdum+tdum1),tdum)) tdum1 =DZERO; 52475 } 52476 52477 if (DNEQUAL(tdum1,DZERO)) 52478 { 52479 gpar1[0] += (tb1*ta22-tb2*ta12)/tdum1; 52480 gpar1[1] += (ta11*tb2-ta21*tb1)/tdum1; 52481 } 52482 52483 /* Calculate value of new points */ 52484 52485 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+ksizem3,&kstat); 52486 if (kstat<0) goto error; 52487 52488 /* If the surface normal has zero length no use in continuing */ 52489 52490 if (kstat == 2) goto war02; 52491 52492 52493 tcurdst = s1309(gpnt1,sproj,eimpli,ideg,&kstat); 52494 if (kstat < 0) goto error; 52495 if (kstat ==2) goto war02; 52496 52497 tcurdst = fabs(tcurdst); 52498 52499 /* Calculate distance from step plane */ 52500 52501 s6diff(spoint,gpnt1,kdim,sdiff); 52502 tdiststep = fabs(s6scpr(sdiff,snorm,kdim)/tlnorm); 52503 52504 52505 /* tcurdst now contains the distance between the point in the parametric 52506 surface and the projection along sproj of this point onto the implicit 52507 surface if ideg== 1,2 or 1001. In the case ideg==1003,1004,1005 we have a 52508 silhouette line and tcurdst contains the angle PI minus the angle 52509 between the view direction and the normal of the surface */ 52510 52511 /* We continue iteration so long as the error titer is not decreasing */ 52512 52513 52514 if (ideg==1003 || ideg==1004 || ideg==1005) 52515 { 52516 /* tcurdst contains an angle and is compared with ANGULAR_TOLERANCE, 52517 while tdiststep contains a distance and is compared with aepsge. 52518 To make a measure of these that is consistent they have to have 52519 the same unit measure thus we make. */ 52520 52521 titer = tcurdst*aepsge + tdiststep*ANGULAR_TOLERANCE; 52522 } 52523 else 52524 titer = tcurdst + tdiststep; 52525 52526 if (DEQUAL(tcurdst,DZERO) && DEQUAL(tdiststep,DZERO)) 52527 { 52528 /* Length is zero iteration has converged */ 52529 kcont = 0; 52530 } 52531 52532 if (knbit==0) 52533 { 52534 /* First iteration intitate distance variable, if the equation 52535 systems were not singular */ 52536 52537 if (DEQUAL(tdum1,DZERO)) goto war02; 52538 tdist = titer; 52539 knbit = 1; 52540 } 52541 else 52542 { 52543 /* More than one iteration done, stop if distance is not decreasing. 52544 Then decide if we converge distance between the points is within 52545 the tolerance and the last step had singular or none singular 52546 equation systems. */ 52547 52548 knbit = knbit + 1; 52549 if (titer>=tdist) 52550 { 52551 /* Distance is not decreasing */ 52552 52553 if (fabs(s6dist(sprev,gpnt1,kdim)) <= aepsge) 52554 { 52555 /* Distance within tolerance */ 52556 52557 /* Check if singularity reached. 52558 This is the case if tdum1=0.0 52559 or if the relative distance between 52560 the input point and 52561 the output point is within the 52562 relative computer resolution */ 52563 52564 ksing = 1; 52565 for (ki=0 ; ki<3; ki++) 52566 { 52567 tdum = MAX(fabs(epnt1[ki]),fabs(gpnt1[ki])); 52568 if (DEQUAL(tdum,DZERO)) tdum = (double)1.0; 52569 if(fabs(epnt1[ki]-gpnt1[ki])/tdum > REL_COMP_RES) 52570 ksing = 0; 52571 } 52572 if (DEQUAL(tdum1,DZERO) || ksing == 1) 52573 { 52574 /* Singular equation system */ 52575 goto war01; 52576 } 52577 else 52578 { 52579 /* Nonsingular equation system */ 52580 goto war00; 52581 } 52582 } 52583 else 52584 { 52585 /* Distance is not within tolerance, divergence */ 52586 goto war02; 52587 } 52588 } 52589 /* Distance still decreasing */ 52590 52591 tdist = titer; 52592 } 52593 52594 /* Make sure that not to many iteration are being done */ 52595 if (knbit > kmaxit) goto war02; 52596 /* Remember this point */ 52597 memcopy(sprev,gpnt1,3,DOUBLE); 52598 } 52599 52600 /* Iteration converged, calculate also second derivatives */ 52601 war00: 52602 52603 kder = 2; 52604 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+ksizem3,&kstat); 52605 if (kstat<0) goto error; 52606 52607 *jstat = 0; 52608 goto out; 52609 52610 /* Iteration converged, singular point found */ 52611 war01: 52612 *jstat = 1; 52613 goto out; 52614 52615 /* To many iterations or iteration diverging */ 52616 war02: 52617 *jstat = 2; 52618 goto out; 52619 52620 /* Error in lower level routine. */ 52621 52622 error : 52623 *jstat = kstat; 52624 s6err("s9iterimp",*jstat,kpos); 52625 goto out; 52626 52627 out: 52628 return; 52629 } 52630 52631 //=========================================================================== 52632 double s9adsimp(double epnt1[],double epar1[],double eimpli[],int ideg,double egd1[], 52633 double epgd1[],double etang[],double eptan[],double astep,int *jstat) 52634 //=========================================================================== 52635 { 52636 int kpos=1; /* Position indicator for errors */ 52637 int kstat; /* Dummy status variable */ 52638 int kdim=3; /* This routine is only working in 3-D */ 52639 int k2dim=2; /* Dimension of parameter plane */ 52640 int ksize; /* Number of doubles for storage of derivateves 52641 and normal vector */ 52642 int ksizem3; /* ksize - 3 */ 52643 double tdum; /* Variable for storage of reals */ 52644 double tdist=(double)0.0;/* Distance between guide point and point */ 52645 double sdiff[3]; /* Vector for difference between two points*/ 52646 double scr1[3],scr2[3]; /* Normal vectors */ 52647 double snorm[3]; /* Normal vector */ 52648 52649 52650 /* If ideg=1,2 or 1001 then only derivatives up to second order 52651 are calculated, then 18 doubles for derivatives and 3 for the 52652 normal vector are to be used for calculation of points in the 52653 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 52654 derivatives up to the third are to be calculated, 52655 thus 30 +3 a total of 33 doubles are to be calculated */ 52656 52657 if (ideg==1003 || ideg==1004 || ideg==1005) 52658 { 52659 ksize = 33; 52660 } 52661 else 52662 { 52663 ksize = 21; 52664 } 52665 ksizem3 = ksize -3; 52666 52667 /* First see that we are not turning direction in the parameter plane */ 52668 52669 s6diff(epgd1,epar1,k2dim,sdiff); 52670 if (s6scpr(sdiff,eptan,k2dim) < DZERO) goto dontstepthrough; 52671 52672 s6diff(egd1,epnt1,kdim,sdiff); 52673 tdum = s6scpr(sdiff,etang,kdim); 52674 tdist = s6length(sdiff,kdim,&kstat); 52675 52676 /* Step onto point if it is within 2.0*aepsge */ 52677 52678 if (tdum > DZERO) 52679 { 52680 if (DZERO < tdist && tdist <= (double)2.0*astep) 52681 { 52682 /* Guide point lies within step length and in step direction, test 52683 if cross products of normal vectors at current point and guide point 52684 point in the same direction, this is not possible to test on for 52685 silhouette curves */ 52686 52687 if (ideg < 1003) 52688 { 52689 52690 /* Make normal to implicit surface at epnt1 */ 52691 s1308(epnt1,3,eimpli,ideg,snorm,&kstat); 52692 if (kstat<0) goto error; 52693 52694 /* Make cross product of normals in start point */ 52695 s6crss(epnt1+ksizem3,snorm,scr1); 52696 52697 52698 /* Make normal to implicit surface at epnt1 */ 52699 s1308(epnt1,3,eimpli,ideg,snorm,&kstat); 52700 if (kstat<0) goto error; 52701 52702 /* Make cross product of normals in guide point */ 52703 s6crss(egd1+ksizem3,snorm,scr2); 52704 52705 52706 /* Make scalar product of these two vectors */ 52707 tdum = s6scpr(scr1,scr2,kdim); 52708 if (kstat<0) goto error; 52709 52710 /* If positive scalar product the curve at the two points point in 52711 the same direction, step through point */ 52712 if (tdum > DZERO) goto stepthrough; 52713 else if (tdum == DZERO) 52714 { 52715 52716 double tl1,tl2; 52717 52718 /* Vectors orthogonal or at least one has length zero */ 52719 52720 tl1 = s6length(scr1,kdim,&kstat); 52721 tl2 = s6length(scr2,kdim,&kstat); 52722 52723 if (tl1 != DZERO && tl2 != DZERO) 52724 goto dontstepthrough; 52725 else if (tl1 == DZERO && tl2 == DZERO) 52726 goto stepthrough; 52727 else if (tl2 == DZERO) 52728 goto stepthrough; 52729 else if (tl2 != DZERO) 52730 { 52731 /* Test if scr2 points in the direction from start */ 52732 52733 tl1 = s6scpr(sdiff,scr2,kdim); 52734 52735 if (tl1 < DZERO) 52736 goto dontstepthrough; 52737 else 52738 goto stepthrough; 52739 } 52740 } 52741 } 52742 else 52743 goto stepthrough; 52744 } 52745 } 52746 52747 dontstepthrough: 52748 52749 *jstat = 0; 52750 goto out; 52751 52752 stepthrough: 52753 *jstat = 1; 52754 goto out; 52755 52756 /* Error in lower leve function */ 52757 error: 52758 *jstat = kstat; 52759 s6err("s9adsimp",*jstat,kpos); 52760 goto out; 52761 52762 out: 52763 return(tdist); 52764 } 52765 52766 //=========================================================================== 52767 void s1331(double ep[],double eimpli[],int ideg,int ider, 52768 double gder[],double gnorm[],int *jstat) 52769 //=========================================================================== 52770 { 52771 int kstat = 0; /* Local status variable */ 52772 int ki,kj,kl; /* Control variables in loop */ 52773 int kpos = 0; /* Position of error */ 52774 int ksize; /* Number of doubles for storage of derivateves 52775 and normal vector */ 52776 int ksizem3; /* ksize - 3 */ 52777 double *spu; /* Pointer to dP/ds */ 52778 double *spv; /* Pointer to dP/dt */ 52779 double *spuu; /* Pointer to ddP/(dsds) */ 52780 double *spuv; /* Pointer to ddP/(dsdt) */ 52781 double *spvv; /* Pointer to ddP/(dtdt) */ 52782 52783 52784 /* If ideg=1,2 or 1001 then only derivatives up to second order 52785 are calculated, then 18 doubles for derivatives and 3 for the 52786 normal vector are to be used for calculation of points in the 52787 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 52788 derivatives up to the third are to be calculated, 52789 thus 30 +3 a total of 33 doubles may be calculated. 52790 Note, gnorm in these cases is replaced by f P - f P 52791 v u u v 52792 so we need ideg to be at least 1. */ 52793 52794 if (ideg == 1003 || ideg == 1004 || ideg == 1005) 52795 { 52796 ksize = 33; 52797 ider=max(ider,1); 52798 } 52799 else 52800 { 52801 ksize = 21; 52802 } 52803 52804 ksizem3 = ksize -3; 52805 52806 /* The calculation of the derivatives of one parameter direction with 52807 * respect to the other is dependent on the degree of the implicit equation 52808 */ 52809 52810 /* Set local pointers */ 52811 52812 spu = ep + 3; 52813 spv = ep + 6; 52814 spuu = ep + 9; 52815 spuv = ep + 12; 52816 spvv = ep + 15; 52817 52818 if (ideg == 1) 52819 { 52820 /* First degree implicit geometry. 52821 * 52822 * Let A = (eimpli[0],eimpli[1],eimpli[2],eimpli[3]) and 52823 * Q= (P(s,t),1), 52824 * then putting Q into the implicit equation gives 52825 * 52826 * f(u,v) = A Q 52827 * 52828 * df dQ 52829 * -- = A -- = N P , where N is the normal vector of the plane. 52830 * du du u 52831 * 52832 * df dQ 52833 * -- = A -- = N P 52834 * dv dv v 52835 * 52836 * 2 2 52837 * d f d Q 52838 * -- = A --- = N P 52839 * 2 2 uu 52840 * du du 52841 * 52842 * 2 2 52843 * d f d Q 52844 * -- = A --- = N P 52845 * dudv dudv uv 52846 * 52847 * 2 2 52848 * d f d Q 52849 * -- = A --- = N P 52850 * 2 2 vv 52851 * dv dv 52852 * 52853 */ 52854 if (ider>=0) 52855 { 52856 gder[0] = s6scpr(ep,eimpli,3) + eimpli[3]; 52857 if (ider>=1) 52858 { 52859 gder[1] = s6scpr(spu,eimpli,3); 52860 gder[2] = s6scpr(spv,eimpli,3); 52861 if (ider>=2) 52862 { 52863 gder[3] = s6scpr(spuu,eimpli,3); 52864 gder[4] = s6scpr(spuv,eimpli,3); 52865 gder[5] = s6scpr(spvv,eimpli,3); 52866 } 52867 } 52868 } 52869 memcopy(gnorm,eimpli,3,DOUBLE); 52870 } 52871 else if (ideg == 2) 52872 { 52873 double sq[4],sduq[4],sdvq[4]; /*vectors*/ 52874 double tsum1,tsum2,tsum3; /*Accumulation of matrix product */ 52875 52876 /* Second degree implicit geometry. 52877 * Denote the 4x4 matrix representing the implicit surface a A.* 52878 * 52879 * We can now calculate the u and v derivatives of the point put into 52880 * the left hand side of the implicit surface equation: 52881 * 52882 * T T 52883 * f(u,v) = Q A Q = sq Q 52884 * 52885 * d d T dQ T dQ 52886 * - f = -- (Q A Q ) = 2 -- A Q = 2 sq -- 52887 * du du du du 52888 * 52889 * d d T dQ T dQ 52890 * - f = -- (Q A Q ) = 2 -- A Q = 2 sq -- 52891 * dv dv dv dv 52892 * 52893 * 2 2 2 T 2 52894 * d d T d Q T dQ dQ dQ dQ 52895 * -- f = -- (Q A Q ) = 2 --- A Q + 2 -- A -- = 2(sq--- + sduq--) 52896 * 2 2 2 du du 2 du 52897 * du du du du 52898 * 52899 * 2 2 2 T 2 52900 * d d T d Q T dQ dQ d Q dQ 52901 * -- f = -- (Q A Q ) = 2 ----AQ + 2 --A-- = 2(sq---- + sduq--) 52902 * dudv dudv dudv du dv dudv dv 52903 * 52904 * 2 2 2 T 2 52905 * d d T d Q T dQ dQ dQ dQ 52906 * -- f = -- (Q A Q ) = 2 --- A Q + 2 -- A -- = 2(sq-- + sdvq--) 52907 * 2 2 2 dv dv 2 dv 52908 * dv dv dv dv 52909 * 52910 * dQ dQ 52911 * First calculate sq = QA, sduq = --A and sdvq = --A 52912 * du dv 52913 * 52914 */ 52915 for (ki=0;ki<4;ki++) 52916 { 52917 tsum1 = eimpli[ki+12]; 52918 tsum2 = DZERO; 52919 tsum3 = DZERO; 52920 for (kj=0,kl=ki;kj<3;kj++,kl+=4) 52921 { 52922 tsum1 += eimpli[kl]*ep[kj]; 52923 if (ider>=1) 52924 { 52925 tsum2 += eimpli[kl]*spu[kj]; 52926 tsum3 += eimpli[kl]*spv[kj]; 52927 } 52928 } 52929 sq[ki] = tsum1; 52930 sduq[ki] = tsum2; 52931 sdvq[ki] = tsum3; 52932 } 52933 52934 /* Make value and partial derivatives */ 52935 52936 if (ider>=0) 52937 { 52938 gder[0] = s6scpr(sq,ep,3) + sq[3]; 52939 if(ider>=1) 52940 { 52941 gder[1] = (double)2.0*s6scpr(sq,spu,3); 52942 gder[2] = (double)2.0*s6scpr(sq,spv,3); 52943 if (ider>1) 52944 { 52945 gder[3] = (double)2.0*(s6scpr(sq,spuu,3) + 52946 s6scpr(sduq,spu,3)); 52947 gder[4] = (double)2.0*(s6scpr(sq,spuv,3) + 52948 s6scpr(sduq,spv,3)); 52949 gder[5] = (double)2.0*(s6scpr(sq,spvv,3) + 52950 s6scpr(sdvq,spv,3)); 52951 } 52952 } 52953 } 52954 memcopy(gnorm,sq,3,DOUBLE); 52955 } 52956 52957 else if (ideg == 1001) 52958 { 52959 double sy[3],sz[3],szu[3],szv[3],szuu[3],szuv[3],szvv[3];/* Derivatives */ 52960 double tzn,tzun,tzvn,tzuun,tzuvn,tzvvn; /* Scalar products */ 52961 double tzduz,tzdvz,tzduduz,tzdudvz,tzdvdvz; /* Scalar products */ 52962 double tduzduz,tdvzdvz,tduzdvz; /* Scalar products */ 52963 double tlenz,tlenz3,tlenz5; /* Vector lengths */ 52964 double sp[3],sdup[3],sdvp[3]; /* temporary vectrs*/ 52965 double sdudup[3],sdudvp[3],sdvdvp[3]; /* temporary vectrs*/ 52966 double *scentr,*saxis,tbigr,tsmalr; /* Torus descript */ 52967 52968 /* Torus surface. */ 52969 52970 scentr = eimpli; 52971 saxis = eimpli + 3; 52972 tbigr = *(eimpli+6); 52973 tsmalr = *(eimpli+7); 52974 52975 52976 /* Intersection of implicit function of 1 and implicit torus surface 52977 * and the the surface. Make the following temporary variables. 52978 * 52979 * y = p - scentr 52980 * z = y - (y saxis) saxis 52981 * 52982 * Put the point and accompanying derivatives into the implicit 52983 * representation of the torus 52984 * 52985 * 2 2 52986 * f(u,v) = (y - R z/sqrt(z z) ) - r 52987 * 52988 * 52989 * 52990 * R z (z z ) 52991 * df R z u R z u 52992 * -- = 2(y - ---------)(y - --------- + ----------) 52993 * du sqrt(z z) u sqrt(z z) 3 52994 * sqrt(z z) 52995 * 52996 * = 2 sp sdup 52997 * 52998 * 52999 * R z (z z ) 53000 * df R z v R z v 53001 * -- = 2(y - ---------)(y - --------- + ----------) 53002 * dv sqrt(z z) v sqrt(z z) 3 53003 * sqrt(z z) 53004 * 53005 * = 2 sp sdvp 53006 * 53007 * 53008 * 53009 * 53010 * 2 R z (z z ) 53011 * d f u R z u 2 53012 * -- = 2(y - --------- + -----------) + 53013 * 2 u sqrt(z z) 3 53014 * du sqrt(z z) 53015 * 53016 * 53017 * R z z (z z ) 53018 * R z uu 2R u u 53019 * 2(y - ---------)(y - --------- + ----------- + 53020 * sqrt(z z) uu sqrt(z z) 3 53021 * sqrt(z z) 53022 * 53023 * 53024 * 2 53025 * R z(z z +zz ) z(zz ) 53026 * u u uu R u 53027 * -------------- - 3 --------- ) 53028 * 3 5 53029 * sqrt(z z) sqrt(z z) 53030 * 53031 * = 2 sdup sdup + sp sdudup 53032 * 53033 * 53034 * 2 R z (z z ) R z (z z ) 53035 * d f u R z u v R z v 53036 * ---- = 2(y - --------- + -----------)(y - --------- + -----------) + 53037 * u sqrt(z z) 3 v sqrt(z z) 3 53038 * dudv sqrt(z z) sqrt(z z) 53039 * 53040 * 53041 * R z z (z z ) z (z z ) 53042 * R z uv R u v R v u 53043 * 2(y - ---------)(y - --------- + ------------ + ------------ + 53044 * sqrt(z z) uv sqrt(z z) 3 3 53045 * sqrt(z z) sqrt(z z) 53046 * 53047 * 53048 * 53049 * R z(z z +zz ) z(zz )(zz ) 53050 * v u uv R u v 53051 * -------------- - 3 -------------) 53052 * 3 5 53053 * sqrt(z z) sqrt(z z) 53054 * 53055 * 53056 * = 2 sdup sdvp + sp sdudvp 53057 * 53058 * 53059 * 2 R z (z z ) 53060 * d f v R z v 2 53061 * -- = 2(y - --------- + -----------) + 53062 * 2 v sqrt(z z) 3 53063 * dv sqrt(z z) 53064 * 53065 * 53066 * R z z (z z ) 53067 * R z vv 2R v v 53068 * 2(y - ---------)(y - --------- + ------------ + 53069 * sqrt(z z) vv sqrt(z z) 3 53070 * sqrt(z z) 53071 * 53072 * 53073 * 2 53074 * R z(z z +zz ) z(zz ) 53075 * v v vv R v 53076 * -------------- - 3 --------- ) 53077 * 3 5 53078 * sqrt(z z) sqrt(z z) 53079 * 53080 * 53081 * = 2 sdvp sdvp + sp sdvdvp 53082 * 53083 * 53084 * 53085 * y = (p - scentr) = p 53086 * u u u 53087 * 53088 * y = (p - scentr) = p 53089 * v v v 53090 * 53091 * y = (p - scentr) = p 53092 * uu uu uu 53093 * 53094 * y = (p - scentr) = p 53095 * uv uv uv 53096 * 53097 * y = (p - scentr) = p 53098 * vv vv vv 53099 * 53100 * z = (y - (y N)N) = p - (p N)N N = saxis (Torus axis) 53101 * u u u u 53102 * 53103 * z = (y - (y N)N) = p - (p N)N 53104 * v v v v 53105 * 53106 * z = (y - (y N)N) = p - (p N)N 53107 * uu uu uu uu 53108 * 53109 * z = (y - (y N)N) = p - (p N)N 53110 * uv uv uv uv 53111 * 53112 * z = (y - (y N)N) = p - (p N)N 53113 * vv vv vv vv 53114 * 53115 */ 53116 for (ki=0;ki<3;ki++) 53117 sy[ki] = ep[ki] - scentr[ki]; 53118 53119 tzn = s6scpr(sy ,saxis,3); 53120 tzun = s6scpr(spu ,saxis,3); 53121 tzvn = s6scpr(spv ,saxis,3); 53122 if (ider>1) 53123 { 53124 tzuun = s6scpr(spuu,saxis,3); 53125 tzuvn = s6scpr(spuv,saxis,3); 53126 tzvvn = s6scpr(spvv,saxis,3); 53127 } 53128 53129 /* Make z and necessary derivatives of z */ 53130 for (ki=0;ki<3;ki++) 53131 { 53132 sz[ki] = sy[ki] - tzn*saxis[ki]; 53133 szu[ki] = spu[ki] - tzun*saxis[ki]; 53134 szv[ki] = spv[ki] - tzvn*saxis[ki]; 53135 if (ider>1) 53136 { 53137 szuu[ki] = spuu[ki] - tzuun*saxis[ki]; 53138 szuv[ki] = spuv[ki] - tzuvn*saxis[ki]; 53139 szvv[ki] = spvv[ki] - tzvvn*saxis[ki]; 53140 } 53141 } 53142 53143 /* Make a number of necessary scalar products */ 53144 53145 tzduz = s6scpr(sz,szu,3); 53146 tzdvz = s6scpr(sz,szv,3); 53147 tduzduz = s6scpr(szu,szu,3); 53148 tduzdvz = s6scpr(szu,szv,3); 53149 tdvzdvz = s6scpr(szv,szv,3); 53150 if (ider>1) 53151 { 53152 tzduduz = s6scpr(sz,szuu,3); 53153 tzdudvz = s6scpr(sz,szuv,3); 53154 tzdvdvz = s6scpr(sz,szvv,3); 53155 } 53156 53157 /* Find lengt of sz */ 53158 53159 tlenz = s6length(sz,3,&kstat); 53160 53161 if (kstat<0) goto error; 53162 if (DEQUAL(tlenz,DZERO)) tlenz =(double)1.0; 53163 tlenz3 = tlenz*tlenz*tlenz; 53164 tlenz5 = tlenz3*tlenz*tlenz; 53165 53166 /* Make a number of necessary vectors */ 53167 53168 for (ki=0;ki<3;ki++) 53169 { 53170 sp[ki] = sy[ki] - tbigr*sz[ki]/tlenz; 53171 if (ider>=1) 53172 { 53173 sdup[ki] = spu[ki] - tbigr*(szu[ki]/tlenz - sz[ki]*tzduz/tlenz3); 53174 sdvp[ki] = spv[ki] - tbigr*(szv[ki]/tlenz - sz[ki]*tzdvz/tlenz3); 53175 if (ider>=2) 53176 { 53177 sdudup[ki] = spuu[ki] - 53178 tbigr*(szuu[ki]/tlenz - 53179 ((double)2.0*szu[ki]*tzduz+ 53180 sz[ki]*(tduzduz+tzduduz))/tlenz3 + 53181 (double)3.0*sz[ki]*tzduz*tzduz/tlenz5); 53182 53183 sdudvp[ki] = spuv[ki] - 53184 tbigr*(szuv[ki]/tlenz - 53185 (szu[ki]*tzdvz+szv[ki]*tzduz+ 53186 sz[ki]*(tduzdvz+tzdudvz))/tlenz3 + 53187 (double)3.0*sz[ki]*tzduz*tzdvz/tlenz5); 53188 53189 sdvdvp[ki] = spvv[ki] - 53190 tbigr*(szvv[ki]/tlenz - 53191 ((double)2.0*szv[ki]*tzdvz+ 53192 sz[ki]*(tdvzdvz+tzdvdvz))/tlenz3 + 53193 (double)3.0*sz[ki]*tzdvz*tzdvz/tlenz5); 53194 } 53195 } 53196 } 53197 53198 /* Make the derivatives */ 53199 if (ider>=0) 53200 { 53201 gder[0] = s6scpr(sp,sp,3) - tsmalr*tsmalr; 53202 if (ider>=1) 53203 { 53204 gder[1] = (double)2.0*s6scpr(sp,sdup,3); 53205 gder[2] = (double)2.0*s6scpr(sp,sdvp,3); 53206 if (ider>=2) 53207 { 53208 gder[3] = (double)2.0*(s6scpr(sdup,sdup,3)+ 53209 s6scpr(sp,sdudup,3)); 53210 gder[4] = (double)2.0*(s6scpr(sdup,sdvp,3)+ 53211 s6scpr(sp,sdudvp,3)); 53212 gder[5] = (double)2.0*(s6scpr(sdvp,sdvp,3)+ 53213 s6scpr(sp,sdvdvp,3)); 53214 } 53215 } 53216 } 53217 memcopy(gnorm,sp,3,DOUBLE); 53218 } 53219 53220 else if (ideg == 1003) 53221 53222 { 53223 53224 /* Silhouette curve, the first three elements of eimpli describes 53225 the viewing direction. 53226 53227 The silhouette line is descibed by the implicit equation, when 53228 Q(u,v) is the description of the surface: 53229 53230 f(u,v) = (Q x Q ) view = 0 53231 u v 53232 53233 f = (Q x Q ) view + (Q x Q ) view 53234 u uu v u uv 53235 53236 53237 f = (Q x Q ) view + (Q x Q ) view 53238 v uv v u vv 53239 53240 53241 53242 f = (Q x Q ) view + 2 (Q x Q ) view + (Q x Q ) view 53243 uu uuu v uu uv u uuv 53244 53245 53246 f = (Q x Q )view + (Q x Q )view + (Q x Q )view + (Q xQ)view 53247 uv uuv v uu vv uv uv u uvv 53248 53249 53250 f = (Q x Q ) view + 2 (Q x Q ) view + (Q x Q ) view 53251 vv uvv v uv vv u vvv 53252 53253 53254 Note that Q x Q has zero length. 53255 uv uv 53256 */ 53257 double *spuuu = ep + 18; 53258 double *spuuv = ep + 21; 53259 double *spuvv = ep + 24; 53260 double *spvvv = ep + 27; 53261 double sdum1[3],sdum2[3],sdum3[3]; 53262 53263 if (ider>=0) 53264 { 53265 s6crss(spu,spv,sdum1); 53266 gder[0] = s6scpr(sdum1,eimpli,3); 53267 if (ider>=1) 53268 { 53269 s6crss(spuu,spv,sdum1); 53270 s6crss(spu,spuv,sdum2); 53271 gder[1] = s6scpr(sdum1,eimpli,3) + s6scpr(sdum2,eimpli,3); 53272 s6crss(spuv,spv,sdum1); 53273 s6crss(spu,spvv,sdum2); 53274 gder[2] = s6scpr(sdum1,eimpli,3) + s6scpr(sdum2,eimpli,3); 53275 if (ider>=2) 53276 { 53277 s6crss(spuuu,spv, sdum1); 53278 s6crss(spuu, spuv, sdum2); 53279 s6crss(spu, spuuv,sdum3); 53280 gder[3] = s6scpr(sdum1,eimpli,3) + 53281 (double)2.0*s6scpr(sdum2,eimpli,3) 53282 + s6scpr(sdum3,eimpli,3);; 53283 s6crss(spuuv,spv, sdum1); 53284 s6crss(spuu, spvv, sdum2); 53285 s6crss(spu, spuvv,sdum3); 53286 gder[4] = s6scpr(sdum1,eimpli,3) + s6scpr(sdum2,eimpli,3) 53287 + s6scpr(sdum3,eimpli,3);; 53288 s6crss(spuvv,spv, sdum1); 53289 s6crss(spuv, spvv, sdum2); 53290 s6crss(spu, spvvv,sdum3); 53291 gder[5] = s6scpr(sdum1,eimpli,3) + 53292 (double)2.0*s6scpr(sdum2,eimpli,3) 53293 + s6scpr(sdum3,eimpli,3);; 53294 } 53295 } 53296 } 53297 } 53298 53299 else if (ideg == 1004) 53300 53301 { 53302 53303 /* Perspective silhouette curve, the first three elements of eimpli 53304 describe the eye point E. 53305 53306 The silhouette line is descibed by the implicit equation, when 53307 P(u,v) is the description of the surface and 53308 N(u,v) = P x P is the normal to the surface: 53309 u v 53310 53311 f(u,v) = N(u,v) . (P(u,v) - E) = 0 53312 53313 Differentiating N gives: 53314 53315 N = P x P + P x P 53316 u uu v u uv 53317 53318 N = P x P + P x P 53319 v uv v u vv 53320 53321 N = P x P + 2 P x P + P x P 53322 uu uuu v uu uv u uuv 53323 53324 N = P x P + P x P + P x P 53325 uv uuu v uu vv u uuv 53326 53327 N = P x P + 2 P x P + P x P 53328 vv uvv v uv vv u vvv 53329 53330 53331 53332 Differentiating f gives: 53333 53334 f = N . (P - E) 53335 u u 53336 53337 f = N . (P - E) 53338 v v 53339 53340 f = N . (P - E) + N . P 53341 uu uu u u 53342 53343 f = N . (P - E) + N . P 53344 uv uv u v 53345 53346 f = N . (P - E) + N . P 53347 vv vv v v 53348 53349 53350 */ 53351 double *spuuu = ep + 18; 53352 double *spuuv = ep + 21; 53353 double *spuvv = ep + 24; 53354 double *spvvv = ep + 27; 53355 double norm[3],normu[3],normv[3],normuu[3],normuv[3],normvv[3]; 53356 double cprod1[3],cprod2[3],cprod3[3]; 53357 double pediff[3]; 53358 53359 53360 if (ider>=0) 53361 { 53362 s6diff(ep,eimpli,3,pediff); 53363 53364 s6crss(spu,spv,norm); 53365 gder[0] = s6scpr(norm,pediff,3); 53366 53367 if (ider>=1) 53368 { 53369 s6crss(spuu,spv,cprod1); 53370 s6crss(spu,spuv,cprod2); 53371 for (ki=0;ki<3;ki++) 53372 { 53373 normu[ki] = cprod1[ki] + cprod2[ki]; 53374 } 53375 s6crss(spuv,spv,cprod1); 53376 s6crss(spu,spvv,cprod2); 53377 for (ki=0;ki<3;ki++) 53378 { 53379 normv[ki] = cprod1[ki] + cprod2[ki]; 53380 } 53381 53382 gder[1] = s6scpr(normu,pediff,3); 53383 gder[2] = s6scpr(normv,pediff,3); 53384 53385 if (ider>=2) 53386 { 53387 s6crss(spuuu,spv,cprod1); 53388 s6crss(spuu,spuv,cprod2); 53389 s6crss(spu,spuuv,cprod3); 53390 for (ki=0;ki<3;ki++) 53391 { 53392 normuu[ki] = cprod1[ki] + 2.0 * cprod2[ki] + cprod3[ki]; 53393 } 53394 53395 /* Note that spuv x spuv = 0 in the formula for normuv */ 53396 s6crss(spuuv,spv,cprod1); 53397 s6crss(spuu,spvv,cprod2); 53398 s6crss(spu,spuvv,cprod3); 53399 for (ki=0;ki<3;ki++) 53400 { 53401 normuv[ki] = cprod1[ki] + cprod2[ki] + cprod3[ki]; 53402 } 53403 53404 s6crss(spuvv,spv,cprod1); 53405 s6crss(spuv,spvv,cprod2); 53406 s6crss(spu,spvvv,cprod3); 53407 for (ki=0;ki<3;ki++) 53408 { 53409 normvv[ki] = cprod1[ki] + 2.0 * cprod2[ki] + cprod3[ki]; 53410 } 53411 53412 gder[3] = s6scpr(normuu,pediff,3) + s6scpr(normu,spu,3); 53413 gder[4] = s6scpr(normuv,pediff,3) + s6scpr(normu,spv,3); 53414 gder[5] = s6scpr(normvv,pediff,3) + s6scpr(normv,spv,3); 53415 53416 } 53417 } 53418 } 53419 } 53420 53421 else if (ideg == 1005) 53422 53423 { 53424 53425 /* Perspective silhouette curve, the first three elements of eimpli 53426 describe Q, the next three describe B. 53427 53428 The silhouette line is descibed by the implicit equation, when 53429 P(u,v) is the description of the surface and 53430 N(u,v) = P x P is the normal to the surface: 53431 u v 53432 53433 f(u,v) = N(u,v) x (P(u,v) - Q) . B = 0 53434 53435 Differentiating N gives: 53436 53437 N = P x P + P x P 53438 u uu v u uv 53439 53440 N = P x P + P x P 53441 v uv v u vv 53442 53443 N = P x P + 2 P x P + P x P 53444 uu uuu v uu uv u uuv 53445 53446 N = P x P + P x P + P x P 53447 uv uuu v uu vv u uuv 53448 53449 N = P x P + 2 P x P + P x P 53450 vv uvv v uv vv u vvv 53451 53452 53453 53454 Differentiating f gives: 53455 53456 f = { N x (P - Q) + N x P } . B 53457 u u u 53458 53459 f = { N x (P - Q) + N x P } . B 53460 v v v 53461 53462 f = { N x (P - Q) + 2 N x P + N x P } . B 53463 uu uu u u uu 53464 53465 f = { N x (P - Q) + N x P + N x P + N x P } . B 53466 uv uv u v v u uv 53467 53468 f = { N x (P - Q) + 2 N x P + N x P } . B 53469 vv vv v v vv 53470 53471 53472 */ 53473 double *spuuu = ep + 18; 53474 double *spuuv = ep + 21; 53475 double *spuvv = ep + 24; 53476 double *spvvv = ep + 27; 53477 double *bvec = eimpli + 3; 53478 double norm[3],normu[3],normv[3],normuu[3],normuv[3],normvv[3]; 53479 double cprod1[3],cprod2[3],cprod3[3],cprod4[3]; 53480 double pqdiff[3],sum[3]; 53481 53482 53483 if (ider>=0) 53484 { 53485 s6diff(ep,eimpli,3,pqdiff); 53486 53487 s6crss(spu,spv,norm); 53488 s6crss(norm,pqdiff,cprod1); 53489 gder[0] = s6scpr(cprod1,bvec,3); 53490 53491 if (ider>=1) 53492 { 53493 s6crss(spuu,spv,cprod1); 53494 s6crss(spu,spuv,cprod2); 53495 for (ki=0;ki<3;ki++) 53496 { 53497 normu[ki] = cprod1[ki] + cprod2[ki]; 53498 } 53499 s6crss(spuv,spv,cprod1); 53500 s6crss(spu,spvv,cprod2); 53501 for (ki=0;ki<3;ki++) 53502 { 53503 normv[ki] = cprod1[ki] + cprod2[ki]; 53504 } 53505 53506 s6crss(normu,pqdiff,cprod1); 53507 s6crss(norm,spu,cprod2); 53508 for (ki=0;ki<3;ki++) 53509 { 53510 sum[ki] = cprod1[ki] + cprod2[ki]; 53511 } 53512 gder[1] = s6scpr(sum,bvec,3); 53513 53514 s6crss(normv,pqdiff,cprod1); 53515 s6crss(norm,spv,cprod2); 53516 for (ki=0;ki<3;ki++) 53517 { 53518 sum[ki] = cprod1[ki] + cprod2[ki]; 53519 } 53520 gder[2] = s6scpr(sum,bvec,3); 53521 53522 if (ider>=2) 53523 { 53524 s6crss(spuuu,spv,cprod1); 53525 s6crss(spuu,spuv,cprod2); 53526 s6crss(spu,spuuv,cprod3); 53527 for (ki=0;ki<3;ki++) 53528 { 53529 normuu[ki] = cprod1[ki] + 2.0 * cprod2[ki] + cprod3[ki]; 53530 } 53531 53532 /* Note that spuv x spuv = 0 in the formula for normuv */ 53533 s6crss(spuuv,spv,cprod1); 53534 s6crss(spuu,spvv,cprod2); 53535 s6crss(spu,spuvv,cprod3); 53536 for (ki=0;ki<3;ki++) 53537 { 53538 normuv[ki] = cprod1[ki] + cprod2[ki] + cprod3[ki]; 53539 } 53540 53541 s6crss(spuvv,spv,cprod1); 53542 s6crss(spuv,spvv,cprod2); 53543 s6crss(spu,spvvv,cprod3); 53544 for (ki=0;ki<3;ki++) 53545 { 53546 normvv[ki] = cprod1[ki] + 2.0 * cprod2[ki] + cprod3[ki]; 53547 } 53548 53549 s6crss(normuu,pqdiff,cprod1); 53550 s6crss(normu,spu,cprod2); 53551 s6crss(norm,spuu,cprod3); 53552 for (ki=0;ki<3;ki++) 53553 { 53554 sum[ki] = cprod1[ki] + 2.0 * cprod2[ki] + cprod3[ki]; 53555 } 53556 gder[3] = s6scpr(sum,bvec,3); 53557 53558 s6crss(normuv,pqdiff,cprod1); 53559 s6crss(normu,spv,cprod2); 53560 s6crss(normv,spu,cprod3); 53561 s6crss(norm,spuv,cprod4); 53562 for (ki=0;ki<3;ki++) 53563 { 53564 sum[ki] = cprod1[ki] + cprod2[ki] + cprod3[ki] + cprod4[ki]; 53565 } 53566 gder[4] = s6scpr(sum,bvec,3); 53567 53568 s6crss(normvv,pqdiff,cprod1); 53569 s6crss(normv,spv,cprod2); 53570 s6crss(norm,spvv,cprod3); 53571 for (ki=0;ki<3;ki++) 53572 { 53573 sum[ki] = cprod1[ki] + 2.0 * cprod2[ki] + cprod3[ki]; 53574 } 53575 gder[5] = s6scpr(sum,bvec,3); 53576 53577 } 53578 } 53579 } 53580 } 53581 53582 if(ideg == 1003 || ideg == 1004 || ideg == 1005) 53583 { 53584 /* The normal vector has no meaning in this case 53585 so we calculate the direction D(u,v) of the solution curve 53586 on the surface P(u,v) 53587 of f(u,v) = N(u,v) . d = 0 (ideg = 1003) 53588 or f(u,v) = N(u,v) . (P(u,v) - E) = 0 (ideg = 1004) 53589 or f(u,v) = N(u,v) x (P(u,v) - Q) . B = 0 (ideg = 1005) 53590 (through the present solution point) 53591 directly. This direction D is in fact f P - f P 53592 v u u v 53593 where P(u,v) is the parameterised 53594 surface, N is the normal P x P , and d is the 53595 u v 53596 view direction. The direction D is used by s1331. */ 53597 53598 for(ki=0; ki<3; ki++) 53599 { 53600 gnorm[ki] = gder[2] * spu[ki] - gder[1] * spv[ki]; 53601 } 53602 (void)s6norm(gnorm,3,gnorm,&kstat); 53603 } 53604 53605 /* Everyting is ok */ 53606 53607 *jstat = 0; 53608 goto out; 53609 53610 53611 /* Error in lower level function */ 53612 error: 53613 *jstat = kstat; 53614 s6err("s1331",*jstat,kpos); 53615 goto out; 53616 53617 out: 53618 return; 53619 } 53620 53621 //=========================================================================== 53622 void s1305(double epar1[],double epar2[],double eval1[],double eval2[], 53623 int *jbound,double gpar[],int *jstat) 53624 //=========================================================================== 53625 { 53626 int kstat; /* Local status variable */ 53627 int kins1; /* epar1 inside/outside SISLbox */ 53628 int kins2; /* epar2 inside/outside SISLbox */ 53629 double tdom; /* Denominator of last intersection point */ 53630 double tfak1,tfak2; /* Distance to straight line */ 53631 double tcdist=HUGE; /* Current distance */ 53632 double tpdist=HUGE; /* Previous distance */ 53633 double simpli[5]; /* Corners of the parameter area pu into the 53634 implicit equation of the line through epar1 and 53635 epar2. */ 53636 double snorm[2]; /* Normal vector */ 53637 double stemp[2]; /* Candidate point */ 53638 double *outside=epar1; /* Pointer to the point that is outside; */ 53639 *jbound = 0; 53640 53641 /* Test if both ends are inside */ 53642 53643 kins1 = kins2 = 0; 53644 53645 if (eval1[0] <= epar1[0] && epar1[0] <= eval1[1] && 53646 eval2[0] <= epar1[1] && epar1[1] <= eval2[1]) kins1 = 1; 53647 53648 if( eval1[0] <= epar2[0] && epar2[0] <= eval1[1] && 53649 eval2[0] <= epar2[1] && epar2[1] <= eval2[1]) kins2 = 1; 53650 53651 if (kins1==1 && kins2==1) goto war01; 53652 53653 if (kins1) outside = epar2; 53654 53655 /* Test if we step from the boundary and out */ 53656 53657 if ((eval1[0] == epar1[0] && epar2[0] < eval1[0]) || 53658 (epar1[0] == eval1[1] && eval1[1] < epar2[0]) || 53659 (eval2[0] == epar1[1] && epar2[1] < eval2[0]) || 53660 (epar1[1] == eval2[1] && eval2[1] < epar2[1]) ) goto war04; 53661 53662 /* Test if both ends are to the left, right, below or above */ 53663 53664 if ( (epar1[0] < eval1[0] && epar2[0] < eval1[0]) || 53665 (eval1[1] < epar1[0] && eval1[1] < epar2[0]) || 53666 (epar1[1] < eval2[0] && epar2[1] < eval2[0]) || 53667 (eval2[1] < epar1[1] && eval2[1] < epar2[1]) ) goto war00; 53668 53669 /* Make normal vector of line though epar1 and epar2 */ 53670 53671 snorm[0] = -(epar2[1] - epar1[1]); 53672 snorm[1] = epar2[0] - epar1[0]; 53673 53674 (void)s6norm(snorm,2,snorm,&kstat); 53675 53676 /* Put corners of parameter area into the implicit equation of the straight 53677 line */ 53678 53679 simpli[0] = (eval1[0]-epar1[0])*snorm[0] + (eval2[0]-epar1[1])*snorm[1]; 53680 simpli[1] = (eval1[0]-epar1[0])*snorm[0] + (eval2[1]-epar1[1])*snorm[1]; 53681 simpli[2] = (eval1[1]-epar1[0])*snorm[0] + (eval2[1]-epar1[1])*snorm[1]; 53682 simpli[3] = (eval1[1]-epar1[0])*snorm[0] + (eval2[0]-epar1[1])*snorm[1]; 53683 simpli[4] = simpli[0]; 53684 53685 /* If simpli[0:3] all have the same sign, the straight line is outside */ 53686 53687 if ((simpli[0]>(double)0.0 && simpli[1]>(double)0.0 && 53688 simpli[2]>(double)0.0 && simpli[3]>(double)0.0) || 53689 (simpli[0]<(double)0.0 && simpli[1]<(double)0.0 && 53690 simpli[2]<(double)0.0 && simpli[3]<(double)0.0) ) goto war00; 53691 53692 /* Treate intersections with left boundary */ 53693 53694 if (simpli[0]*simpli[1] <= (double)0.0 && epar1[0] != eval1[0]) 53695 { 53696 /* Intersection along left boundary */ 53697 53698 tfak1 = fabs(simpli[0]); 53699 tfak2 = fabs(simpli[1]); 53700 tdom = tfak1 + tfak2; 53701 53702 if (DNEQUAL(tdom,(double)0.0)) 53703 { 53704 /* The straight line and the left boundary does not coinside */ 53705 53706 stemp[0] = eval1[0]; 53707 stemp[1] = (tfak2*eval2[0] + tfak1*eval2[1])/tdom; 53708 tcdist = s6dist(stemp, outside,2); 53709 if (*jbound == 0 || tcdist < tpdist) 53710 { 53711 /* New point closer than previous intersection point */ 53712 53713 gpar[0] = stemp[0]; 53714 gpar[1] = stemp[1]; 53715 *jbound = 1; 53716 tpdist = tcdist; 53717 } 53718 } 53719 } 53720 53721 /* Treate intersections with upper boundary */ 53722 53723 if (simpli[1]*simpli[2] <= (double)0.0 && epar1[1] != eval2[1]) 53724 { 53725 /* Intersection along upper boundary */ 53726 53727 tfak1 = fabs(simpli[1]); 53728 tfak2 = fabs(simpli[2]); 53729 tdom = tfak1 + tfak2; 53730 if (DNEQUAL(tdom,(double)0.0)) 53731 { 53732 /* The straight line and the upper boundary does not coinside */ 53733 53734 stemp[0] = (tfak2*eval1[0] + tfak1*eval1[1])/tdom; 53735 stemp[1] = eval2[1]; 53736 tcdist = s6dist(stemp, outside,2); 53737 53738 if (*jbound == 0 || tcdist < tpdist) 53739 { 53740 /* New point closer than previous intersection point */ 53741 53742 gpar[0] = stemp[0]; 53743 gpar[1] = stemp[1]; 53744 *jbound = 2; 53745 tpdist = tcdist; 53746 } 53747 } 53748 } 53749 53750 /* Treate intersections with right boundary */ 53751 53752 if (simpli[2]*simpli[3] <= (double)0.0 && epar1[0] != eval1[1]) 53753 { 53754 /* Intersection along right boundary */ 53755 53756 tfak1 = fabs(simpli[2]); 53757 tfak2 = fabs(simpli[3]); 53758 tdom = tfak1 + tfak2; 53759 if (DNEQUAL(tdom,(double)0.0)) 53760 { 53761 /* The straight line and the right boundary does not coinside */ 53762 53763 stemp[0] = eval1[1]; 53764 stemp[1] = (tfak2*eval2[1] + tfak1*eval2[0])/tdom; 53765 tcdist = s6dist(stemp, outside,2); 53766 53767 if (*jbound == 0 || tcdist < tpdist) 53768 { 53769 /* New point closer than previous intersection point */ 53770 53771 gpar[0] = stemp[0]; 53772 gpar[1] = stemp[1]; 53773 *jbound = 3; 53774 tpdist = tcdist; 53775 } 53776 } 53777 } 53778 53779 /* Treate intersections with lower boundary */ 53780 53781 if (simpli[3]*simpli[4] <= (double)0.0 && epar1[1] != eval2[0]) 53782 { 53783 /* Intersection along lower boundary */ 53784 53785 tfak1 = fabs(simpli[3]); 53786 tfak2 = fabs(simpli[4]); 53787 tdom = tfak1 + tfak2; 53788 if (DNEQUAL(tdom,(double)0.0)) 53789 { 53790 /* The straight line and the lower boundary does not coinside */ 53791 53792 stemp[0] = (tfak2*eval1[1] + tfak1*eval1[0])/tdom; 53793 stemp[1] = eval2[0]; 53794 tcdist = s6dist(stemp, outside,2); 53795 53796 if (*jbound == 0 || tcdist < tpdist) 53797 { 53798 /* New point closer than previous intersection point */ 53799 53800 gpar[0] = stemp[0]; 53801 gpar[1] = stemp[1]; 53802 *jbound = 4; 53803 tpdist = tcdist; 53804 } 53805 } 53806 } 53807 53808 if (kins1 == 1) 53809 goto war02; 53810 53811 if (kins2 == 1 || *jbound != 0) goto war03; 53812 53813 goto war05; 53814 53815 /* Line outside */ 53816 53817 war00: 53818 *jstat = 0; 53819 goto out; 53820 53821 /* Line inside */ 53822 53823 war01: 53824 *jstat = 1; 53825 goto out; 53826 53827 /* epar1 inside epar2 outside */ 53828 war02: 53829 *jstat = 2; 53830 goto out; 53831 53832 /* epar2 inside epar1 outside */ 53833 war03: 53834 *jstat = 3; 53835 goto out; 53836 53837 /* epar1 on boundary, epar2 outside */ 53838 war04: 53839 *jstat = 4; 53840 goto out; 53841 53842 /* Special error */ 53843 war05: 53844 *jstat = 5; 53845 goto out; 53846 53847 out: 53848 return; 53849 } 53850 53851 //=========================================================================== 53852 void s9clipimp(double epar1[],double epar2[],SISLSurf *psurf1,double eimpli[], 53853 int ideg,double euval[],double evval[],double aepsge, 53854 double gpnt1[],double gpar1[],int *jstat) 53855 //=========================================================================== 53856 { 53857 int kpos=0; /* Position of error */ 53858 int klfu=0; /* Variable used as pointer in knot vector */ 53859 int klfv=0; /* Variable used as pointer in knot vector */ 53860 int kder=2; /* Number of derivatives to be calculated */ 53861 int kstat; /* Local status variable */ 53862 int kdir; /* Parameter direction of tpar */ 53863 int kcross; /* Control variable in while loop */ 53864 int knbit; /* Number of iterations */ 53865 int krem; /* Remember status */ 53866 int kbound; /* Numbering of boundary */ 53867 int ksize; /* Number of doubles for storage of derivateves 53868 and normal vector */ 53869 int ksizem3; /* ksize - 3 */ 53870 double tpar; /* Constant parameter value */ 53871 double spnt1[33]; /* Coordinates of point */ 53872 double spar1[2],spar2[2]; /* Local parameter values */ 53873 double spar3[2]; /* Local parameter values */ 53874 53875 53876 53877 /* If ideg=1,2 or 1001 then only derivatives up to second order 53878 are calculated, then 18 doubles for derivatives and 3 for the 53879 normal vector are to be used for calculation of points in the 53880 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 53881 derivatives up to the third are to be calculated, 53882 thus 30 +3 a total of 33 doubles are to be calculated */ 53883 53884 if (ideg==1003 || ideg==1004 || ideg==1005) 53885 { 53886 kder = 3; 53887 ksize = 33; 53888 } 53889 else 53890 { 53891 ksize = 21; 53892 kder =2; 53893 } 53894 ksizem3 = ksize -3; 53895 53896 53897 /* Make local copy of parameters */ 53898 53899 memcopy(spar1,epar1,2,DOUBLE); 53900 memcopy(spar2,epar2,2,DOUBLE); 53901 53902 kcross = 1; 53903 knbit = 0; 53904 53905 while(kcross && knbit<4) 53906 { 53907 53908 /* Find intersection between boundary of parameter area and patch */ 53909 53910 s1305(spar1,spar2,euval,evval,&kbound,spar3,&kstat); 53911 if (kstat<0) goto error; 53912 53913 /* Remember status so that the line can be updated properly */ 53914 krem = kstat; 53915 53916 if (kstat<2 || kbound == 0) 53917 { 53918 /* No intersection */ 53919 kcross = 0; 53920 } 53921 else 53922 { 53923 53924 /* Calculate start point */ 53925 53926 s1421(psurf1,kder,spar3,&klfu,&klfv,spnt1,spnt1+ksizem3,&kstat); 53927 if (kstat<0) goto error; 53928 53929 if (kbound==1) 53930 { 53931 kdir = 1; 53932 tpar = euval[0]; 53933 } 53934 else if (kbound==2) 53935 { 53936 kdir = 2; 53937 tpar = evval[1]; 53938 } 53939 else if (kbound==3) 53940 { 53941 kdir = 1; 53942 tpar = euval[1]; 53943 } 53944 else if (kbound==4) 53945 { 53946 kdir = 2; 53947 tpar = evval[0]; 53948 } 53949 53950 53951 /* Iterate to boundary intersection */ 53952 53953 s9boundimp(spnt1,gpar1,psurf1,eimpli,ideg,tpar,kdir,aepsge, 53954 gpnt1,gpar1,&kstat); 53955 if (kstat<0) goto error; 53956 if (kstat==2) goto war02; 53957 53958 /* Iteration converged, copy output if new loop necessary */ 53959 53960 53961 if (krem == 2) 53962 { 53963 /* spar1 was inside, update spar2 */ 53964 memcopy(spar2,gpar1,2,double); 53965 } 53966 else 53967 { 53968 /* spar2 was inside, update spar1 */ 53969 memcopy(spar1,gpar1,2,double); 53970 } 53971 53972 /* Update number of iterations */ 53973 53974 knbit++; 53975 } 53976 } 53977 53978 53979 53980 /* Problem solved if kcross==0. In this case we might have two cases: 53981 - iteration not used: Then knbit=0 53982 - iteration used : Then knbit>0 53983 53984 if kcross==1, then we have stopped on the condition knbit>3, and we 53985 have no sucess. */ 53986 53987 if (kcross==0 && knbit ==0) 53988 { 53989 /* Iteration not used because boundary not crossed */ 53990 *jstat = 0; 53991 } 53992 else if (kcross==0 && knbit > 0) 53993 { 53994 /* Boundary crossed, point found, more than one intersection point 53995 is possible, check which to return */ 53996 53997 if (spar1[0] == epar1[0] && spar1[1] == epar1[1]) 53998 { 53999 memcopy(gpar1,spar2,2,double); 54000 } 54001 else 54002 { 54003 memcopy(gpar1,spar1,2,double); 54004 54005 /* Calculate crossing point, only necessary when we step into 54006 the patch since we already could have stepped out and this 54007 point is recorded in gpnt1 */ 54008 54009 s1421(psurf1,kder,gpar1,&klfu,&klfv,gpnt1,gpnt1+ksizem3,&kstat); 54010 if (kstat<0) goto error; 54011 } 54012 54013 *jstat = 1; 54014 } 54015 else 54016 { 54017 /* To many tries */ 54018 goto war02; 54019 } 54020 goto out; 54021 54022 /* Iteration without sucess */ 54023 54024 war02: *jstat = 2; 54025 goto out; 54026 54027 /* Error in lower level routine. */ 54028 54029 error : *jstat = kstat; 54030 s6err("s9clipimp",*jstat,kpos); 54031 goto out; 54032 54033 out: 54034 return; 54035 54036 } 54037 54038 //=========================================================================== 54039 void s1437(SISLSurf *ps1,double apar,SISLCurve **rcurve,int *jstat) 54040 //=========================================================================== 54041 { 54042 int kstat = 0; /* Local status variable. */ 54043 int kpos = 0; /* Position of error. */ 54044 int kind = 0; /* Kind of curve 54045 = 1 : Polynomial B-spline curve. 54046 = 2 : Rational B-spline curve. 54047 = 3 : Polynomial Bezier curve. 54048 = 4 : Rational Bezier curve. */ 54049 int kdim; /* Dimension of the space in which the surface lies.*/ 54050 int kder = 0; /* Number of derivatives of curve to evaluate. */ 54051 int kleft = 0; /* Parameter used in evalutation of curve. */ 54052 double *ecoef = SISL_NULL; /* Pointer to vertices */ 54053 double *scoef = SISL_NULL; /* Vertices of surface with changed parameter 54054 directions. */ 54055 double *scurve = SISL_NULL; /* Vertices of constant parameter curve. */ 54056 SISLCurve *qc = SISL_NULL; /* Intermediate curve. */ 54057 54058 /* Get dimension of space. */ 54059 54060 kdim = ps1 -> idim; 54061 kind = ps1->ikind; 54062 54063 /* Prepare for rational description. */ 54064 54065 if(ps1->ikind == 2 || ps1->ikind == 4) 54066 { 54067 ecoef = ps1->rcoef; 54068 kdim = kdim+1; 54069 } 54070 else 54071 { 54072 ecoef = ps1->ecoef; 54073 } 54074 54075 54076 /* Allocate space for coefficients of constant parameter curve 54077 and of surface with changed parameter direction. */ 54078 54079 if ((scurve = newarray(kdim*ps1->in2,double)) == SISL_NULL) goto err101; 54080 if ((scoef = newarray(kdim*ps1->in1*ps1->in2,double)) == SISL_NULL) goto err101; 54081 54082 /* Change parameter directions of surface. */ 54083 54084 s6chpar(ecoef,ps1->in1,ps1->in2,kdim,scoef); 54085 54086 /* Create curve to evaluate. */ 54087 54088 qc = newCurve(ps1->in1,ps1->ik1,ps1->et1,scoef,1,kdim*ps1->in2,0); 54089 if (qc == SISL_NULL) goto err101; 54090 54091 /* Evaluate this curve in given parameter value. */ 54092 54093 s1221(qc,kder,apar,&kleft,scurve,&kstat); 54094 if (kstat < 0) goto error; 54095 54096 /* Create constant parameter curve. */ 54097 54098 *rcurve = newCurve(ps1->in2,ps1->ik2,ps1->et2,scurve,kind,ps1->idim,1); 54099 if (*rcurve == SISL_NULL) goto err101; 54100 54101 /* Set periodicity flag. */ 54102 54103 (*rcurve)->cuopen = ps1->cuopen_2; 54104 54105 /* Curve picked. */ 54106 54107 *jstat = 0; 54108 goto out; 54109 54110 /* Error in space allocation. */ 54111 54112 err101: *jstat = -101; 54113 s6err("s1437",*jstat,kpos); 54114 goto out; 54115 54116 /* Error in lower level routine. */ 54117 54118 error : *jstat = kstat; 54119 s6err("s1437",*jstat,kpos); 54120 goto out; 54121 54122 out: 54123 54124 /* Free space occupied by local arrays. */ 54125 54126 if (scoef != SISL_NULL) freearray(scoef); 54127 if (scurve != SISL_NULL) freearray(scurve); 54128 if (qc != SISL_NULL) freeCurve(qc); 54129 54130 return; 54131 } 54132 54133 //=========================================================================== 54134 void s1712 (SISLCurve * pc, double abeg, double aend, SISLCurve ** rcnew, int *jstat) 54135 //=========================================================================== 54136 { 54137 int kstat; /* Local status variable. */ 54138 int kpos = 0; /* Position of error. */ 54139 double tbeg, tend; /* The less and greater point. */ 54140 SISLCurve *q1 = SISL_NULL; /* Pointer to new curve-object. */ 54141 SISLCurve *q2 = SISL_NULL; /* Pointer to new curve-object. */ 54142 SISLCurve *q3 = SISL_NULL; /* Pointer to new curve-object. */ 54143 int kturn = 0; 54144 54145 /* Check that we have a curve to pick a part of. */ 54146 54147 if (!pc) 54148 goto err150; 54149 54150 /* Check that the intersection points are interior points. */ 54151 54152 if ((abeg < pc->et[0] && DNEQUAL(abeg,pc->et[0])) || 54153 (abeg > pc->et[pc->in+pc->ik-1] && DNEQUAL(abeg,pc->et[pc->in+pc->ik-1]))) 54154 goto err151; 54155 if ((aend < pc->et[0] && DNEQUAL(aend,pc->et[0])) || 54156 (aend > pc->et[pc->in+pc->ik-1] && DNEQUAL(aend,pc->et[pc->in+pc->ik-1]))) 54157 goto err151; 54158 54159 /* Check that abeg is not like aend. */ 54160 54161 if (DEQUAL(abeg,aend)) 54162 goto err151; 54163 54164 if (pc->cuopen == SISL_CRV_PERIODIC) 54165 { 54166 double delta = pc->et[pc->in] - pc->et[pc->ik - 1]; 54167 54168 if (abeg > aend) kturn = 1; 54169 54170 if (abeg < pc->et[pc->ik - 1] && DNEQUAL(abeg, pc->et[pc->ik - 1])) 54171 abeg += delta; 54172 if (abeg > pc->et[pc->in] || DEQUAL(abeg, pc->et[pc->in])) 54173 abeg -= delta; 54174 54175 if (aend < pc->et[pc->ik - 1] && DNEQUAL(aend, pc->et[pc->ik - 1])) 54176 aend += delta; 54177 if (aend > pc->et[pc->in] && DNEQUAL(aend, pc->et[pc->in])) 54178 aend -= delta; 54179 54180 if ((abeg > aend && !kturn) || (abeg < aend && kturn)) 54181 kturn = 1; 54182 else 54183 kturn = 0; 54184 } 54185 54186 /* Find the smaller and greater of the intersection points. */ 54187 54188 if (abeg < aend) 54189 { 54190 tbeg = abeg; 54191 tend = aend; 54192 } 54193 else 54194 { 54195 tbeg = aend; 54196 tend = abeg; 54197 } 54198 54199 /* Divide into two at each point. The new curve is 54200 the middelmost curve.*/ 54201 54202 /* We start with dividing at the first point, and free the curv at 54203 left. */ 54204 54205 s1710 (pc, tbeg, &q1, &q2, &kstat); 54206 if (kstat < 0) 54207 goto err153; 54208 /* UJK, periodicity */ 54209 if (kstat && q1 && !q2) 54210 { 54211 q2 = q1; 54212 q1 = SISL_NULL; 54213 } 54214 else if (q1) 54215 { 54216 freeCurve (q1); 54217 q1 = SISL_NULL; 54218 } 54219 54220 /* Then we divide at the last point. The curve to left is the new curve.*/ 54221 54222 s1710 (q2, tend, &q1, &q3, &kstat); 54223 if (kstat < 0) 54224 goto err153; 54225 /* BOH, periodicity */ 54226 if (kstat && !q1 && q3) 54227 { 54228 q1 = q3; 54229 q3 = SISL_NULL; 54230 } 54231 54232 /* The curve is turned if nessesary. */ 54233 54234 if ((abeg > aend && !kturn) || (abeg < aend && kturn)) 54235 s1706 (q1); 54236 54237 /* Updating output. */ 54238 54239 *rcnew = q1; 54240 *jstat = 0; 54241 goto out; 54242 54243 54244 /* Error. Error at low level function. */ 54245 54246 err153: 54247 *jstat = kstat; 54248 goto outfree; 54249 54250 54251 /* Error. No curve to pick a part of. */ 54252 54253 err150: 54254 *jstat = -150; 54255 s6err ("s1712", *jstat, kpos); 54256 goto out; 54257 54258 54259 /* Error. No part, abeg and aend has illegal values. */ 54260 54261 err151: 54262 *jstat = -151; 54263 s6err ("s1712", *jstat, kpos); 54264 goto out; 54265 54266 54267 /* Error in output. */ 54268 54269 outfree: 54270 if (q1) 54271 freeCurve (q1); 54272 54273 54274 /* Free local used memory. */ 54275 54276 out: 54277 if (q2) 54278 freeCurve (q2); 54279 if (q3) 54280 freeCurve (q3); 54281 return; 54282 } 54283 54284 //=========================================================================== 54285 void s1436(SISLSurf *ps1,double apar,SISLCurve **rcurve,int *jstat) 54286 //=========================================================================== 54287 { 54288 int kstat = 0; /* Local status variable. */ 54289 int kpos = 0; /* Position of error. */ 54290 int kder = 0; /* Number of derivatives of curve to evalutate. */ 54291 int kleft = 0; /* Parameter used in evaluation of curve. */ 54292 int kind = 0; /* Kind of curve 54293 = 1 : Polynomial B-spline curve. 54294 = 2 : Rational B-spline curve. 54295 = 3 : Polynomial Bezier curve. 54296 = 4 : Rational Bezier curve. */ 54297 int kdim; 54298 double *scoef; /* Pointer to vertices. */ 54299 double *scurve = SISL_NULL; /* Vertices of constant parameter curve. */ 54300 SISLCurve *qc = SISL_NULL; /* Pointer to intermediate curve. */ 54301 54302 /* Prepare for rational description. */ 54303 54304 kdim = ps1->idim; 54305 kind = ps1->ikind; 54306 if(ps1->ikind == 2 || ps1->ikind == 4) 54307 { 54308 scoef = ps1->rcoef; 54309 kdim = kdim+1; 54310 } 54311 else 54312 { 54313 scoef = ps1->ecoef; 54314 } 54315 54316 /* Create the curve describing the surface as a curve. */ 54317 54318 if ((qc = newCurve(ps1->in2,ps1->ik2,ps1->et2,scoef,1, 54319 ps1->in1*kdim,0)) == SISL_NULL) goto err101; 54320 54321 /* Allocate space for value of curve. */ 54322 54323 if ((scurve = newarray(ps1->in1*kdim,double)) == SISL_NULL) goto err101; 54324 54325 /* Evaluate this curve at given parameter value. */ 54326 54327 s1221(qc,kder,apar,&kleft,scurve,&kstat); 54328 if (kstat < 0) goto error; 54329 54330 /* Create constant parameter curve. */ 54331 54332 *rcurve = newCurve(ps1->in1,ps1->ik1,ps1->et1,scurve,kind,ps1->idim,1); 54333 if (*rcurve == SISL_NULL) goto err101; 54334 54335 /* Set periodicity flag. */ 54336 54337 (*rcurve)->cuopen = ps1->cuopen_1; 54338 54339 /* Curve picked. */ 54340 54341 *jstat = 0; 54342 goto out; 54343 54344 /* Error in space allocation. */ 54345 54346 err101: *jstat = -101; 54347 s6err("s1436",*jstat,kpos); 54348 goto out; 54349 54350 /* Error in lower level routine. */ 54351 54352 error : *jstat = kstat; 54353 s6err("s1436",*jstat,kpos); 54354 goto out; 54355 54356 out: 54357 54358 /* Free space occupied by local arrays. */ 54359 54360 if (scurve != SISL_NULL) freearray(scurve); 54361 if (qc != SISL_NULL) freeCurve(qc); 54362 54363 return; 54364 } 54365 54366 //=========================================================================== 54367 double s1309(double epnt[],double edir[],double eimpli[],int ideg,int *jstat) 54368 //=========================================================================== 54369 { 54370 double sdir[3]; /* Normilized direction vector */ 54371 double tb1,ta11,ta12; /* Dummy variables */ 54372 double tsum,t1,t2,tdum1;/* Dummy variables */ 54373 double tcurdst=0.0; /* The distance */ 54374 double sq[4]; /* Array used for temporary results */ 54375 int ksize; /* Number of doubles for storage of derivatives 54376 and normal vector */ 54377 int ksizem3; /* ksize - 3 */ 54378 int kstat; /* Local status variable */ 54379 int kdim=3; /* Dimesnon of 3-D space */ 54380 int ki,kj,kl,kp; /* Control variables in loop */ 54381 int kpos=1; /* Position of error */ 54382 54383 54384 54385 /* If ideg=1,2 or 1001 then only derivatives up to second order 54386 are calculated, then 18 doubles for derivatives and 3 for the 54387 normal vector are to be used for calculation of points in the 54388 spline surface. For ideg=1003,1004,1005 we have a silhouette curve and 54389 derivatives up to the third are to be calculated, 54390 thus 30 +3 a total of 33 doubles are to be calculated */ 54391 54392 if (ideg==1003 || ideg==1004 || ideg==1005) 54393 { 54394 ksize = 33; 54395 } 54396 else 54397 { 54398 ksize = 21; 54399 } 54400 54401 ksizem3 = ksize -3; 54402 (void)s6norm(edir,kdim,sdir,&kstat); 54403 if (kstat < 0) goto error; 54404 54405 if (ideg==1) 54406 { 54407 /* Put parametric representation of projection line into 54408 implicit equation of plane */ 54409 tb1 = s6scpr(eimpli,epnt,kdim); 54410 ta11 = s6scpr(eimpli,sdir,kdim); 54411 if( ta11 == (double)0.0) goto war02; 54412 tcurdst = -(eimpli[3]+tb1)/ta11; 54413 } 54414 else if (ideg==2) 54415 { 54416 54417 /* Find distance from the new point to the implicit surface, by 54418 intersecting the straight line throught the point and with 54419 sdir as normalized direction vector, normalized version of 3 54420 first coordinates of sq the implicit surface and P0 = (P,1). 54421 54422 This problem can be written: 54423 54424 T T 2 T 54425 P0 A P0 + 2 t P0 A sdir + t (sdir,0) A (sdir,0) = 0 54426 54427 T 54428 We have to calulate calculate tb1=P0 A P and qs=P0 A, thus: 54429 T 2 T 54430 tb1 + 2 t sq sdir + t (sdir,0) A (sdir,0) = 0 54431 54432 Thus the first step is to calculate qs = A (P,1) 54433 */ 54434 for (ki=0;ki<4;ki++) 54435 { 54436 tsum = eimpli[12+ki]; 54437 for (kj=0,kl=ki ; kj<3 ; kj++,kl+=4) 54438 { 54439 tsum +=(eimpli[kl]*epnt[kj]); 54440 } 54441 sq[ki] = tsum; 54442 } 54443 54444 tb1 = s6scpr(epnt,sq,kdim) + sq[3]; 54445 54446 ta11 = (double)2.0*s6scpr(sq,sdir,kdim); 54447 54448 ta12 = (double)0.0; 54449 for (ki=0,kl=0;ki<3;ki++,kl+=4) 54450 { 54451 kp = kl; 54452 for (kj=0;kj<3;kj++,kp++) 54453 { 54454 ta12 += sdir[ki]*eimpli[kp]*sdir[kj]; 54455 } 54456 } 54457 54458 /* Now our equation system is: 54459 2 54460 ta12 t + ta11 t + tb1 = 0 54461 54462 we want the root with the smallest absolute value: 54463 2 54464 t = (-ta11 +/- sqrt(ta11 -4ta12 tb1))/(2ta12) 54465 */ 54466 if (DNEQUAL(ta12,(double)0.0)) 54467 { 54468 tdum1 = ta11*ta11 - (double)4.0*ta12*tb1; 54469 if (tdum1 < DZERO) goto war02; 54470 tdum1 = sqrt(tdum1); 54471 t1 = (-ta11 + tdum1)/((double)2.0*ta12); 54472 t2 = (-ta11 - tdum1)/((double)2.0*ta12); 54473 if (fabs(t1)<fabs(t2)) 54474 { 54475 tcurdst = t1; 54476 } 54477 else 54478 { 54479 tcurdst = t2; 54480 } 54481 } 54482 else if(DNEQUAL(ta11,(double)0.0)) 54483 { 54484 tcurdst = tb1/ta11; 54485 } 54486 else 54487 { 54488 /* Unsolvable system */ 54489 goto war02; 54490 } 54491 } 54492 else if (ideg==1001) 54493 { 54494 /* Torus surface */ 54495 54496 double *scentr; /* The center of the torus */ 54497 double *snorm; /* The normal of the torus symmetry plane */ 54498 double tbigr; /* The big radius of the torus */ 54499 double tsmalr; /* The small radius of the torus */ 54500 double sdum1[3]; /* Temporary storage for point */ 54501 double sdum2[3]; /* Temporary storage for point */ 54502 double tproj; /* Projection of vector onto snorm */ 54503 54504 54505 scentr = eimpli; 54506 snorm = eimpli+3; 54507 tbigr = *(eimpli+6); 54508 tsmalr = *(eimpli+7); 54509 54510 /* Find projection of vector from torus center on to torus axis */ 54511 s6diff(epnt,scentr,kdim,sdum1); 54512 tproj = s6scpr(sdum1,snorm,kdim); 54513 54514 /* Project vector from torus center to epnt onto torus plane */ 54515 for (ki=0;ki<kdim;ki++) 54516 sdum2[ki] = sdum1[ki] - tproj*snorm[ki]; 54517 (void)s6norm(sdum2,kdim,sdum2,&kstat); 54518 if (kstat<0) goto error; 54519 54520 /* Find vector from torus circle to epnt */ 54521 for (ki=0;ki<kdim;ki++) 54522 sdum1[ki] = sdum1[ki] - tbigr*sdum2[ki]; 54523 54524 /* Find length of this vector and compare with tsmalr */ 54525 54526 tcurdst = fabs(s6length(sdum1,kdim,&kstat)-tsmalr); 54527 if (kstat<0) goto error; 54528 } 54529 else if (ideg==1003) 54530 { 54531 /* Silhouette line/curve */ 54532 54533 double sdum1[3]; /* Temporary storage for point */ 54534 54535 (void)s6norm(epnt+ksizem3,kdim,sdum1,&kstat); 54536 if (kstat<0) goto error; 54537 54538 /* eimpli[0,1,2] is assumed to, be normalized */ 54539 54540 t1 = s6scpr(sdum1,eimpli,kdim); 54541 54542 /* t1 now contains the cosine of the angle between the view direction 54543 and the normal vector. This is Equal to sin of PI/2 minus the angle 54544 between the vectors, thus the actual angle can be calulated */ 54545 54546 tcurdst = asin(t1); 54547 tcurdst = fabs(tcurdst); 54548 } 54549 54550 else if (ideg==1004) 54551 { 54552 /* Perspective silhouette line/curve */ 54553 54554 double sdum1[3],sdum2[3]; /* Temporary storage for point */ 54555 54556 s6diff(epnt,eimpli,kdim,sdum1); 54557 (void)s6norm(sdum1,kdim,sdum2,&kstat); 54558 /* OK if sdum1 is zero -- tcurdst will be zero as well */ 54559 (void)s6norm(epnt+ksizem3,kdim,sdum1,&kstat); 54560 54561 54562 t1 = s6scpr(sdum1,sdum2,kdim); 54563 54564 /* t1 now contains the cosine of the angle between the direction of the 54565 point epnt relative to the eyepoint E (in eimpli) 54566 and the normal vector. This is Equal to sin of PI/2 minus the angle 54567 between the vectors, thus the actual angle can be calulated */ 54568 54569 tcurdst = asin(t1); 54570 tcurdst = fabs(tcurdst); 54571 } 54572 54573 else if (ideg==1005) 54574 { 54575 /* Circular silhouette line/curve */ 54576 54577 double sdum1[3],sdum2[3]; /* Temporary storage for point */ 54578 double *bvec=eimpli+3; 54579 54580 s6diff(epnt,eimpli,kdim,sdum1); 54581 s6crss(epnt+ksizem3,sdum1,sdum2); 54582 (void)s6norm(sdum2,kdim,sdum1,&kstat); 54583 /* OK if sdum2 is zero -- tcurdst will be zero as well */ 54584 54585 /* bvec = eimpli[3,4,5] is assumed to, be normalized */ 54586 54587 t1 = s6scpr(sdum1,bvec,kdim); 54588 54589 /* t1 now contains the cosine of the angle between 54590 (the cross product of the normal vector and the direction of the 54591 point epnt relative to the point Q (in eimpli)) 54592 and the direction vector B. This is Equal to sin of PI/2 minus the angle 54593 between the vectors, thus the actual angle can be calulated */ 54594 54595 tcurdst = asin(t1); 54596 tcurdst = fabs(tcurdst); 54597 } 54598 54599 *jstat = 0; 54600 goto out; 54601 54602 /* Projection not possible */ 54603 war02: *jstat = 2; 54604 goto out; 54605 54606 /* Error in lower level routine. */ 54607 54608 error : *jstat = kstat; 54609 s6err("s1309",*jstat,kpos); 54610 goto out; 54611 54612 out: 54613 return(tcurdst); 54614 } 54615 54616 //=========================================================================== 54617 void s1605(SISLCurve *pc,double aepsge,double **gpoint,int *jnbpnt,int *jstat) 54618 //=========================================================================== 54619 { 54620 int kstat = 0; /* Status variable. */ 54621 int kpos = 0; /* Position of error reported. */ 54622 int ki,kj,kk,kh,kr,kl; /* Counters. */ 54623 int kikr; /* Order of current derivative curve. */ 54624 int kih; /* Current location in sdd2. */ 54625 int kihn; /* Next location in sdd2. */ 54626 int kjh; /* Index in sdd2. */ 54627 int kstop; /* Number of divided differences to compute. */ 54628 int kdim = pc->idim; /* Dimension of space in which the curve lies. */ 54629 int kncoef = pc->in; /* Number of vertices of curve. */ 54630 int korder = pc->ik; /* Order of curve. */ 54631 int kordnew = korder-2; /* Order of derivative curve of which 54632 to find an upper bound. */ 54633 int knmbel = 100; /* Number of elements with which the output 54634 array is to be increased. */ 54635 int kmaxpar = knmbel; /* Length of output parameter array. */ 54636 int kpar = 0; /* Number of parameter values computed. */ 54637 int kant; /* Number of sampling points at a knot interval. */ 54638 int left = 0; /* Help index to evaluator. */ 54639 double tant; /* Number of sampling points at a knot interval. */ 54640 double tfac; /* Factor used in taking divided differences. */ 54641 double ta; /* Start value of parameter interval. */ 54642 double tb; /* End value of parameter interval. */ 54643 double th; /* Distance between output parameter values. */ 54644 double *st; /* Pointer to knot vector of curve. */ 54645 double *par = SISL_NULL; /* Array used to store parameter values. */ 54646 double *sh = SISL_NULL; /* Work array. */ 54647 double *sh1 = SISL_NULL; /* Work array. */ 54648 double *sdd = SISL_NULL; /* Work array used to compute divided differences. */ 54649 double *sdd2 = SISL_NULL; /* Array used to store final divided differences. */ 54650 double *smaxd = SISL_NULL; /* Array used to store maximum divided differences.*/ 54651 54652 /* Test input. */ 54653 54654 if (korder < 1) goto err110; 54655 if (kncoef < korder) goto err111; 54656 if (kdim < 1) goto err102; 54657 54658 if (korder == 1) 54659 { 54660 kpar = kncoef; 54661 if ((*gpoint = newarray(kpar*kdim,DOUBLE)) == SISL_NULL) goto err101; 54662 memcopy(gpoint,pc->ecoef,kpar*kdim,DOUBLE); 54663 *jnbpnt = kpar; 54664 *jstat = 0; 54665 goto out; 54666 } 54667 54668 54669 /* Set local pointer to knot vector of curve. */ 54670 54671 st = pc->et; 54672 54673 /* Allocate some scratch for output array. */ 54674 54675 if ((par = newarray(knmbel,DOUBLE)) == SISL_NULL) goto err101; 54676 54677 /* Allocate scratch for internal arrays. */ 54678 54679 if ((sdd = new0array((kordnew+6)*kdim,DOUBLE)) == SISL_NULL) goto err101; 54680 sdd2 = sdd+3*kdim; 54681 smaxd = sdd2+kordnew*kdim; 54682 sh = smaxd+kdim; 54683 sh1 = sh+kdim; 54684 54685 /* Main loop to determine the interpolation points in each knot interval 54686 by computing 2. order differences and taking the maximum of the 54687 appropriate kordnew 2. order differences on each knot interval. The 54688 number of uniform interplation points in the knot interval can then 54689 by estimated using the bound described in METHOD. 54690 In the following the index ki will point at the next coefficient to be 54691 included in the computation of the 2. order derivatives. 54692 kpar points to the location in the array par where the parameter value 54693 of the next interpolation point is to be stored. 54694 kih points to the location in sdd2 where the next 2. order difference 54695 is to be stored. */ 54696 54697 kpar=0; 54698 tb = st[korder-1]; 54699 54700 for (kih=0, ki=0; ki<kncoef; ki=kj) 54701 { 54702 /* Compute the index of the first knot greater than tb. */ 54703 54704 for (kj=MAX(korder-1,ki)+1; st[kj]==tb; kj++); 54705 ta = tb; 54706 tb = st[kj]; 54707 54708 /* Check if the multiplisity of the knot is greater than 54709 korder-2. */ 54710 54711 if (kj-ki >= korder-1) 54712 { 54713 if (kpar+1 > kmaxpar) 54714 if ((par = increasearray(par,(kmaxpar+=knmbel),DOUBLE)) 54715 == SISL_NULL) goto err101; 54716 par[kpar] = ta; 54717 kpar++; 54718 } 54719 54720 /* If the 2. order differences may be different from zero, 54721 Compute them. */ 54722 54723 for (kk=ki; korder>2 && kk<kj; kk++) 54724 { 54725 /* Pick the next coefficient. */ 54726 54727 memcopy(sh,pc->ecoef+kk*kdim,kdim,DOUBLE); 54728 54729 /* Compute the 1, 2 difference at kk. */ 54730 54731 kikr = korder - 1; 54732 kstop = MIN(2,korder-kj+kk); 54733 for (kr=0; kr<kstop; kr++) 54734 { 54735 tfac = (double)kikr/(st[kk+kikr] - ta); 54736 kikr--; 54737 for (kh=0; kh<kdim; kh++) 54738 sh1[kh] = (sh[kh] - sdd[kr*kdim+kh])*tfac; 54739 memcopy(sdd+kr*kdim,sh,kdim,DOUBLE); 54740 memcopy(sh,sh1,kdim,DOUBLE); 54741 } 54742 memcopy(sdd+kr*kdim,sh,kdim,DOUBLE); 54743 54744 /* Compute the maximum of the 2. order difference. The 54745 kordnew previous 2. order differences are stored in 54746 sdd2 and the current one (sdd+3*kdim) is to overwrite 54747 sdd2+kih*kdim. The fact that only one new element enters 54748 sdd2 at a time can be taken advantage of in computing 54749 the maximum difference. */ 54750 54751 if (kstop == 2) 54752 { 54753 for (kihn=(kih+1)%kordnew, kh=0; kh<kdim; kh++) 54754 { 54755 sh[kh] = fabs(sh[kh]); 54756 if (sdd2[kih*kdim+kh] < smaxd[kh]) 54757 smaxd[kh] = MAX(smaxd[kh],sh[kh]); 54758 else if (sh[kh] >= smaxd[kh]) 54759 smaxd[kh] = sh[kh]; 54760 else 54761 { 54762 for (kjh=kihn, smaxd[kh]=sh[kh], kl=0; 54763 kl<kordnew-1; kl++, kjh=(kjh+1)%kordnew) 54764 smaxd[kh] = MAX(smaxd[kh],sdd2[kjh*kdim+kh]); 54765 } 54766 sdd2[kih*kdim+kh] = sh[kh]; 54767 } 54768 kih = kihn; 54769 } 54770 } 54771 54772 /* Compute the number of interpolation points. */ 54773 54774 for (kant=0, kh=0; kh<kdim; kh++) 54775 { 54776 tant = (tb-ta)*sqrt(smaxd[kh]/((double)8.0*aepsge)); 54777 kant = MAX(MAX(kant,(int)tant),1); 54778 } 54779 54780 /* Make sure that par is great enough. */ 54781 54782 if (kpar+kant >= kmaxpar) 54783 if ((par = increasearray(par,(kmaxpar+=MAX(kant,knmbel)),DOUBLE)) 54784 == SISL_NULL) goto err101; 54785 54786 /* Compute the parameter values of the interpolation points. */ 54787 54788 for (th=(tb-ta)/(double)(kant+1), kk=0; kk<kant; kpar++,kk++) 54789 par[kpar] = ta + (double)(kk+1)*th; 54790 par[kpar] = tb; 54791 kpar++; 54792 } 54793 54794 /* Make the points. */ 54795 54796 if ((*gpoint = newarray(kpar*kdim,DOUBLE)) == SISL_NULL) goto err101; 54797 54798 for (kh=kk=0; kk<kpar; kk++,kh+=kdim) 54799 { 54800 s1221(pc,0,par[kk],&left,*gpoint+kh,&kstat); 54801 if (kstat < 0) goto err101; 54802 } 54803 54804 /* Task performed. */ 54805 54806 *jnbpnt = kpar; 54807 *jstat = 0; 54808 goto out; 54809 54810 54811 /* Error in scratch allocation. */ 54812 54813 err101 : 54814 *jstat = -101; 54815 s6err("s1605",*jstat,kpos); 54816 goto out; 54817 54818 /* Error in input. Dimension less than one. */ 54819 54820 err102 : 54821 *jstat = -102; 54822 s6err("s1605",*jstat,kpos); 54823 goto out; 54824 54825 /* Error in input. Order less than one. */ 54826 54827 err110 : 54828 *jstat = -110; 54829 s6err("s1605",*jstat,kpos); 54830 goto out; 54831 54832 /* Error in input. Number of coefficients less than order. */ 54833 54834 err111 : 54835 *jstat = -111; 54836 s6err("s1605",*jstat,kpos); 54837 goto out; 54838 54839 out : 54840 /* Free scratch occupied by local arrays. */ 54841 54842 if (sdd != SISL_NULL) freearray(sdd); 54843 if (par != SISL_NULL) freearray(par); 54844 } 54845 54846 //=========================================================================== 54847 void make_cv_kreg (SISLCurve * pc, SISLCurve ** rcnew, int *jstat) 54848 //=========================================================================== 54849 { 54850 int kn=pc->in; /* Number of vertices in 1. par. dir. */ 54851 int kk=pc->ik; /* Order in 1. par. dir. */ 54852 /* --------------------------------------------------------- */ 54853 /* Pick part of curve */ 54854 s1712 (pc, pc->et[kk-1], pc->et[kn], rcnew, jstat); 54855 if (*jstat < 0) goto error; 54856 54857 if (pc->cuopen == SISL_CRV_PERIODIC ) 54858 (*rcnew)->cuopen = SISL_CRV_CLOSED; 54859 54860 goto out; 54861 54862 /* Error in lower level routine */ 54863 error: 54864 s6err ("make_cv_kreg", *jstat, 0); 54865 54866 out:; 54867 54868 } 54869 54870 //=========================================================================== 54871 SISLIntpt * hp_newIntpt (int ipar, double *epar, double adist, int itype, 54872 int ileft1, int iright1, int ileft2, int iright2, 54873 int size_1, int size_2, double egeom1[], double egeom2[]) 54874 //=========================================================================== 54875 { 54876 SISLIntpt *pnew; /* Local pointer to instance to create. */ 54877 int ki; /* Counter. */ 54878 54879 54880 /* Allocate space for instance of Intpt. */ 54881 54882 pnew = new0array (1, SISLIntpt); 54883 if (pnew == SISL_NULL) 54884 goto err101; 54885 54886 /* Initialize parameters concerning the size of arrays describing 54887 the intersection curves in which this points lie, and allocate 54888 scratch for the arrays. */ 54889 54890 pnew->no_of_curves_alloc = 4; 54891 pnew->no_of_curves = 0; 54892 54893 if ((pnew->pnext = newarray (pnew->no_of_curves_alloc, SISLIntpt *)) == SISL_NULL) 54894 goto err101; 54895 if ((pnew->curve_dir = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL) 54896 goto err101; 54897 if ((pnew->left_obj_1 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL) 54898 goto err101; 54899 if ((pnew->left_obj_2 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL) 54900 goto err101; 54901 if ((pnew->right_obj_1 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL) 54902 goto err101; 54903 if ((pnew->right_obj_2 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL) 54904 goto err101; 54905 54906 /* Initialize instance. First allocate space for parameter array. */ 54907 54908 pnew->epar = SISL_NULL; 54909 if (ipar > 0) 54910 { 54911 pnew->epar = newarray (ipar, DOUBLE); 54912 if (pnew->epar == SISL_NULL) 54913 goto err101; 54914 } 54915 54916 54917 /* Initialize the variables of the instance. */ 54918 54919 pnew->ipar = ipar; 54920 for (ki = 0; ki < ipar; ki++) 54921 pnew->epar[ki] = epar[ki]; 54922 pnew->adist = adist; 54923 pnew->pcurve = SISL_NULL; 54924 pnew->edge_1 = 0; 54925 pnew->edge_2 = 0; 54926 pnew->iinter = itype; 54927 pnew->marker = 0; 54928 pnew->evaluated = 0; 54929 54930 if (size_1 > 0) 54931 { 54932 pnew->geo_data_1 = newarray (size_1, DOUBLE); 54933 pnew->size_1 = size_1; 54934 memcopy (pnew->geo_data_1, egeom1, size_1, double); 54935 } 54936 else 54937 { 54938 pnew->geo_data_1 = SISL_NULL; 54939 pnew->size_1 = 0; 54940 } 54941 54942 if (size_2 > 0) 54943 { 54944 pnew->geo_data_2 = newarray (size_2, DOUBLE); 54945 pnew->size_2 = size_2; 54946 memcopy (pnew->geo_data_2, egeom2, size_2, double); 54947 } 54948 else 54949 { 54950 pnew->geo_data_2 = SISL_NULL; 54951 pnew->size_2 = 0; 54952 } 54953 54954 54955 *(pnew->left_obj_1) = ileft1; 54956 *(pnew->left_obj_2) = ileft2; 54957 *(pnew->right_obj_1) = iright1; 54958 *(pnew->right_obj_2) = iright2; 54959 54960 for (ki = 0; ki < pnew->no_of_curves_alloc; ki++) 54961 pnew->pnext[ki] = SISL_NULL; 54962 54963 /* for (ki=0; ki<6; ki++) pnew -> geo_aux[ki] = DZERO; */ 54964 54965 pnew->trim[0] = SISL_NULL; 54966 pnew->trim[1] = SISL_NULL; 54967 54968 /* Init the left/right evaluator to default value zero. */ 54969 pnew->iside_1 = 0; 54970 pnew->iside_2 = 0; 54971 54972 /* Task done. */ 54973 54974 goto out; 54975 54976 /* Error in space allocation. Return zero. */ 54977 54978 err101:pnew = SISL_NULL; 54979 goto out; 54980 54981 out:return (pnew); 54982 } 54983 54984 //=========================================================================== 54985 void sh6idnpt(SISLIntdat **pintdat,SISLIntpt **pintpt,int itest,int *jstat) 54986 //=========================================================================== 54987 { 54988 register int ki,kj; /* Counters. */ 54989 54990 /* We have to be sure that we have an intdat structure. */ 54991 54992 if ((*pintdat) == SISL_NULL) 54993 { 54994 if (((*pintdat) = newIntdat()) == SISL_NULL) goto err101; 54995 } 54996 54997 54998 /* Then we have to be sure that we do not have the intersection point 54999 before or an equal point. */ 55000 55001 for (ki=0; ki<(*pintdat)->ipoint; ki++) 55002 if ((*pintdat)->vpoint[ki] == (*pintpt)) 55003 { 55004 *jstat = 1; 55005 goto out; 55006 } 55007 else if (itest) 55008 { 55009 for (kj=0; kj<(*pintpt)->ipar; kj++) 55010 if (DNEQUAL((*pintpt)->epar[kj],(*pintdat)->vpoint[ki]->epar[kj])) 55011 break; 55012 55013 if (kj == (*pintpt)->ipar) 55014 { 55015 freeIntpt(*pintpt); 55016 (*pintpt) = (*pintdat)->vpoint[ki]; 55017 *jstat = 2; 55018 goto out; 55019 } 55020 } 55021 55022 55023 /* Then we have to be sure that the array vpoint is great enough. */ 55024 55025 if (ki == (*pintdat)->ipmax) 55026 { 55027 (*pintdat)->ipmax += 20; 55028 55029 if (((*pintdat)->vpoint = increasearray((*pintdat)->vpoint, 55030 (*pintdat)->ipmax,SISLIntpt *)) == SISL_NULL) 55031 goto err101; 55032 } 55033 55034 55035 /* Now we can insert the new point. */ 55036 55037 (*pintdat)->vpoint[ki] = (*pintpt); 55038 (*pintdat)->ipoint++; 55039 *jstat = 0; 55040 goto out; 55041 55042 55043 /* Error in space allocation. */ 55044 55045 err101: *jstat = -101; 55046 s6err("sh6idnpt",*jstat,0); 55047 goto out; 55048 55049 out: ; 55050 } 55051 55052 //=========================================================================== 55053 void sh1790(SISLObject *po1,SISLObject *po2,int itype, double aepsge,int *jstat) 55054 //=========================================================================== 55055 { 55056 int kstat = 0; /* Local status error. */ 55057 int kpos = 0; /* Position of error. */ 55058 int ktype = itype%10; /* Type of box to make. */ 55059 int kant; /* Number of sides in all boxes. */ 55060 int kdim1,kdim2; /* Dimension of space. */ 55061 int ki,kj=0; /* Counters. */ 55062 int kpttest=0; /* Indicates wether one object is a point and 55063 the geometry has dimension greater than 1. 55064 In that case the boundaries of the box is 55065 placed further out in the min- and max-arrays. */ 55066 int kshadow = 0; /* Indicates if there is a risk of a shadow areas */ 55067 int kbez = 0; /* Indicates if any object is a bezier object. */ 55068 double tdist; /* Distance between boxes. */ 55069 double teps1; /* To be used in 1D. */ 55070 double teps2; /* Two times aepsge if expanded box. */ 55071 double tepsge = aepsge; /* Tolerance to be used locally. In 1D 55072 tepsge=2*aepsge since the point is not 55073 expended. */ 55074 double t1,t2,t3,t4; /* Help variables. */ 55075 double t01,t02,t03,t04; /* Help variables. */ 55076 double *tmin1,*tmax1; /* Smallest and larges value of the vertices of 55077 first object in each box in all dimension. */ 55078 double *tmin2,*tmax2; /* Smallest and larges value of the vertices of 55079 second object in each box in all dimension.*/ 55080 55081 /* Set local tolerance. */ 55082 55083 teps2 = (ktype == 0) ? aepsge : (double)2.0*aepsge; 55084 55085 /* Check if one object is a point. */ 55086 55087 if (po1->iobj == SISLPOINT) kdim1 = po1->p1->idim; 55088 else if (po1->iobj == SISLCURVE) kdim1 = po1->c1->idim; 55089 else if (po1->iobj == SISLSURFACE) kdim1 = po1->s1->idim; 55090 55091 if (kdim1 == 1) 55092 { 55093 if (ktype != 0) teps2 = (double)3.0*aepsge; 55094 teps1 = (ktype == 0) ? aepsge : aepsge+aepsge; 55095 55096 if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT) 55097 tepsge += aepsge; 55098 } 55099 else 55100 { 55101 teps1 = DZERO; 55102 if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT) 55103 kpttest = 1; 55104 } 55105 55106 55107 /* Compute the box of the first object. */ 55108 55109 sh1992(po1,itype,tepsge,&kstat); 55110 if (kstat < 0) goto error; 55111 55112 /* VSK. 06.93. Adjust microbox tolerance in bezier case. */ 55113 55114 if (ktype != 0 && kstat == 1) kbez = 1; 55115 55116 /* Set pointers to box boundaries. */ 55117 55118 if (po1->iobj == SISLPOINT) 55119 { 55120 tmin1 = po1->p1->pbox->e2min[ktype]; 55121 tmax1 = po1->p1->pbox->e2max[ktype]; 55122 } 55123 else if (po1->iobj == SISLCURVE) 55124 { 55125 tmin1 = po1->c1->pbox->e2min[ktype]; 55126 tmax1 = po1->c1->pbox->e2max[ktype]; 55127 } 55128 else if (po1->iobj == SISLSURFACE) 55129 { 55130 tmin1 = po1->s1->pbox->e2min[ktype]; 55131 tmax1 = po1->s1->pbox->e2max[ktype]; 55132 } 55133 else goto err121; 55134 55135 /* Make requested box. */ 55136 55137 sh1992(po2,itype,tepsge,&kstat); 55138 if (kstat < 0) goto error; 55139 55140 /* VSK. 06.93. Adjust microbox tolerance in bezier case. */ 55141 55142 if (ktype != 0 && kstat == 1) kbez += 1; 55143 if (kdim1 == 1 && kbez > 0) teps2 -= (double)2.0*aepsge; 55144 else if (kbez > 0) teps2 -= aepsge; 55145 if (kbez) teps1 = aepsge; 55146 55147 /* Set pointers to box boundaries. */ 55148 55149 if (po2->iobj == SISLPOINT) 55150 { 55151 tmin2 = po2->p1->pbox->e2min[ktype]; 55152 tmax2 = po2->p1->pbox->e2max[ktype]; 55153 kdim2 = po2->p1->idim; 55154 } 55155 else if (po2->iobj == SISLCURVE) 55156 { 55157 tmin2 = po2->c1->pbox->e2min[ktype]; 55158 tmax2 = po2->c1->pbox->e2max[ktype]; 55159 kdim2 = po2->c1->idim; 55160 } 55161 else if (po2->iobj == SISLSURFACE) 55162 { 55163 tmin2 = po2->s1->pbox->e2min[ktype]; 55164 tmax2 = po2->s1->pbox->e2max[ktype]; 55165 kdim2 = po2->s1->idim; 55166 } 55167 else goto err121; 55168 55169 /* Check dimension. */ 55170 55171 if (kdim1 != kdim2 ) goto err106; 55172 else 55173 if (kdim1 < 1 ) goto err105; 55174 55175 55176 /* Compute total number of SISLbox edges. */ 55177 55178 if (itype < 10 && kdim1 == 3) kant = 9; 55179 else 55180 if (itype < 10 && kdim1 == 2) kant = 4; 55181 else kant = kdim1; 55182 55183 55184 /* For each dimension in all boxes perform box-test. First check 55185 that we point on the right place in the min- and max-arrays. */ 55186 55187 if (kpttest) 55188 { 55189 tmin1 += kant; 55190 tmin2 += kant; 55191 tmax1 += kant; 55192 tmax2 += kant; 55193 } 55194 55195 for (ki=0; ki<kant; ki++,tmin1++,tmax1++,tmin2++,tmax2++) 55196 { 55197 /* Sorting: t1-t2 The SISLbox with largest max value. 55198 t3-t4 The other box. */ 55199 55200 if (*tmax1 > *tmax2) 55201 { 55202 t1 = *tmax1; t01 = *(tmax1 - kant*kpttest); 55203 t2 = *tmin1; t02 = *(tmin1 - kant*kpttest); 55204 t3 = *tmax2; t03 = *(tmax2 - kant*kpttest); 55205 t4 = *tmin2; t04 = *(tmin2 - kant*kpttest); 55206 } 55207 else 55208 { 55209 t1 = *tmax2; t01 = *(tmax2 - kant*kpttest); 55210 t2 = *tmin2; t02 = *(tmin2 - kant*kpttest); 55211 t3 = *tmax1; t03 = *(tmax1 - kant*kpttest); 55212 t4 = *tmin1; t04 = *(tmin1 - kant*kpttest); 55213 } 55214 tdist = t2 - t3; 55215 55216 /* Use non-expanded boxes when testing if minibox is possible. */ 55217 55218 if (t01 - min(t02,t04) <= teps2) 55219 kj++; /* Minibox is possible. */ 55220 else if (kdim1 == 1 && t01-t04 <= teps1 && t03-t02 <= teps1) 55221 kj++; /* Minibox is possible. */ 55222 else if (t3 < t2 && (tdist > teps2 || !kpttest)) 55223 { 55224 *jstat = 0; /* No overlap. */ 55225 goto out; 55226 } 55227 else if (t3 < t2) 55228 kshadow = 1; /* Danger of shadow area. */ 55229 55230 /* UJK and ALA, 91-08: The tolerance is now 55231 incorporated in the box. 55232 else if (kdim1 != 1 && t3 - t2 < tepsge && t3 - t4 > teps2 && 55233 t1 - t2 > teps2) 55234 { 55235 *jstat = 2; Only edge touching possible. 55236 goto degenerate; 55237 } 55238 else if ( kdim1 == 1 && (t1 - t4 < tepsge || t3 - t2 < tepsge)) 55239 { 55240 *jstat = 2; Only edge touching possible. 55241 goto out; 55242 } */ 55243 55244 /* else possible overlap. */ 55245 } 55246 55247 if (kj == kant) 55248 *jstat = 3; /* Minibox found. */ 55249 else if (kshadow) 55250 *jstat = 5; /* Danger of shadow area. */ 55251 else 55252 *jstat = 1; /* Overlap. */ 55253 55254 55255 /* Box-test performed. */ 55256 55257 /* degenerate: */ 55258 /* Test if one of the objects has collapsed. Use non-expanded box. */ 55259 if (kdim1 != 1 && po1->iobj > SISLPOINT) 55260 { 55261 if (po1->iobj == SISLCURVE) 55262 { 55263 tmin1 = po1->c1->pbox->e2min[ktype]; 55264 tmax1 = po1->c1->pbox->e2max[ktype]; 55265 } 55266 55267 else if (po1->iobj == SISLSURFACE) 55268 { 55269 tmin1 = po1->s1->pbox->e2min[ktype]; 55270 tmax1 = po1->s1->pbox->e2max[ktype]; 55271 } 55272 55273 /* Make sure that we are correct place in the min- and max-arrays. */ 55274 55275 if (kpttest) 55276 { 55277 tmin1 += kant; 55278 tmax1 += kant; 55279 } 55280 55281 for(ki=0;ki<kdim1;ki++,tmin1++,tmax1++) 55282 if (fabs(tmax1[0]-tmin1[0]) > tepsge) break; 55283 55284 if (ki == kdim1+1) 55285 { 55286 *jstat = 4; 55287 goto out; 55288 } 55289 } 55290 55291 if (kdim1 != 1 && po2->iobj > SISLPOINT) 55292 { 55293 if (po2->iobj == SISLCURVE) 55294 { 55295 tmin1 = po2->c1->pbox->e2min[ktype]; 55296 tmax1 = po2->c1->pbox->e2max[ktype]; 55297 } 55298 55299 else if (po2->iobj == SISLSURFACE) 55300 { 55301 tmin1 = po2->s1->pbox->e2min[ktype]; 55302 tmax1 = po2->s1->pbox->e2max[ktype]; 55303 } 55304 55305 /* Make sure that we are correct place in the min- and max-arrays. */ 55306 55307 if (kpttest) 55308 { 55309 tmin1 += kant; 55310 tmax1 += kant; 55311 } 55312 55313 for(ki=0;ki<kdim1;ki++,tmin1++,tmax1++) 55314 if (fabs(tmax1[0]-tmin1[0]) > tepsge) break; 55315 55316 if (ki == kdim1+1) 55317 { 55318 *jstat = 4; 55319 goto out; 55320 } 55321 } 55322 goto out; 55323 55324 /* Dimensions conflicting. */ 55325 55326 err106: *jstat = -106; 55327 s6err("sh1790",*jstat,kpos); 55328 goto out; 55329 55330 /* Dimensions less than one. */ 55331 55332 err105: *jstat = -105; 55333 s6err("sh1790",*jstat,kpos); 55334 goto out; 55335 55336 /* Kind of object does not exist. */ 55337 55338 err121: *jstat = -121; 55339 s6err("sh1790",*jstat,kpos); 55340 goto out; 55341 55342 /* Error in lower level routine. */ 55343 55344 error: *jstat = kstat; 55345 s6err("sh1790",*jstat,kpos); 55346 goto out; 55347 55348 out: return; 55349 } 55350 55351 //=========================================================================== 55352 SISLEdge *newEdge (int iedge) 55353 //=========================================================================== 55354 { 55355 int ki; /* Counter. */ 55356 SISLEdge *pnew; /* Local pointer to the instance. */ 55357 SISLPtedge *(*ppt); /* Pointer to traverst array prpt of 55358 pointers to Ptedge-instances. */ 55359 55360 /* Allocate space for instance. */ 55361 55362 pnew = newarray (1, SISLEdge); 55363 if (pnew == SISL_NULL) 55364 goto err101; 55365 55366 /* Allocate space for array of pointers to Ptedge. */ 55367 55368 pnew->prpt = newarray (iedge, SISLPtedge *); 55369 if (pnew->prpt == SISL_NULL) 55370 goto err101; 55371 55372 /* Initiate the variables of the instance. */ 55373 55374 pnew->iedge = iedge; 55375 pnew->ipoint = 0; 55376 55377 ppt = pnew->prpt; 55378 for (ki = 0; ki < iedge; ki++) 55379 *(ppt++) = SISL_NULL; 55380 55381 /* Task done. */ 55382 55383 goto out; 55384 55385 /* Error in space allocation. Retrun zero. */ 55386 55387 err101:pnew = SISL_NULL; 55388 goto out; 55389 55390 out:return (pnew); 55391 } 55392 55393 //=========================================================================== 55394 void s1438(SISLCurve *pc,int iedge,SISLPoint **rpedge,double *cpar,int *jstat) 55395 //=========================================================================== 55396 { 55397 int kpos = 0; /* Position of error. */ 55398 55399 if (iedge == 0) 55400 { 55401 *cpar = pc->et[pc->ik - 1]; 55402 55403 if (((*rpedge) = newPoint(pc->ecoef,pc->idim,1)) == SISL_NULL) 55404 goto err101; 55405 } 55406 else if (iedge == 1) 55407 { 55408 *cpar = pc->et[pc->in]; 55409 55410 if (((*rpedge)=newPoint(pc->ecoef+pc->idim*(pc->in-1),pc->idim,1))==SISL_NULL) 55411 goto err101; 55412 } 55413 else goto err141; 55414 55415 /* SISLPoint picked. */ 55416 55417 *jstat = 0; 55418 goto out; 55419 55420 55421 /* Error in space allocation. */ 55422 55423 err101: *jstat = -101; 55424 s6err("s1438",*jstat,kpos); 55425 goto out; 55426 55427 /* Error in number of edges. */ 55428 55429 err141 : *jstat = -141; 55430 s6err("s1438",*jstat,kpos); 55431 goto out; 55432 55433 out: ; 55434 } 55435 55436 //=========================================================================== 55437 void sh1782 (SISLObject * po1, SISLObject * po2, double aepsge, 55438 SISLIntdat * pintdat, int ipar, double apar, 55439 SISLIntdat ** rintdat, int *jnewpt, int *jstat) 55440 //=========================================================================== 55441 { 55442 int kstat = 0; /* Status variable. */ 55443 int kdim; /* Dimension of geometry space. */ 55444 int knpoint; /* Number of int.pt. in array. */ 55445 SISLIntpt **uintpt = SISL_NULL; /* Array storing intersection points. */ 55446 55447 *jnewpt = 0; 55448 55449 /* Test if an intersection data structure exist. */ 55450 55451 if (pintdat == SISL_NULL) 55452 { 55453 *jstat = 0; 55454 goto out; 55455 } 55456 55457 /* Fetch dimension of geometry space. */ 55458 55459 if (po1->iobj == SISLPOINT) 55460 kdim = po1->p1->idim; 55461 else if (po1->iobj == SISLCURVE) 55462 kdim = po1->c1->idim; 55463 else 55464 kdim = po1->s1->idim; 55465 55466 /* Insert the intersection points from pintdat into the structure 55467 *rintdat belonging to the current problem. */ 55468 55469 sh6idput (po1, po2, rintdat, pintdat, ipar, apar, &uintpt, &knpoint, &kstat); 55470 if (kstat < 0) 55471 goto error; 55472 55473 if (knpoint == 0) 55474 { 55475 *jstat = 0; 55476 goto out; 55477 } 55478 55479 55480 /* Browse on the dimension of geometry space and the type of 55481 the input objects. */ 55482 55483 if (kdim <= 2 && ((po1->iobj == SISLSURFACE && po2->iobj == SISLPOINT) 55484 || (po2->iobj == SISLSURFACE && po1->iobj == SISLPOINT))) 55485 { 55486 /* Compute pre-topology in one-dimensional surface-level value 55487 intersection. */ 55488 55489 sh1782_s9sf_pt (po1, po2, aepsge, rintdat, uintpt, knpoint, 55490 ipar, &kstat); 55491 if (kstat < 0) 55492 goto error; 55493 55494 } 55495 55496 else if (kdim == 3 && 55497 ((po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE) || 55498 (po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE ))) 55499 { 55500 /* Surface-surface intersection in 3-dimensional geometry space. */ 55501 55502 sh1782_s9sf_cu (po1, po2, aepsge, rintdat, uintpt, knpoint, 55503 ipar, &kstat); 55504 if (kstat < 0) 55505 goto error; 55506 } 55507 55508 else if (kdim == 3 && po1->iobj == SISLSURFACE 55509 && po2->iobj == SISLSURFACE) 55510 { 55511 /* Surface-surface intersection in 3-dimensional geometry space. */ 55512 55513 sh1782_s9sf_sf (po1, po2, aepsge, rintdat, uintpt, knpoint, 55514 ipar, &kstat); 55515 if (kstat < 0) 55516 goto error; 55517 } 55518 55519 /* Task performed. */ 55520 55521 *jstat = 0; 55522 goto out; 55523 55524 /* Error in lower level routine. */ 55525 55526 error:*jstat = kstat; 55527 goto out; 55528 55529 out:if (uintpt != SISL_NULL) 55530 freearray (uintpt); 55531 } 55532 55533 //=========================================================================== 55534 void sh1782_s9sf_pt (SISLObject * po1, SISLObject * po2, double aepsge, 55535 SISLIntdat ** rintdat, SISLIntpt ** uintpt, int kpoint, 55536 int ipar, int *jstat) 55537 //=========================================================================== 55538 { 55539 int kstat = 0; /* Status variable. */ 55540 int kdim; /* Dimension of geometry space. */ 55541 double tdum, tsign; /* Parameters used to browse between cases.*/ 55542 double *sder; /* Surface geometry values. */ 55543 double *sdum; /* Normal of surface(dummy) */ 55544 int ind; /* Index for curve's par val. */ 55545 int ki, kj, klow, khigh; /* Help indexes into uintpt */ 55546 int index1, index2; /* Dummy in this context */ 55547 int kant; /* Edge indicator */ 55548 int *edge_f, *edge_l; /* Pointers to atribute edge in intpt */ 55549 SISLSurf *ps; /* The 1D Surface */ 55550 /* --------------------------------------------------------------------- */ 55551 55552 /* Test input */ 55553 kdim = (po1->iobj == SISLSURFACE) ? po1->s1->idim : po2->s1->idim; 55554 if (kdim != 1 && kdim !=2) 55555 goto err106; 55556 55557 if (ipar == 0) 55558 ind = 1; 55559 else 55560 ind = 0; 55561 55562 if (po1->iobj == SISLSURFACE) 55563 tsign = (double) 1.0; 55564 else 55565 tsign = -(double) 1.0; 55566 55567 /* Loop for all points */ 55568 for (ki = 0; ki < kpoint; ki++) 55569 for (kj = ki + 1; kj < kpoint; kj++) 55570 /* Connected ? */ 55571 { 55572 sh6getlist (uintpt[ki], uintpt[kj], &index1, &index2, &kstat); 55573 if (kstat < 0) 55574 goto error; 55575 if (!kstat) 55576 { 55577 /* They are connected, sort on edge par val*/ 55578 if (uintpt[ki]->epar[ind] < 55579 uintpt[kj]->epar[ind]) 55580 { 55581 klow = ki; 55582 khigh = kj; 55583 } 55584 else 55585 { 55586 klow = kj; 55587 khigh = ki; 55588 } 55589 55590 /* Fetch geometry of surface */ 55591 sh6getgeom ((po1->iobj == SISLSURFACE) ? po1 : po2, 55592 (po1->iobj == SISLSURFACE) ? 1 : 2, 55593 uintpt[klow], &sder, &sdum, aepsge, &kstat); 55594 55595 if (kstat < 0) 55596 goto error; 55597 55598 if (ipar == 0) 55599 tdum = tsign * sder[1]; 55600 else 55601 tdum = -tsign * sder[2]; 55602 55603 if (tdum > DZERO) 55604 sh6setdir (uintpt[klow], uintpt[khigh], &kstat); 55605 else if (tdum < 0) 55606 sh6setdir (uintpt[khigh], uintpt[klow], &kstat); 55607 55608 sh6setcnsdir (uintpt[klow], uintpt[khigh], ipar, &kstat); 55609 55610 /* Mark edge intersection curve */ 55611 if (sh6ismain (uintpt[ki]) && sh6ismain (uintpt[kj]) && 55612 po1->o1 == po1 && 55613 po2->o1 == po2) 55614 { 55615 55616 ps = po1->s1; 55617 edge_f = &(uintpt[ki]->edge_1); 55618 edge_l = &(uintpt[kj]->edge_1); 55619 55620 if (po2->iobj == SISLSURFACE) 55621 { 55622 edge_f = &(uintpt[ki]->edge_2); 55623 edge_l = &(uintpt[kj]->edge_2); 55624 ps = po2->s1; 55625 } 55626 55627 kant = 0; 55628 if (ipar == 0) 55629 { 55630 if (DEQUAL (uintpt[ki]->epar[ipar], 55631 ps->et1[ps->ik1 - 1])) 55632 kant = -1; 55633 else if (DEQUAL (uintpt[ki]->epar[ipar], 55634 ps->et1[ps->in1])) 55635 kant = 1; 55636 } 55637 else 55638 { 55639 if (DEQUAL (uintpt[ki]->epar[ipar], ps->et2[ps->ik2 - 1])) 55640 kant = 1; 55641 else if (DEQUAL (uintpt[ki]->epar[ipar], 55642 ps->et2[ps->in2])) 55643 kant = -1; 55644 } 55645 55646 if (kant) 55647 { 55648 if ((double) kant * tdum > DZERO) 55649 *edge_f = *edge_l = SI_RIGHT; 55650 else if ((double) kant * tdum < DZERO) 55651 *edge_f = *edge_l = SI_LEFT; 55652 55653 } 55654 55655 } 55656 55657 } 55658 } 55659 55660 *jstat = 0; 55661 goto out; 55662 55663 /* Error in input. Incorrect dimension. */ 55664 55665 err106:*jstat = -106; 55666 goto out; 55667 55668 /* Error lower level routine. */ 55669 55670 error:*jstat = kstat; 55671 goto out; 55672 55673 out: 55674 return; 55675 } 55676 55677 //=========================================================================== 55678 void sh1782_s9sf_cu (SISLObject * po1, SISLObject * po2, double aepsge, 55679 SISLIntdat ** rintdat, SISLIntpt ** uintpt, int kpoint, 55680 int ipar, int *jstat) 55681 //=========================================================================== 55682 { 55683 int kstat = 0; /* Status variable. */ 55684 int kdim; /* Dimension of geometry space. */ 55685 double tdum; /* Parameter used to browse on the cases. */ 55686 double *val_s1; /* Surface geometry */ 55687 double *val_s2; /* Surface geometry */ 55688 double *snorm1; /* Normal vector of surface. */ 55689 double *snorm2; /* Normal vector of surface. */ 55690 double *sdir; /* Direction vector of intersection curve. */ 55691 double *stang; /* Tangent vector of edge curve. */ 55692 int ind; /* Index for curve's par val. */ 55693 int ki, kj, klow, khigh; /* Help indexes into uintpt */ 55694 int index1, index2; /* Dummy in this context */ 55695 int kcurve; /* Which object is the curve? */ 55696 /* --------------------------------------------------------------------- */ 55697 55698 *jstat = 0; 55699 55700 /* Test input */ 55701 55702 if (po1->iobj == SISLCURVE && po2->iobj == SISLSURFACE) 55703 { 55704 kcurve = 1; 55705 kdim = po1->c1->idim; 55706 if (kdim != 3) 55707 goto err104; 55708 if (kdim != po2->s1->idim) 55709 goto err106; 55710 } 55711 else if (po1->iobj == SISLSURFACE && po2->iobj == SISLCURVE) 55712 { 55713 kcurve = 2; 55714 kdim = po1->s1->idim; 55715 if (kdim != 3) 55716 goto err104; 55717 if (kdim != po2->c1->idim) 55718 goto err106; 55719 } 55720 else 55721 goto err104; 55722 55723 /* Get index for curve par val */ 55724 if (kcurve == 1 && ipar == 1) 55725 ind = 2; 55726 else if ((kcurve == 1 && ipar == 2) || 55727 (kcurve == 2 && ipar == 0)) 55728 ind = 1; 55729 else if (kcurve == 2 && ipar == 1) 55730 ind = 0; 55731 else 55732 goto out; 55733 55734 /* Loop for all points */ 55735 for (ki = 0; ki < kpoint; ki++) 55736 for (kj = ki + 1; kj < kpoint; kj++) 55737 /* Connected ? */ 55738 { 55739 sh6getlist (uintpt[ki], uintpt[kj], &index1, &index2, &kstat); 55740 if (kstat < 0) 55741 goto error; 55742 if (!kstat) 55743 { 55744 /* They are connected, sort on edge par val*/ 55745 if (uintpt[ki]->epar[ind] < 55746 uintpt[kj]->epar[ind]) 55747 { 55748 klow = ki; 55749 khigh = kj; 55750 } 55751 else 55752 { 55753 klow = kj; 55754 khigh = ki; 55755 } 55756 55757 /* Get geometry first object */ 55758 sh6getgeom (po1, 1, uintpt[klow], &val_s1, &snorm1, aepsge, &kstat); 55759 if (kstat < 0) 55760 goto error; 55761 55762 /* Get geometry second object */ 55763 sh6getgeom (po2, 2, uintpt[klow], &val_s2, &snorm2, aepsge, &kstat); 55764 if (kstat < 0) 55765 goto error; 55766 55767 /* Fetch tangent of edge curve. */ 55768 if (ipar == 0) 55769 stang = val_s1 + 6; 55770 else if (ipar == 1 && kcurve == 2) 55771 stang = val_s1 + 3; 55772 else if (ipar == 1 && kcurve == 1) 55773 stang = val_s2 + 6; 55774 else 55775 stang = val_s2 + 3; 55776 55777 /* The direction of the intersection curve is set along 55778 the direction of the curve in the intersection. */ 55779 if (kcurve == 1) 55780 sdir = val_s1 + 3; 55781 else 55782 sdir = val_s2 + 3; 55783 55784 tdum = s6scpr (sdir, stang, kdim); 55785 55786 if (tdum > 0) 55787 sh6setdir (uintpt[klow], uintpt[khigh], &kstat); 55788 else if (tdum < 0) 55789 sh6setdir (uintpt[khigh], uintpt[klow], &kstat); 55790 55791 sh6setcnsdir (uintpt[klow], uintpt[khigh], ipar, &kstat); 55792 } 55793 } 55794 *jstat = 0; 55795 goto out; 55796 55797 55798 /* Error in input. Dimension not equal to 3. */ 55799 55800 err104:*jstat = -104; 55801 goto out; 55802 55803 /* Error in input. Conflicting dimensions. */ 55804 55805 err106:*jstat = -106; 55806 goto out; 55807 55808 /* Error lower level routine. */ 55809 55810 error:*jstat = kstat; 55811 goto out; 55812 55813 out: 55814 return; 55815 } 55816 55817 //=========================================================================== 55818 void sh1782_s9sf_sf (SISLObject * po1, SISLObject * po2, double aepsge, 55819 SISLIntdat ** rintdat, SISLIntpt ** uintpt, int kpoint, 55820 int ipar, int *jstat) 55821 //=========================================================================== 55822 { 55823 int kstat = 0; /* Status variable. */ 55824 int kdim; /* Dimension of geometry space. */ 55825 double tdum; /* Parameter used to browse on the cases. */ 55826 double *val_s1; /* Surface geometry */ 55827 double *val_s2; /* Surface geometry */ 55828 double *snorm1; /* Normal vector of surface. */ 55829 double *snorm2; /* Normal vector of surface. */ 55830 double sdir[3]; /* Direction vector of intersection curve. */ 55831 double *stang; /* Tangent vector of edge curve. */ 55832 int ind; /* Index for curve's par val. */ 55833 int ki, kj, klow, khigh; /* Help indexes into uintpt */ 55834 int index1, index2; /* Dummy in this context */ 55835 int *edge_f, *edge_l; /* Pointers to atribute edge in intpt */ 55836 int kant; /* Edge indicator */ 55837 SISLSurf *ps; /* The 3D Surface enhanced */ 55838 /* --------------------------------------------------------------------- */ 55839 55840 /* Test input */ 55841 kdim = po1->s1->idim; 55842 if (kdim != 3) 55843 goto err104; 55844 if (kdim != po2->s1->idim) 55845 goto err106; 55846 55847 /* Get index for curve par val */ 55848 if (ipar == 0) 55849 ind = 1; 55850 else if (ipar == 1) 55851 ind = 0; 55852 else if (ipar == 2) 55853 ind = 3; 55854 else 55855 ind = 2; 55856 55857 /* Loop for all points */ 55858 for (ki = 0; ki < kpoint; ki++) 55859 for (kj = ki + 1; kj < kpoint; kj++) 55860 /* Connected ? */ 55861 { 55862 sh6getlist (uintpt[ki], uintpt[kj], &index1, &index2, &kstat); 55863 if (kstat < 0) 55864 goto error; 55865 if (!kstat) 55866 { 55867 /* They are connected, sort on edge par val*/ 55868 if (uintpt[ki]->epar[ind] < 55869 uintpt[kj]->epar[ind]) 55870 { 55871 klow = ki; 55872 khigh = kj; 55873 } 55874 else 55875 { 55876 klow = kj; 55877 khigh = ki; 55878 } 55879 55880 55881 55882 55883 /* Get geometry first object */ 55884 sh6getgeom (po1, 1, uintpt[klow], &val_s1, &snorm1, aepsge, &kstat); 55885 if (kstat < 0) 55886 goto error; 55887 55888 /* Get geometry second object */ 55889 sh6getgeom (po2, 2, uintpt[klow], &val_s2, &snorm2, aepsge, &kstat); 55890 if (kstat < 0) 55891 goto error; 55892 55893 /* Get geometry lower level object */ 55894 /* Fetch tangent of edge curve. */ 55895 if (ipar == 0) 55896 stang = val_s1 + 6; 55897 else if (ipar == 1) 55898 stang = val_s1 + 3; 55899 else if (ipar == 2) 55900 stang = val_s2 + 6; 55901 else 55902 stang = val_s2 + 3; 55903 55904 /* Compute direction of intersection curve. */ 55905 s6crss (snorm1, snorm2, sdir); 55906 55907 tdum = s6scpr (sdir, stang, kdim); 55908 55909 if (tdum > 0) 55910 sh6setdir (uintpt[klow], uintpt[khigh], &kstat); 55911 else if (tdum < 0) 55912 sh6setdir (uintpt[khigh], uintpt[klow], &kstat); 55913 55914 sh6setcnsdir (uintpt[klow], uintpt[khigh], ipar, &kstat); 55915 /* Mark edge intersection curve */ 55916 if (sh6ismain (uintpt[ki]) && sh6ismain (uintpt[kj]) && 55917 po1->o1 == po1 && 55918 po2->o1 == po2) 55919 { 55920 55921 if (ipar < 2) 55922 /* First surf */ 55923 { 55924 edge_f = &(uintpt[ki]->edge_1); 55925 edge_l = &(uintpt[kj]->edge_1); 55926 ps = po1->s1; 55927 } 55928 else 55929 { 55930 edge_f = &(uintpt[ki]->edge_2); 55931 edge_l = &(uintpt[kj]->edge_2); 55932 ps = po2->s1; 55933 } 55934 55935 kant = 0; 55936 if (ipar == 0 || ipar == 2) 55937 { 55938 if (DEQUAL (uintpt[ki]->epar[ipar], 55939 ps->et1[ps->ik1 - 1])) 55940 kant = -1; 55941 else if (DEQUAL (uintpt[ki]->epar[ipar], 55942 ps->et1[ps->in1])) 55943 kant = 1; 55944 } 55945 else 55946 { 55947 if (DEQUAL (uintpt[ki]->epar[ipar], ps->et2[ps->ik2 - 1])) 55948 kant = 1; 55949 else if (DEQUAL (uintpt[ki]->epar[ipar], 55950 ps->et2[ps->in2])) 55951 kant = -1; 55952 } 55953 55954 if (kant) 55955 { 55956 if ((double) kant * tdum > DZERO) 55957 *edge_f = *edge_l = SI_RIGHT; 55958 else if ((double) kant * tdum < DZERO) 55959 *edge_f = *edge_l = SI_LEFT; 55960 55961 } 55962 55963 55964 55965 55966 55967 } 55968 } 55969 } 55970 *jstat = 0; 55971 goto out; 55972 55973 55974 /* Error in input. Dimension not equal to 3. */ 55975 55976 err104:*jstat = -104; 55977 goto out; 55978 55979 /* Error in input. Conflicting dimensions. */ 55980 55981 err106:*jstat = -106; 55982 goto out; 55983 55984 /* Error lower level routine. */ 55985 55986 error:*jstat = kstat; 55987 goto out; 55988 55989 out: 55990 return; 55991 } 55992
Generated on Tue Sep 21 15:44:24 2010 for GoTools Core by  doxygen 1.6.3