home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / gfx / 3d / irit / geom_lib / intrnrml.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-09  |  10.5 KB  |  248 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d (not only polygonal) solid modeller.             *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Aug. 1990   *
  5. ******************************************************************************
  6. *   Module to interplate internal vertices using vertices on the given       *
  7. * convex boundary OriginalVList. All internal vertices are assumed to be in  *
  8. * the interior of the convex region defined by OriginalVList or on its       *
  9. * boundary.                                     *
  10. *****************************************************************************/
  11.  
  12. #include <math.h>
  13. #include "irit_sm.h"
  14. #include "iritprsr.h"
  15. #include "geomat3d.h"
  16. #include "intrnrml.h"
  17.  
  18. /* #define DEBUG1          To define polygon (with normals printing routine. */
  19.  
  20. static void UpdateOneVertexNormal(IPVertexStruct *VUpdate,
  21.                   IPPolygonStruct *OriginalPl);
  22.  
  23. #ifdef DEBUG1 
  24. static void PrintPolygon(IPPolygonStruct *Pl);
  25. #endif /* DEBUG1 */
  26.  
  27. /*****************************************************************************
  28. * DESCRIPTION:                                                               M
  29. * For each polygon in PlList update any vertex normal which is zero to an    M
  30. * interpolated value using the Original polygon vertex list OriginalPl.      M
  31. *   All the new vertices are enclosed within the original polygon which      M
  32. * must be convex as well.                             M
  33. *                                                                            *
  34. * PARAMETERS:                                                                M
  35. *   PlList:       List of polygons to update normal for.                     M
  36. *   OriginalPl:   Original polygons PlList was derived from, probably using  M
  37. *                 Boolean operations.                                        M
  38. *                                                                            *
  39. * RETURN VALUE:                                                              M
  40. *   void                                                                     M
  41. *                                                                            *
  42. * KEYWORDS:                                                                  M
  43. *   UpdateVerticesNormals, normals                                           M
  44. *****************************************************************************/
  45. void UpdateVerticesNormals(IPPolygonStruct *PlList,
  46.                IPPolygonStruct *OriginalPl)
  47. {
  48.     IPVertexStruct *V, *VHead;
  49.  
  50.     while (PlList) {
  51.     V = VHead = PlList -> PVertex;
  52.     do {
  53.         if (APX_EQ(V -> Normal[0], 0.0) &&
  54.         APX_EQ(V -> Normal[1], 0.0) &&
  55.         APX_EQ(V -> Normal[2], 0.0)) {
  56.         /* This vertex need to be updated. */
  57.         UpdateOneVertexNormal(V, OriginalPl);
  58.         }
  59.  
  60.         V = V -> Pnext;
  61.     }
  62.     while (V != NULL && V != VHead);
  63.  
  64.     PlList = PlList -> Pnext;
  65.     }
  66. }
  67.  
  68. /*****************************************************************************
  69. * DESCRIPTION:                                                               *
  70. *   Update one normal of one vertex by a convex blend of normals of          *
  71. * boundary vertices.                                 *
  72. *                                                                            *
  73. * PARAMETERS:                                                                *
  74. *   VUpdate:      Vertex to update normal for.                               *
  75. *   OriginalPl:   Using a convex blend of normals from the original polygon. *
  76. *                                                                            *
  77. * RETURN VALUE:                                                              *
  78. *   void                                                                     *
  79. *****************************************************************************/
  80. static void UpdateOneVertexNormal(IPVertexStruct *VUpdate,
  81.                   IPPolygonStruct *OriginalPl)
  82. {
  83.     IPVertexStruct *V,
  84.     *OriginalVList = OriginalPl -> PVertex;
  85.  
  86.     V = OriginalVList;
  87.     do {
  88.     if (Colinear3Vertices(V, VUpdate, V -> Pnext)) {
  89.         /* Interpolate the normal according to the edge vertices VUpdate */
  90.         /* is on and according to the distance of VUpdate to edge ends.  */
  91.         InterpNrmlBetweenTwo(VUpdate, V, V -> Pnext);
  92.         return;
  93.     }
  94.     V = V -> Pnext;
  95.     }
  96.     while (V != NULL && V != OriginalVList);
  97.  
  98.     /* If we are here then the point is not on the polygon boundary and in   */
  99.     /* that case we simply use the polygon normal as an approximation.       */
  100.     PT_COPY(VUpdate -> Normal, OriginalPl -> Plane);
  101. }
  102.  
  103. /*****************************************************************************
  104. * DESCRIPTION:                                                               M
  105. * Verify the colinearity of the given three vertices.                        M
  106. *                                                                            *
  107. * PARAMETERS:                                                                M
  108. *   V1, V2, V3: Vertices to test for colinearity.                            M
  109. *                                                                            *
  110. * RETURN VALUE:                                                              M
  111. *   int:        TRUE if colinear, FALSE otherwise.                           M
  112. *                                                                            *
  113. * KEYWORDS:                                                                  M
  114. *   Colinear3Vertices, colinearity                                           M
  115. *****************************************************************************/
  116. int Colinear3Vertices(IPVertexStruct *V1,
  117.               IPVertexStruct *V2,
  118.               IPVertexStruct *V3)
  119. {
  120.     RealType l;
  121.     VectorType V12, V23, V;
  122.  
  123.     if (PT_APX_EQ(V1 -> Coord, V2 -> Coord) ||
  124.     PT_APX_EQ(V2 -> Coord, V3 -> Coord))
  125.     return TRUE;
  126.  
  127.     PT_SUB(V12, V1 -> Coord, V2 -> Coord);
  128.     PT_SUB(V23, V2 -> Coord, V3 -> Coord);
  129.  
  130.     /* Make sure the middle point is in fact in the middle. */
  131.     if (V12[0] * V23[0] < -IRIT_EPSILON ||
  132.         V12[1] * V23[1] < -IRIT_EPSILON ||
  133.     V12[2] * V23[2] < -IRIT_EPSILON)
  134.     return FALSE;
  135.  
  136.     GMVecCrossProd(V, V12, V23);
  137.  
  138.     l = PT_LENGTH(V);
  139.  
  140.     return APX_EQ(l, 0.0);
  141. }
  142.  
  143. /*****************************************************************************
  144. * DESCRIPTION:                                                               M
  145. *   Update Normal of the middle vertex V, assumed to be between V1 and V2.   M
  146. *                                                                            *
  147. * PARAMETERS:                                                                M
  148. *   V:          Vertex that its normal is to be updated.                     M
  149. *   V1, V2:     Edge V is assumed to be on so that the two normals of V1     M
  150. *               and V2 can be blended to form the normal of V.               M
  151. *                                                                            *
  152. * RETURN VALUE:                                                              M
  153. *   void                                                                     M
  154. *                                                                            *
  155. * KEYWORDS:                                                                  M
  156. *   InterpNrmlBetweenTwo, normals                                            M
  157. *****************************************************************************/
  158. void InterpNrmlBetweenTwo(IPVertexStruct *V,
  159.               IPVertexStruct *V1,
  160.               IPVertexStruct *V2)
  161. {
  162.     RealType t1, t2;
  163.     VectorType Vec1, Vec2;
  164.  
  165.     PT_SUB(Vec1, V -> Coord, V1 -> Coord);
  166.     PT_SUB(Vec2, V -> Coord, V2 -> Coord);
  167.     t1 = PT_LENGTH(Vec1);
  168.     t2 = PT_LENGTH(Vec2);
  169.  
  170.     PT_COPY(Vec1, V1 -> Normal);
  171.     PT_COPY(Vec2, V2 -> Normal);
  172.     PT_SCALE(Vec1, t2);
  173.     PT_SCALE(Vec2, t1);
  174.     PT_ADD(V -> Normal, Vec1, Vec2);
  175.  
  176.     PT_NORMALIZE(V -> Normal);
  177. }
  178.  
  179. /*****************************************************************************
  180. * DESCRIPTION:                                                               M
  181. *   Update normal of the middle vertex V, assumed to be between V1 and V2.   M
  182. *                                                                            *
  183. * PARAMETERS:                                                                M
  184. *   Pt:         Middle position at which a normal is to be ucomputed.        M
  185. *   Normal:     Where resulting vector is to be placed.                      M
  186. *   V1, V2:     Edge V is assumed to be on so that the two normals of V1     M
  187. *               and V2 can be blended to form the normal of V.               M
  188. *                                                                            *
  189. * RETURN VALUE:                                                              M
  190. *   void                                                                     M
  191. *                                                                            *
  192. * KEYWORDS:                                                                  M
  193. *   InterpNrmlBetweenTwo2, normals                                           M
  194. *****************************************************************************/
  195. void InterpNrmlBetweenTwo2(PointType Pt,
  196.                VectorType Normal,
  197.                IPVertexStruct *V1,
  198.                IPVertexStruct *V2)
  199. {
  200.     RealType t1, t2;
  201.     VectorType Vec1, Vec2;
  202.  
  203.     PT_SUB(Vec1, Pt, V1 -> Coord);
  204.     PT_SUB(Vec2, Pt, V2 -> Coord);
  205.     t1 = PT_LENGTH(Vec1);
  206.     t2 = PT_LENGTH(Vec2);
  207.  
  208.     PT_COPY(Vec1, V1 -> Normal);
  209.     PT_COPY(Vec2, V2 -> Normal);
  210.     PT_SCALE(Vec1, t2);
  211.     PT_SCALE(Vec2, t1);
  212.     PT_ADD(Normal, Vec1, Vec2);
  213.  
  214.     PT_NORMALIZE(Normal);
  215. }
  216.  
  217. #ifdef DEBUG1 
  218.  
  219. /*****************************************************************************
  220. * DESCRIPTION:                                                               *
  221. * Prints the content of the given polygon, to standard output.             *
  222. *                                                                            *
  223. * PARAMETERS:                                                                *
  224. *   Pl:         Polygon to print to stdout.                                  *
  225. *                                                                            *
  226. * RETURN VALUE:                                                              *
  227. *   void                                                                     *
  228. *****************************************************************************/
  229. static void PrintPolygon(IPPolygonStruct *Pl)
  230. {
  231.     IPVertexStruct *V = Pl -> Coord,
  232.          *VHead = V;
  233.  
  234.     do {
  235.     printf("    %10lg %10lg %10lg (%10lg %10lg %10lg)",
  236.            V -> Coord[0], V -> Coord[1], V -> Coord[2],
  237.            V -> Normal[0], V -> Normal[1], V -> Normal[2]);
  238.     if (IS_INTERNAL_EDGE(V))
  239.         printf(" (Internal)\n");
  240.     else
  241.         printf("\n");
  242.     V = V -> Pnext;
  243.     }
  244.     while (V!= NULL && V != VHead);
  245. }
  246.  
  247. #endif /* DEBUG1 */
  248.