ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm.c
(Generate patch)

Comparing ray/src/hd/sm.c (file contents):
Revision 3.10 by gwlarson, Mon Dec 28 19:30:27 1998 UTC vs.
Revision 3.13 by gwlarson, Sun Jan 10 10:27:48 1999 UTC

# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ SGI";
18  
19   SM *smMesh = NULL;
20   double smDist_sum=0;
21 + #define S_INC 1000
22   int smNew_tri_cnt=0;
23 < double smMinSampDiff = 4.25e-4; /* min edge length in radians */
23 > int smNew_tri_size=0;
24  
25 + #define SM_MIN_SAMP_DIFF 1e-4/* min edge length in radians */
26 +
27   /* Each edge extends .5536 radians - 31.72 degrees */
28   static FVECT icosa_verts[162] =
29   {{-0.018096,0.495400,0.868477},{0.018614,-0.554780,0.831789},
# Line 445 | Line 448 | smAlloc(max_samples)
448  
449    total_points = n + SM_EXTRA_POINTS;
450  
451 <  max_tris = total_points*4;
451 >  max_tris = total_points*2;
452    /* Now allocate space for mesh vertices and triangles */
453    max_tris = smAlloc_mesh(smMesh, total_points, max_tris);
454  
# Line 568 | Line 571 | insert_tri(argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,
571    /* If the set size is below expansion threshold,or at maximum
572       number of quadtree levels : just add */
573    optr = qtqueryset(qt);
574 <  if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n >= QT_MAX_LEVELS))
574 >  if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n > (QT_MAX_LEVELS-2)))
575      return(qtadduelem(qt,t_id));
576    /* otherwise: expand node- and insert tri, and reinsert existing tris
577       in set to children of new node
# Line 697 | Line 700 | int v0_id,v1_id,v2_id;
700      SM_NTH_VERT(sm,v2_id) = t_id;
701  
702      if(SM_BASE_ID(sm,v0_id) || SM_BASE_ID(sm,v1_id) || SM_BASE_ID(sm,v2_id))
700    {
701      smClear_tri_flags(sm,t_id);
703        SM_SET_NTH_T_BASE(sm,t_id);
703    }
704      else
705 <    {
706 <      SM_CLR_NTH_T_BASE(sm,t_id);
707 <      SM_SET_NTH_T_ACTIVE(sm,t_id);
708 <      SM_SET_NTH_T_NEW(sm,t_id);
709 <      S_SET_FLAG(T_NTH_V(t,0));
710 <      S_SET_FLAG(T_NTH_V(t,1));
711 <      S_SET_FLAG(T_NTH_V(t,2));
712 <      SM_SAMPLE_TRIS(sm)++;
713 <      smNew_tri_cnt++;
714 <    }
705 >      if(SM_DIR_ID(sm,v0_id) && SM_DIR_ID(sm,v1_id) && SM_DIR_ID(sm,v2_id))
706 >      SM_SET_NTH_T_BG(sm,t_id);
707  
708 +    S_SET_FLAG(T_NTH_V(t,0));
709 +    S_SET_FLAG(T_NTH_V(t,1));
710 +    S_SET_FLAG(T_NTH_V(t,2));
711 +
712 +    SM_SET_NTH_T_ACTIVE(sm,t_id);
713 +    SM_SET_NTH_T_NEW(sm,t_id);
714 +
715 +    SM_SAMPLE_TRIS(sm)++;
716 +    smNew_tri_cnt++;
717 +
718      /* return initialized triangle */
719      return(t_id);
720   }
# Line 769 | Line 771 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_p
771                         !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) ||
772                         !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2))))
773            goto Ltri_error;
774 +        /*
775          if(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,1)) ||
776             SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) ||
777             SM_NTH_TRI(sm,T_NTH_NBR(ta,1))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) ||
# Line 776 | Line 779 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_p
779             SM_NTH_TRI(sm,T_NTH_NBR(tb,0))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) ||
780             SM_NTH_TRI(sm,T_NTH_NBR(tb,1))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) )
781            goto Ltri_error;
782 +          */
783   #endif
784      /* Reset neighbor pointers of original neighbors */
785      n = SM_NTH_TRI(sm,T_NTH_NBR(t,enext));
# Line 811 | Line 815 | smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_p
815  
816      remove_from_list(t_id,add_ptr);
817      remove_from_list(t1_id,add_ptr);
818 < #if 1
818 >
819      smDelete_tri(sm,t_id);
820      smDelete_tri(sm,t1_id);
817 #else
818    *del_ptr = push_data(*del_ptr,t_id);
819    *del_ptr = push_data(*del_ptr,t1_id);
820 #endif
821  
822
823
822      *tn_id = ta_id;
823      *tn1_id = tb_id;
824      
# Line 850 | Line 848 | smUpdate_locator(sm,add_list)
848   SM *sm;
849   LIST *add_list;
850   {
851 <  int t_id,i;
851 >  int t_id;
852    TRI *t;
855  OBJECT *optr;
853    
854    while(add_list)
855    {
# Line 872 | Line 869 | LIST *tlist,*add_list;
869      FVECT p,p0,p1,p2;
870      int e,e1,swapped = 0;
871      int t_id,t_opp_id;
872 <    LIST *del_list=NULL;
872 >    LIST *del_list=NULL,*lptr;
873  
874      VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
875      while(tlist)
# Line 909 | Line 906 | LIST *tlist,*add_list;
906              tlist = push_data(tlist,t_opp_id);
907          }
908      }
909 < #if 0
913 <    while(del_list)
914 <    {
915 <      t_id = pop_list(&del_list);
916 <      smDelete_tri(sm,t_id);
917 <    }
918 < #endif
909 >
910      smUpdate_locator(sm,add_list);
911  
912      return(swapped);
# Line 967 | Line 958 | smInsert_samp(sm,s_id,tri_id,on,which)
958      FVECT npt;
959      TRI *tri,*nbr,*topp;
960  
970
961      add_list = NULL;
962      for(i=0; i<3;i++)
963        v_id[i] = T_NTH_V(SM_NTH_TRI(sm,tri_id),i);
# Line 1226 | Line 1216 | int *onptr,*whichptr;
1216    optr = qtqueryset(qt);
1217    tri_id = smTri_in_set(sm,tpt,optr,onptr,whichptr);
1218  
1229 #ifdef DEBUG
1230  if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),0))) ||
1231     !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),1))) ||
1232     !T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),2))))
1233    eputs("Invalid tri nbrs smPointLocateTri()\n");
1234 #endif
1219    return(tri_id);
1220   }
1221  
# Line 1285 | Line 1269 | smTest_sample(sm,tri_id,dir,p,rptr)
1269  
1270      for(i=0; i<3; i++)
1271      {
1272 <        if(SM_BASE_ID(sm,vid[i]))
1273 <        {
1274 <          bcnt++;
1275 <           continue;
1276 <        }
1293 <        if(SM_DIR_ID(sm,vid[i]))
1294 <           dcnt++;
1295 <        VSUB(diff[i],SM_NTH_WV(sm,vid[i]),p);
1296 <        /* If same world point: replace */
1272 >      if(SM_BASE_ID(sm,vid[i]))
1273 >        bcnt++;
1274 >      if(SM_DIR_ID(sm,vid[i]))
1275 >        dcnt++;
1276 >      
1277      }
1278      /* TEST 1: If the new sample is close in ws, and close in the spherical
1279         projection to one of the triangle vertex samples
1280      */
1281 + #if 0
1282      norm = FALSE;
1302    if(bcnt + dcnt != 3)
1303    {
1283        VSUB(spt,p,SM_VIEW_CENTER(sm));
1284        ds = DOT(spt,spt);
1285        dnear = FHUGE;
1286        for(i=0; i<3; i++)
1287          {
1309          if(SM_BASE_ID(sm,vid[i]) || SM_DIR_ID(sm,vid[i]))
1310            continue;
1288            d = DOT(diff[i],diff[i])/ds;
1289            if(d < dnear)
1290              {
# Line 1316 | Line 1293 | smTest_sample(sm,tri_id,dir,p,rptr)
1293              }
1294          }
1295  
1296 <      if(dnear <=  smMinSampDiff*smMinSampDiff)
1296 >      if(dnear <=  SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF)
1297          {
1298            /* Pick the point with dir closest to that of the canonical view
1299               if it is the new sample: mark existing point for deletion
1300               */
1301 +          if(SM_BASE_ID(sm,nearid))
1302 +          {
1303 +            *rptr = nearid;
1304 +            return(TRUE);
1305 +          }
1306 +          if(SM_DIR_ID(sm,nearid))
1307 +            return(FALSE);
1308 +          if(!dir)
1309 +          {
1310 +            *rptr = nearid;
1311 +            return(TRUE);
1312 +          }
1313            normalize(spt);
1314            norm = TRUE;
1315            VSUB(npt,SM_NTH_WV(sm,nearid),SM_VIEW_CENTER(sm));
# Line 1328 | Line 1317 | smTest_sample(sm,tri_id,dir,p,rptr)
1317            d = fdir2diff(SM_NTH_W_DIR(sm,nearid), npt);
1318            d2 = 2. - 2.*DOT(dir,spt);
1319            /* The existing sample is a better sample:punt */
1320 <          if(d2 > d)
1320 >         if(d2 > d)
1321              return(FALSE);
1322 <          else
1323 <            {
1324 <                /* The new sample is better: mark the existing one
1322 >         else
1323 >         {
1324 >        /* The new sample is better: mark the existing one
1325                     for deletion after the new one is added*/
1326 <              *rptr = nearid;
1327 <              return(TRUE);
1339 <            }
1326 >        *rptr = nearid;
1327 >        return(TRUE);
1328          }
1329 <    }
1329 >     }  
1330 >    
1331    /* TEST 3: If the spherical projection of new is < S_REPLACE_EPS
1332       from a base point: Edge length is constrained to subtend <45 degrees:
1333       original base mesh edges are approx 32 degrees- so have about 13 degrees
1334       to work in: S_REPLACE_EPS is the square of the radian value
1335    */
1336 +
1337      if(bcnt)
1338      {  
1339          dnear = FHUGE;
1350        if(bcnt + dcnt ==3)
1351          VSUB(spt,p,SM_VIEW_CENTER(sm));
1340          if(!norm)
1341            normalize(spt);
1342  
# Line 1358 | Line 1346 | smTest_sample(sm,tri_id,dir,p,rptr)
1346                 continue;
1347              VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm));
1348              d = DIST_SQ(npt,spt);
1349 <            if(d < S_REPLACE_EPS && d < dnear)
1349 >            if(dnear <=  SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d< near)
1350                 {
1351                     dnear = d;
1352                     nearid = vid[i];
# Line 1371 | Line 1359 | smTest_sample(sm,tri_id,dir,p,rptr)
1359              return(TRUE);
1360          }
1361      }
1362 + #else
1363 +    {
1364 +      FVECT nearpt;
1365 +    dnear = FHUGE;
1366 +    VSUB(spt,p,SM_VIEW_CENTER(sm));
1367 +    ds = DOT(spt,spt);
1368 +    normalize(spt);
1369 +
1370 +    for(i=0; i<3; i++)
1371 +    {
1372          
1373 +      VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm));
1374 +      
1375 +      if(!SM_BASE_ID(sm,vid[i]) && !SM_DIR_ID(sm,vid[i]))
1376 +        normalize(npt);
1377 +
1378 +      d = DIST_SQ(npt,spt);
1379 +      if(d < SM_MIN_SAMP_DIFF*SM_MIN_SAMP_DIFF && d < dnear)
1380 +        {
1381 +          dnear = d;
1382 +          nearid = vid[i];
1383 +          VCOPY(nearpt,npt);
1384 +        }
1385 +
1386 +    }
1387 +    if(dnear != FHUGE)
1388 +    {
1389 +          /* Pick the point with dir closest to that of the canonical view
1390 +             if it is the new sample: mark existing point for deletion
1391 +             */
1392 +          if(SM_BASE_ID(sm,nearid))
1393 +          {
1394 +            *rptr = nearid;
1395 +            return(TRUE);
1396 +          }
1397 +          if(SM_DIR_ID(sm,nearid))
1398 +            return(FALSE);
1399 +          if(!dir)
1400 +          {
1401 +            *rptr = nearid;
1402 +            return(TRUE);
1403 +          }
1404 +          d = fdir2diff(SM_NTH_W_DIR(sm,nearid), nearpt);
1405 +          d2 = 2. - 2.*DOT(dir,spt);
1406 +          /* The existing sample is a better sample:punt */
1407 +         if(d2 > d)
1408 +            return(FALSE);
1409 +         else
1410 +         {
1411 +        /* The new sample is better: mark the existing one
1412 +                   for deletion after the new one is added*/
1413 +        *rptr = nearid;
1414 +        return(TRUE);
1415 +        }
1416 +    }  
1417 +    }
1418 + #endif  
1419    /* TEST 4:
1420       If the addition of the new sample point would introduce a "puncture"
1421       or cause new triangles with large depth differences:dont add:    
1422       */
1423      if(bcnt || dcnt)
1424         return(TRUE);
1425 +
1426      /* If the new point is in front of the existing points- add */
1427      dv = DIST_SQ(SM_NTH_WV(sm,vid[0]),SM_VIEW_CENTER(sm));
1428      if(ds < dv)
1429        return(TRUE);
1430  
1431      d01 = DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_NTH_WV(sm,vid[0]));
1432 +    VSUB(diff[0],SM_NTH_WV(sm,vid[0]),p);
1433      s0 = DOT(diff[0],diff[0]);
1434      if(s0 < S_REPLACE_SCALE*d01)
1435         return(TRUE);
1436 +
1437      d12 = DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_NTH_WV(sm,vid[1]));
1438      if(s0 < S_REPLACE_SCALE*d12)
1439         return(TRUE);    
# Line 1394 | Line 1441 | smTest_sample(sm,tri_id,dir,p,rptr)
1441      if(s0 < S_REPLACE_SCALE*d20)
1442         return(TRUE);    
1443      d = MIN3(d01,d12,d20);
1444 <    s1 = DOT(diff[1],diff[1]);
1444 >    VSUB(diff[1],SM_NTH_WV(sm,vid[1]),p);
1445 >   s1 = DOT(diff[1],diff[1]);
1446      if(s1 < S_REPLACE_SCALE*d)
1447         return(TRUE);
1448 +    VSUB(diff[2],SM_NTH_WV(sm,vid[2]),p);
1449      s2 = DOT(diff[2],diff[2]);
1450      if(s2 < S_REPLACE_SCALE*d)
1451         return(TRUE);    
# Line 1413 | Line 1462 | smTest_sample(sm,tri_id,dir,p,rptr)
1462      return(FALSE);
1463   }
1464  
1465 <
1417 < int
1418 < smAlloc_samp(sm)
1465 > smReplace_base_samp(sm,b_id,s_id,tri,t_id,which)
1466   SM *sm;
1467 + int b_id,s_id;
1468 + TRI *tri;
1469 + int t_id,which;
1470   {
1471 <  int s_id,replaced,cnt;
1422 <  SAMP *s;
1423 <  FVECT p;
1471 >  TRI *t;
1472  
1473 <  s = SM_SAMP(sm);
1474 <  s_id = sAlloc_samp(s,&replaced);
1475 <
1476 <  cnt=0;
1477 <  while(replaced)
1473 >  SM_NTH_VERT(sm,s_id) = t_id;
1474 >  T_NTH_V(tri,which) = s_id;
1475 >  if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) ||
1476 >       SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3))))
1477 >    SM_CLR_NTH_T_BASE(sm,t_id);
1478 >  if(!SM_IS_NTH_T_NEW(sm,t_id))
1479    {
1480 <    if(smRemoveVertex(sm,s_id))
1481 <      break;
1433 <    s_id = sAlloc_samp(s,&replaced);
1434 <    cnt++;
1435 <    if(cnt > S_MAX_SAMP(s))
1436 <      error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n");
1480 >    smNew_tri_cnt++;
1481 >    SM_SET_NTH_T_NEW(sm,t_id);
1482    }
1483 <  return(s_id);
1483 >  t_id = smTri_next_ccw_nbr(sm,tri,b_id);
1484 >  while(t_id != INVALID)
1485 >  {
1486 >    t = SM_NTH_TRI(sm,t_id);
1487 >    which = T_WHICH_V(t,b_id);
1488 >    T_NTH_V(t,which) = s_id;
1489 >    /* Check if still a base triangle */
1490 >    if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) ||
1491 >         SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3))))
1492 >      SM_CLR_NTH_T_BASE(sm,t_id);
1493 >     if(!SM_IS_NTH_T_NEW(sm,t_id))
1494 >        {
1495 >          smNew_tri_cnt++;
1496 >          SM_SET_NTH_T_NEW(sm,t_id);
1497 >        }
1498 >     t_id = smTri_next_ccw_nbr(sm,t,b_id);
1499 >    }
1500   }
1501  
1502   int
# Line 1445 | Line 1506 | smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which)
1506       FVECT dir,p;
1507       int s_id,t_id,o_id,on,which;
1508   {
1509 <  int tonemap,v_id;
1509 >  int v_id,tri_id;
1510    TRI *t,*tri;
1511  
1512    tri = SM_NTH_TRI(sm,t_id);
# Line 1454 | Line 1515 | smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which)
1515    /* If it is a base id, need new sample */
1516    if(SM_BASE_ID(sm,v_id))
1517    {
1518 <    tonemap = (SM_TONE_MAP(sm) > s_id);
1519 <    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,tonemap);
1459 <    SM_NTH_VERT(sm,s_id) = t_id;
1460 <    T_NTH_V(tri,which) = s_id;
1461 <    if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) ||
1462 <         SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3))))
1463 <      SM_CLR_NTH_T_BASE(sm,t_id);
1464 <    t_id = smTri_next_ccw_nbr(sm,tri,v_id);
1465 <    while(t_id != INVALID)
1466 <    {
1467 <      t = SM_NTH_TRI(sm,t_id);
1468 <      which = T_WHICH_V(t,v_id);
1469 <      T_NTH_V(t,which) = s_id;
1470 <      /* Check if still a base triangle */
1471 <      if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) ||
1472 <           SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3))))
1473 <        SM_CLR_NTH_T_BASE(sm,t_id);
1474 <      t_id = smTri_next_ccw_nbr(sm,t,v_id);
1475 <    }
1518 >    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
1519 >    smReplace_base_samp(sm,v_id,s_id,tri,t_id,which);
1520      return(s_id);
1521    }
1522 <  else
1523 <    if(on == ON_V || !p)
1522 >  if(dir)
1523 >  {
1524 >    /* If world point */
1525 >    /* if existing point is a dir: leave */
1526 >    if(SM_DIR_ID(sm,v_id))
1527 >      return(INVALID);
1528 >    if(on == ON_V)
1529      {
1530 <      tonemap = (SM_TONE_MAP(sm) > v_id);
1531 <      sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap);
1530 >      sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id);
1531 >
1532 >     if(!SM_IS_NTH_T_NEW(sm,t_id))
1533 >        {
1534 >          smNew_tri_cnt++;
1535 >          SM_SET_NTH_T_NEW(sm,t_id);
1536 >        }
1537 >      tri_id = smTri_next_ccw_nbr(sm,tri,v_id);
1538 >      while(tri_id != t_id)
1539 >      {
1540 >        t = SM_NTH_TRI(sm,tri_id);
1541 >     if(!SM_IS_NTH_T_NEW(sm,tri_id))
1542 >        {
1543 >          smNew_tri_cnt++;
1544 >          SM_SET_NTH_T_NEW(sm,tri_id);
1545 >        }
1546 >
1547 >        tri_id = smTri_next_ccw_nbr(sm,t,v_id);
1548 >      }
1549        return(v_id);
1550      }
1551 <  else /* on == ON_P */
1552 <    {
1553 <      FVECT spt,npt;
1554 <      double d,d2;
1551 >    /* on == ON_P */
1552 >    else
1553 >   {
1554 >     FVECT spt,npt;
1555 >     double d,d2;
1556  
1557 <      /* Need to check which sample is preferable */
1558 <      VSUB(spt,p,SM_VIEW_CENTER(sm));
1559 <      normalize(spt);
1557 >    /* Need to check which sample is preferable */
1558 >     VSUB(spt,p,SM_VIEW_CENTER(sm));
1559 >     normalize(spt);
1560          
1561 <      VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm));
1562 <      normalize(npt);
1563 <      d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt);
1564 <      d2 = 2. - 2.*DOT(dir,spt);
1561 >     VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm));
1562 >     normalize(npt);
1563 >     d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt);
1564 >     d2 = 2. - 2.*DOT(dir,spt);
1565        /* The existing sample is a better sample:punt */
1566 <      if(d2 < d)
1567 <      {
1568 <        /* The new sample has better information- replace values */
1569 <        tonemap = (SM_TONE_MAP(sm) > v_id);
1570 <        sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap);
1571 <      }
1572 <      return(v_id);
1566 >     if(d2 < d)
1567 >       {
1568 >         /* The new sample has better information- replace values */
1569 >         sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id);
1570 >         if(!SM_IS_NTH_T_NEW(sm,t_id))
1571 >            {
1572 >              smNew_tri_cnt++;
1573 >              SM_SET_NTH_T_NEW(sm,t_id);
1574 >            }
1575 >
1576 >         tri_id = smTri_next_ccw_nbr(sm,tri,v_id);
1577 >         while(tri_id != t_id)
1578 >           {
1579 >             t = SM_NTH_TRI(sm,tri_id);
1580 >             if(!SM_IS_NTH_T_NEW(sm,tri_id))
1581 >            {
1582 >              smNew_tri_cnt++;
1583 >              SM_SET_NTH_T_NEW(sm,tri_id);
1584 >            }
1585 >             tri_id = smTri_next_ccw_nbr(sm,t,v_id);
1586 >           }
1587 >       }
1588 >    return(v_id);
1589 >   }
1590 >  }
1591 >  else
1592 >    { /* New point is a dir */
1593 >      return(INVALID);
1594      }
1595   }
1596  
1597 + int
1598 + smAlloc_samp(sm)
1599 + SM *sm;
1600 + {
1601 +  int s_id,replaced,cnt;
1602 +  SAMP *s;
1603 +  FVECT p;
1604 +
1605 +  s = SM_SAMP(sm);
1606 +  s_id = sAlloc_samp(s,&replaced);
1607 +
1608 +  cnt=0;
1609 +  while(replaced)
1610 +  {
1611 +    if(smRemoveVertex(sm,s_id))
1612 +      break;
1613 +    s_id = sAlloc_samp(s,&replaced);
1614 +    cnt++;
1615 +    if(cnt > S_MAX_SAMP(s))
1616 +      error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n");
1617 +  }
1618 +  return(s_id);
1619 + }
1620 +
1621 +
1622   /* Add sample to the mesh:
1623  
1624     the sample can be a world space or directional point. If o_id !=INVALID,
# Line 1537 | Line 1650 | smAdd_samp(sm,c,dir,p,o_id)
1650    /* If sample is a world space point */
1651    if(p)
1652    {
1653 <    t_id = smPointLocateTri(sm,p,&on,&which);
1654 <    if(t_id == INVALID)
1653 >    while(1)
1654 >    {
1655 >      t_id = smPointLocateTri(sm,p,&on,&which);
1656 >      if(t_id == INVALID)
1657        {
1658   #ifdef DEBUG
1659 <        eputs("smAddSamp(): unable to locate tri containing sample \n");
1659 >          eputs("smAddSamp(): unable to locate tri containing sample \n");
1660   #endif
1661 +          smUnalloc_samp(sm,s_id);
1662 +          return(INVALID);
1663 +        }
1664 +      /* If spherical projection coincides with existing sample: replace */
1665 +      if((on == ON_V || on == ON_P))
1666 +      {
1667 +          n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which);
1668 +          if(n_id!= s_id)
1669 +             smUnalloc_samp(sm,s_id);
1670 +          return(n_id);
1671 +      }
1672 +      if((!(smTest_sample(sm,t_id,dir,p,&r_id))))
1673 +     {
1674          smUnalloc_samp(sm,s_id);
1675          return(INVALID);
1676        }
1677 <    /* If spherical projection coincides with existing sample: replace */
1678 <    if((on == ON_V || on == ON_P))
1679 <    {
1680 <      if((n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which))!= s_id)
1681 <        smUnalloc_samp(sm,s_id);
1682 <        return(n_id);
1677 >      if(r_id != INVALID)
1678 >      {
1679 >        smRemoveVertex(sm,r_id);
1680 >        sDelete_samp(SM_SAMP(sm),r_id);
1681 >      }
1682 >      else
1683 >        break;
1684      }
1556    if((!(smTest_sample(sm,t_id,dir,p,&r_id))))
1557    {
1558      smUnalloc_samp(sm,s_id);
1559      return(INVALID);
1560    }
1685      /* If sample is being added in the middle of the sample array: tone
1686         map individually
1687         */
1688      /* Initialize sample */
1689 <    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,(SM_TONE_MAP(sm)>s_id));    
1689 >    sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id);
1690      
1691    }
1692      /* If sample is a direction vector */
1693      else
1694      {
1695        VADD(wpt,dir,SM_VIEW_CENTER(sm));
1696 <      t_id = smPointLocateTri(sm,wpt,&on,&which);
1697 <      if(t_id == INVALID)
1698 <        {
1696 >      while(1)
1697 >        {
1698 >            t_id = smPointLocateTri(sm,wpt,&on,&which);
1699 >            if(t_id == INVALID)
1700 >               {
1701   #ifdef DEBUG
1702 <          eputs("smAddSamp(): unable to locate tri containing sample \n");
1702 >                   eputs("smAddSamp(): can'tlocate tri containing samp\n");
1703   #endif
1704 <          smUnalloc_samp(sm,s_id);
1705 <          return(INVALID);
1704 >                   smUnalloc_samp(sm,s_id);
1705 >                   return(INVALID);
1706 >               }
1707 >            if(on == ON_V || on == ON_P)
1708 >            {
1709 >                n_id=smReplace_samp(sm,c,NULL,wpt,s_id,t_id,o_id,on,which);
1710 >                if(n_id !=s_id)
1711 >                   smUnalloc_samp(sm,s_id);
1712 >                return(n_id);
1713 >            }
1714 >            if((!(smTest_sample(sm,t_id,NULL,wpt,&r_id))))
1715 >            {
1716 >                smUnalloc_samp(sm,s_id);
1717 >                return(INVALID);
1718 >            }
1719 >            if(r_id != INVALID)
1720 >            {
1721 >                smRemoveVertex(sm,r_id);
1722 >                sDelete_samp(SM_SAMP(sm),r_id);
1723 >            }
1724 >            else
1725 >               break;
1726          }
1581    if(on == ON_V || on == ON_P)
1582    {
1583      if((n_id = smReplace_samp(sm,c,wpt,NULL,s_id,t_id,o_id,on,which))!= s_id)
1584        smUnalloc_samp(sm,s_id);
1585        return(n_id);
1586    }
1727        /* Allocate space for a sample and initialize */
1728 <      sInit_samp(SM_SAMP(sm),s_id,c,wpt,NULL,o_id,(SM_TONE_MAP(sm)>s_id));
1728 >      sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id);
1729      }
1730    if(!SM_DIR_ID(sm,s_id))
1731      {
# Line 1596 | Line 1736 | smAdd_samp(sm,c,dir,p,o_id)
1736      }
1737      smInsert_samp(sm,s_id,t_id,on,which);
1738  
1599    /* If new sample replaces existing one- remove that vertex now */
1600    if(r_id != INVALID)
1601    {
1602      smRemoveVertex(sm,r_id);
1603      sDelete_samp(SM_SAMP(sm),r_id);
1604    }
1739      return(s_id);
1740   }
1741  
# Line 1624 | Line 1758 | FVECT p;
1758   {
1759      int s_id;
1760  
1627
1761      /* First check if this the first sample: if so initialize mesh */
1629
1762      if(SM_NUM_SAMP(smMesh) == 0)
1763      {
1764        smInit_sm(smMesh,odev.v.vp);
# Line 1727 | Line 1859 | smNext_tri_flag_set(sm,i,which,b)
1859   }
1860  
1861  
1862 +
1863   int
1864   smNext_valid_tri(sm,i)
1865       SM *sm;
# Line 1807 | Line 1940 | smRebuild_mesh(sm,v)
1940          }
1941  
1942      }
1810
1811   smNew_tri_cnt = SM_SAMPLE_TRIS(sm);
1943   #ifdef DEBUG
1944      fprintf(stderr,"smRebuild_mesh():done\n");
1945   #endif
# Line 2145 | Line 2276 | mark_active_tris(argptr,root,qt)
2276      t_id = QT_SET_NEXT_ELEM(optr);
2277      /* Set the render flag */
2278       tri = SM_NTH_TRI(smMesh,t_id);
2279 <     if(!T_IS_VALID(tri) ||  SM_IS_NTH_T_BASE(smMesh,t_id))
2279 >     if(!T_IS_VALID(tri))
2280              continue;
2281       SM_SET_NTH_T_ACTIVE(smMesh,t_id);
2282       /* Set the Active bits of the Vertices */
2283       S_SET_FLAG(T_NTH_V(tri,0));
2284       S_SET_FLAG(T_NTH_V(tri,1));
2285       S_SET_FLAG(T_NTH_V(tri,2));
2286 <   }
2286 >  }
2287   }
2288  
2289  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines