PostGIS  2.2.8dev-r@@SVN_REVISION@@

◆ lwpsurface_is_closed()

int lwpsurface_is_closed ( const LWPSURFACE psurface)

Definition at line 86 of file lwpsurface.c.

References struct_psurface_arcs::ax, struct_psurface_arcs::ay, struct_psurface_arcs::az, struct_psurface_arcs::bx, struct_psurface_arcs::by, struct_psurface_arcs::bz, struct_psurface_arcs::cnt, struct_psurface_arcs::face, LWPSURFACE::flags, FLAGS_GET_Z, LWPSURFACE::geoms, getPoint4d_p(), lwalloc(), lwfree(), LWPSURFACE::ngeoms, POINTARRAY::npoints, LWPOLY::rings, POINT4D::x, POINT4D::y, and POINT4D::z.

Referenced by lwgeom_dimension(), and lwgeom_is_closed().

87 {
88  int i, j, k;
89  int narcs, carc;
90  int found;
91  psurface_arcs arcs;
92  POINT4D pa, pb;
93  LWPOLY *patch;
94 
95  /* If surface is not 3D, it's can't be closed */
96  if (!FLAGS_GET_Z(psurface->flags)) return 0;
97 
98  /* If surface is less than 4 faces hard to be closed too */
99  if (psurface->ngeoms < 4) return 0;
100 
101  /* Max theorical arcs number if no one is shared ... */
102  for (i=0, narcs=0 ; i < psurface->ngeoms ; i++)
103  {
104  patch = (LWPOLY *) psurface->geoms[i];
105  narcs += patch->rings[0]->npoints - 1;
106  }
107 
108  arcs = lwalloc(sizeof(struct struct_psurface_arcs) * narcs);
109  for (i=0, carc=0; i < psurface->ngeoms ; i++)
110  {
111 
112  patch = (LWPOLY *) psurface->geoms[i];
113  for (j=0; j < patch->rings[0]->npoints - 1; j++)
114  {
115 
116  getPoint4d_p(patch->rings[0], j, &pa);
117  getPoint4d_p(patch->rings[0], j+1, &pb);
118 
119  /* remove redundant points if any */
120  if (pa.x == pb.x && pa.y == pb.y && pa.z == pb.z) continue;
121 
122  /* Make sure to order the 'lower' point first */
123  if ( (pa.x > pb.x) ||
124  (pa.x == pb.x && pa.y > pb.y) ||
125  (pa.x == pb.x && pa.y == pb.y && pa.z > pb.z) )
126  {
127  pa = pb;
128  getPoint4d_p(patch->rings[0], j, &pb);
129  }
130 
131  for (found=0, k=0; k < carc ; k++)
132  {
133 
134  if ( ( arcs[k].ax == pa.x && arcs[k].ay == pa.y &&
135  arcs[k].az == pa.z && arcs[k].bx == pb.x &&
136  arcs[k].by == pb.y && arcs[k].bz == pb.z &&
137  arcs[k].face != i) )
138  {
139  arcs[k].cnt++;
140  found = 1;
141 
142  /* Look like an invalid PolyhedralSurface
143  anyway not a closed one */
144  if (arcs[k].cnt > 2)
145  {
146  lwfree(arcs);
147  return 0;
148  }
149  }
150  }
151 
152  if (!found)
153  {
154  arcs[carc].cnt=1;
155  arcs[carc].face=i;
156  arcs[carc].ax = pa.x;
157  arcs[carc].ay = pa.y;
158  arcs[carc].az = pa.z;
159  arcs[carc].bx = pb.x;
160  arcs[carc].by = pb.y;
161  arcs[carc].bz = pb.z;
162  carc++;
163 
164  /* Look like an invalid PolyhedralSurface
165  anyway not a closed one */
166  if (carc > narcs)
167  {
168  lwfree(arcs);
169  return 0;
170  }
171  }
172  }
173  }
174 
175  /* A polyhedron is closed if each edge
176  is shared by exactly 2 faces */
177  for (k=0; k < carc ; k++)
178  {
179  if (arcs[k].cnt != 2)
180  {
181  lwfree(arcs);
182  return 0;
183  }
184  }
185  lwfree(arcs);
186 
187  /* Invalid Polyhedral case */
188  if (carc < psurface->ngeoms) return 0;
189 
190  return 1;
191 }
double x
Definition: liblwgeom.h:336
uint8_t flags
Definition: liblwgeom.h:553
void lwfree(void *mem)
Definition: lwutil.c:214
int npoints
Definition: liblwgeom.h:355
LWPOLY ** geoms
Definition: liblwgeom.h:558
POINTARRAY ** rings
Definition: liblwgeom.h:441
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:124
double z
Definition: liblwgeom.h:336
void * lwalloc(size_t size)
Definition: lwutil.c:199
double y
Definition: liblwgeom.h:336
int ngeoms
Definition: liblwgeom.h:556
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:231
Here is the call graph for this function:
Here is the caller graph for this function: