PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ _lwt_AddEdge()

static LWT_ELEMID _lwt_AddEdge ( LWT_TOPOLOGY topo,
LWT_ELEMID  start_node,
LWT_ELEMID  end_node,
LWLINE geom,
int  skipChecks,
int  modFace 
)
static
Parameters
modFacecan be 0 - have two new faces replace a splitted face 1 - modify a splitted face, adding a new one -1 - do not check at all for face splitting

Definition at line 2263 of file lwgeom_topo.c.

2266 {
2267  LWT_ISO_EDGE newedge;
2268  LWGEOM *cleangeom;
2269  edgeend span; /* start point analisys */
2270  edgeend epan; /* end point analisys */
2271  POINT2D p1, pn, p2;
2272  POINTARRAY *pa;
2273  LWT_ELEMID node_ids[2];
2274  const LWPOINT *start_node_geom = NULL;
2275  const LWPOINT *end_node_geom = NULL;
2276  int num_nodes;
2277  LWT_ISO_NODE *endpoints;
2278  int i;
2279  int prev_left;
2280  int prev_right;
2281  LWT_ISO_EDGE seledge;
2282  LWT_ISO_EDGE updedge;
2283 
2284  if ( ! skipChecks )
2285  {
2286  /* curve must be simple */
2287  if ( ! lwgeom_is_simple(lwline_as_lwgeom(geom)) )
2288  {
2289  lwerror("SQL/MM Spatial exception - curve not simple");
2290  return -1;
2291  }
2292  }
2293 
2294  newedge.start_node = start_node;
2295  newedge.end_node = end_node;
2296  newedge.geom = geom;
2297  newedge.face_left = -1;
2298  newedge.face_right = -1;
2299  /* TODO: should do the repeated points removal in 2D space */
2300  cleangeom = lwgeom_remove_repeated_points( lwline_as_lwgeom(geom), 0 );
2301 
2302  pa = lwgeom_as_lwline(cleangeom)->points;
2303  if ( pa->npoints < 2 ) {
2304  lwgeom_free(cleangeom);
2305  lwerror("Invalid edge (no two distinct vertices exist)");
2306  return -1;
2307  }
2308 
2309  /* Initialize endpoint info (some of that ) */
2310  span.cwFace = span.ccwFace =
2311  epan.cwFace = epan.ccwFace = -1;
2312 
2313  /* Compute azimuth of first edge end on start node */
2314  getPoint2d_p(pa, 0, &p1);
2315  if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &pn) )
2316  {
2317  lwgeom_free(cleangeom);
2318  lwerror("Invalid edge (no two distinct vertices exist)");
2319  return -1;
2320  }
2321  if ( ! azimuth_pt_pt(&p1, &pn, &span.myaz) ) {
2322  lwgeom_free(cleangeom);
2323  lwerror("error computing azimuth of first edgeend [%.15g %.15g,%.15g %.15g]",
2324  p1.x, p1.y, pn.x, pn.y);
2325  return -1;
2326  }
2327  LWDEBUGF(1, "edge's start node is %g,%g", p1.x, p1.y);
2328 
2329  /* Compute azimuth of last edge end on end node */
2330  getPoint2d_p(pa, pa->npoints-1, &p2);
2331  if ( ! _lwt_FirstDistinctVertex2D(pa, &p2, pa->npoints-1, -1, &pn) )
2332  {
2333  lwgeom_free(cleangeom);
2334  /* This should never happen as we checked the edge while computing first edgend */
2335  lwerror("Invalid clean edge (no two distinct vertices exist) - should not happen");
2336  return -1;
2337  }
2338  lwgeom_free(cleangeom);
2339  if ( ! azimuth_pt_pt(&p2, &pn, &epan.myaz) ) {
2340  lwerror("error computing azimuth of last edgeend [%.15g %.15g,%.15g %.15g]",
2341  p2.x, p2.y, pn.x, pn.y);
2342  return -1;
2343  }
2344  LWDEBUGF(1, "edge's end node is %g,%g", p2.x, p2.y);
2345 
2346  /*
2347  * Check endpoints existence, match with Curve geometry
2348  * and get face information (if any)
2349  */
2350 
2351  if ( start_node != end_node ) {
2352  num_nodes = 2;
2353  node_ids[0] = start_node;
2354  node_ids[1] = end_node;
2355  } else {
2356  num_nodes = 1;
2357  node_ids[0] = start_node;
2358  }
2359 
2360  endpoints = lwt_be_getNodeById( topo, node_ids, &num_nodes, LWT_COL_NODE_ALL );
2361  if ( num_nodes < 0 ) {
2362  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2363  return -1;
2364  }
2365  for ( i=0; i<num_nodes; ++i )
2366  {
2367  LWT_ISO_NODE* node = &(endpoints[i]);
2368  if ( node->containing_face != -1 )
2369  {
2370  if ( newedge.face_left == -1 )
2371  {
2372  newedge.face_left = newedge.face_right = node->containing_face;
2373  }
2374  else if ( newedge.face_left != node->containing_face )
2375  {
2376  _lwt_release_nodes(endpoints, num_nodes);
2377  lwerror("SQL/MM Spatial exception - geometry crosses an edge"
2378  " (endnodes in faces %" LWTFMT_ELEMID " and %" LWTFMT_ELEMID ")",
2379  newedge.face_left, node->containing_face);
2380  }
2381  }
2382 
2383  LWDEBUGF(1, "Node %d, with geom %p (looking for %d and %d)",
2384  node->node_id, node->geom, start_node, end_node);
2385  if ( node->node_id == start_node ) {
2386  start_node_geom = node->geom;
2387  }
2388  if ( node->node_id == end_node ) {
2389  end_node_geom = node->geom;
2390  }
2391  }
2392 
2393  if ( ! skipChecks )
2394  {
2395  if ( ! start_node_geom )
2396  {
2397  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2398  lwerror("SQL/MM Spatial exception - non-existent node");
2399  return -1;
2400  }
2401  else
2402  {
2403  pa = start_node_geom->point;
2404  getPoint2d_p(pa, 0, &pn);
2405  if ( ! p2d_same(&pn, &p1) )
2406  {
2407  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2408  lwerror("SQL/MM Spatial exception"
2409  " - start node not geometry start point."
2410  //" - start node not geometry start point (%g,%g != %g,%g).", pn.x, pn.y, p1.x, p1.y
2411  );
2412  return -1;
2413  }
2414  }
2415 
2416  if ( ! end_node_geom )
2417  {
2418  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2419  lwerror("SQL/MM Spatial exception - non-existent node");
2420  return -1;
2421  }
2422  else
2423  {
2424  pa = end_node_geom->point;
2425  getPoint2d_p(pa, 0, &pn);
2426  if ( ! p2d_same(&pn, &p2) )
2427  {
2428  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2429  lwerror("SQL/MM Spatial exception"
2430  " - end node not geometry end point."
2431  //" - end node not geometry end point (%g,%g != %g,%g).", pn.x, pn.y, p2.x, p2.y
2432  );
2433  return -1;
2434  }
2435  }
2436 
2437  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2438 
2439  if ( _lwt_CheckEdgeCrossing( topo, start_node, end_node, geom, 0 ) )
2440  return -1;
2441 
2442  } /* ! skipChecks */
2443 
2444  /*
2445  * All checks passed, time to prepare the new edge
2446  */
2447 
2448  newedge.edge_id = lwt_be_getNextEdgeId( topo );
2449  if ( newedge.edge_id == -1 ) {
2450  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2451  return -1;
2452  }
2453 
2454  /* Find adjacent edges to each endpoint */
2455  int isclosed = start_node == end_node;
2456  int found;
2457  found = _lwt_FindAdjacentEdges( topo, start_node, &span,
2458  isclosed ? &epan : NULL, -1 );
2459  if ( found ) {
2460  span.was_isolated = 0;
2461  newedge.next_right = span.nextCW ? span.nextCW : -newedge.edge_id;
2462  prev_left = span.nextCCW ? -span.nextCCW : newedge.edge_id;
2463  LWDEBUGF(1, "New edge %d is connected on start node, "
2464  "next_right is %d, prev_left is %d",
2465  newedge.edge_id, newedge.next_right, prev_left);
2466  if ( newedge.face_right == -1 ) {
2467  newedge.face_right = span.cwFace;
2468  }
2469  if ( newedge.face_left == -1 ) {
2470  newedge.face_left = span.ccwFace;
2471  }
2472  } else {
2473  span.was_isolated = 1;
2474  newedge.next_right = isclosed ? -newedge.edge_id : newedge.edge_id;
2475  prev_left = isclosed ? newedge.edge_id : -newedge.edge_id;
2476  LWDEBUGF(1, "New edge %d is isolated on start node, "
2477  "next_right is %d, prev_left is %d",
2478  newedge.edge_id, newedge.next_right, prev_left);
2479  }
2480 
2481  found = _lwt_FindAdjacentEdges( topo, end_node, &epan,
2482  isclosed ? &span : NULL, -1 );
2483  if ( found ) {
2484  epan.was_isolated = 0;
2485  newedge.next_left = epan.nextCW ? epan.nextCW : newedge.edge_id;
2486  prev_right = epan.nextCCW ? -epan.nextCCW : -newedge.edge_id;
2487  LWDEBUGF(1, "New edge %d is connected on end node, "
2488  "next_left is %d, prev_right is %d",
2489  newedge.edge_id, newedge.next_left, prev_right);
2490  if ( newedge.face_right == -1 ) {
2491  newedge.face_right = span.ccwFace;
2492  } else if ( modFace != -1 && newedge.face_right != epan.ccwFace ) {
2493  /* side-location conflict */
2494  lwerror("Side-location conflict: "
2495  "new edge starts in face"
2496  " %" LWTFMT_ELEMID " and ends in face"
2497  " %" LWTFMT_ELEMID,
2498  newedge.face_right, epan.ccwFace
2499  );
2500  return -1;
2501  }
2502  if ( newedge.face_left == -1 ) {
2503  newedge.face_left = span.cwFace;
2504  } else if ( modFace != -1 && newedge.face_left != epan.cwFace ) {
2505  /* side-location conflict */
2506  lwerror("Side-location conflict: "
2507  "new edge starts in face"
2508  " %" LWTFMT_ELEMID " and ends in face"
2509  " %" LWTFMT_ELEMID,
2510  newedge.face_left, epan.cwFace
2511  );
2512  return -1;
2513  }
2514  } else {
2515  epan.was_isolated = 1;
2516  newedge.next_left = isclosed ? newedge.edge_id : -newedge.edge_id;
2517  prev_right = isclosed ? -newedge.edge_id : newedge.edge_id;
2518  LWDEBUGF(1, "New edge %d is isolated on end node, "
2519  "next_left is %d, prev_right is %d",
2520  newedge.edge_id, newedge.next_left, prev_right);
2521  }
2522 
2523  /*
2524  * If we don't have faces setup by now we must have encountered
2525  * a malformed topology (no containing_face on isolated nodes, no
2526  * left/right faces on adjacent edges or mismatching values)
2527  */
2528  if ( newedge.face_left != newedge.face_right )
2529  {
2530  lwerror("Left(%" LWTFMT_ELEMID ")/right(%" LWTFMT_ELEMID ")"
2531  "faces mismatch: invalid topology ?",
2532  newedge.face_left, newedge.face_right);
2533  return -1;
2534  }
2535  else if ( newedge.face_left == -1 && modFace > -1 )
2536  {
2537  lwerror("Could not derive edge face from linked primitives:"
2538  " invalid topology ?");
2539  return -1;
2540  }
2541 
2542  /*
2543  * Insert the new edge, and update all linking
2544  */
2545 
2546  int ret = lwt_be_insertEdges(topo, &newedge, 1);
2547  if ( ret == -1 ) {
2548  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2549  return -1;
2550  } else if ( ret == 0 ) {
2551  lwerror("Insertion of split edge failed (no reason)");
2552  return -1;
2553  }
2554 
2555  int updfields;
2556 
2557  /* Link prev_left to us
2558  * (if it's not us already) */
2559  if ( llabs(prev_left) != newedge.edge_id )
2560  {
2561  if ( prev_left > 0 )
2562  {
2563  /* its next_left_edge is us */
2564  updfields = LWT_COL_EDGE_NEXT_LEFT;
2565  updedge.next_left = newedge.edge_id;
2566  seledge.edge_id = prev_left;
2567  }
2568  else
2569  {
2570  /* its next_right_edge is us */
2571  updfields = LWT_COL_EDGE_NEXT_RIGHT;
2572  updedge.next_right = newedge.edge_id;
2573  seledge.edge_id = -prev_left;
2574  }
2575 
2576  ret = lwt_be_updateEdges(topo,
2577  &seledge, LWT_COL_EDGE_EDGE_ID,
2578  &updedge, updfields,
2579  NULL, 0);
2580  if ( ret == -1 ) {
2581  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2582  return -1;
2583  }
2584  }
2585 
2586  /* Link prev_right to us
2587  * (if it's not us already) */
2588  if ( llabs(prev_right) != newedge.edge_id )
2589  {
2590  if ( prev_right > 0 )
2591  {
2592  /* its next_left_edge is -us */
2593  updfields = LWT_COL_EDGE_NEXT_LEFT;
2594  updedge.next_left = -newedge.edge_id;
2595  seledge.edge_id = prev_right;
2596  }
2597  else
2598  {
2599  /* its next_right_edge is -us */
2600  updfields = LWT_COL_EDGE_NEXT_RIGHT;
2601  updedge.next_right = -newedge.edge_id;
2602  seledge.edge_id = -prev_right;
2603  }
2604 
2605  ret = lwt_be_updateEdges(topo,
2606  &seledge, LWT_COL_EDGE_EDGE_ID,
2607  &updedge, updfields,
2608  NULL, 0);
2609  if ( ret == -1 ) {
2610  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2611  return -1;
2612  }
2613  }
2614 
2615  /* NOT IN THE SPECS...
2616  * set containing_face = null for start_node and end_node
2617  * if they where isolated
2618  *
2619  */
2620  LWT_ISO_NODE updnode, selnode;
2621  updnode.containing_face = -1;
2622  if ( span.was_isolated )
2623  {
2624  selnode.node_id = start_node;
2625  ret = lwt_be_updateNodes(topo,
2626  &selnode, LWT_COL_NODE_NODE_ID,
2627  &updnode, LWT_COL_NODE_CONTAINING_FACE,
2628  NULL, 0);
2629  if ( ret == -1 ) {
2630  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2631  return -1;
2632  }
2633  }
2634  if ( epan.was_isolated )
2635  {
2636  selnode.node_id = end_node;
2637  ret = lwt_be_updateNodes(topo,
2638  &selnode, LWT_COL_NODE_NODE_ID,
2639  &updnode, LWT_COL_NODE_CONTAINING_FACE,
2640  NULL, 0);
2641  if ( ret == -1 ) {
2642  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2643  return -1;
2644  }
2645  }
2646 
2647  /* Check face splitting, if required */
2648 
2649  if ( modFace > -1 ) {
2650 
2651  if ( ! isclosed && ( epan.was_isolated || span.was_isolated ) )
2652  {
2653  LWDEBUG(1, "New edge is dangling, so it cannot split any face");
2654  return newedge.edge_id; /* no split */
2655  }
2656 
2657  int newface1 = -1;
2658 
2659  /* IDEA: avoid building edge ring if input is closed, which means we
2660  * know in advance it splits a face */
2661 
2662  if ( ! modFace )
2663  {
2664  newface1 = _lwt_AddFaceSplit( topo, -newedge.edge_id, newedge.face_left, 0 );
2665  if ( newface1 == 0 ) {
2666  LWDEBUG(1, "New edge does not split any face");
2667  return newedge.edge_id; /* no split */
2668  }
2669  }
2670 
2671  int newface = _lwt_AddFaceSplit( topo, newedge.edge_id,
2672  newedge.face_left, 0 );
2673  if ( modFace )
2674  {
2675  if ( newface == 0 ) {
2676  LWDEBUG(1, "New edge does not split any face");
2677  return newedge.edge_id; /* no split */
2678  }
2679 
2680  if ( newface < 0 )
2681  {
2682  /* face on the left is the universe face */
2683  /* must be forming a maximal ring in universal face */
2684  newface = _lwt_AddFaceSplit( topo, -newedge.edge_id,
2685  newedge.face_left, 0 );
2686  if ( newface < 0 ) return newedge.edge_id; /* no split */
2687  }
2688  else
2689  {
2690  _lwt_AddFaceSplit( topo, -newedge.edge_id, newedge.face_left, 1 );
2691  }
2692  }
2693 
2694  /*
2695  * Update topogeometries, if needed
2696  */
2697  if ( newedge.face_left != 0 )
2698  {
2699  ret = lwt_be_updateTopoGeomFaceSplit(topo, newedge.face_left,
2700  newface, newface1);
2701  if ( ret == 0 ) {
2702  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2703  return -1;
2704  }
2705 
2706  if ( ! modFace )
2707  {
2708  /* drop old face from the face table */
2709  ret = lwt_be_deleteFacesById(topo, &(newedge.face_left), 1);
2710  if ( ret == -1 ) {
2711  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2712  return -1;
2713  }
2714  }
2715  }
2716 
2717  } // end of face split checking
2718 
2719  return newedge.edge_id;
2720 }
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:170
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:330
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition: measures.c:2417
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
int lwgeom_is_simple(const LWGEOM *lwgeom)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:348
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition: lwgeom.c:1503
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:49
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_NEXT_RIGHT
#define LWT_COL_NODE_CONTAINING_FACE
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_NEXT_LEFT
#define LWT_COL_NODE_NODE_ID
Node fields.
#define LWT_COL_NODE_ALL
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
Definition: lwgeom_topo.c:120
LWT_ISO_NODE * lwt_be_getNodeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int *numelems, int fields)
Definition: lwgeom_topo.c:156
static int _lwt_FirstDistinctVertex2D(const POINTARRAY *pa, POINT2D *ref, int from, int dir, POINT2D *op)
Definition: lwgeom_topo.c:1395
LWT_ELEMID lwt_be_getNextEdgeId(LWT_TOPOLOGY *topo)
Definition: lwgeom_topo.c:219
static int lwt_be_updateTopoGeomFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID split_face, LWT_ELEMID new_face1, LWT_ELEMID new_face2)
Definition: lwgeom_topo.c:343
static int _lwt_CheckEdgeCrossing(LWT_TOPOLOGY *topo, LWT_ELEMID start_node, LWT_ELEMID end_node, const LWLINE *geom, LWT_ELEMID myself)
Definition: lwgeom_topo.c:601
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
Definition: lwgeom_topo.c:467
int lwt_be_updateEdges(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *sel_edge, int sel_fields, const LWT_ISO_EDGE *upd_edge, int upd_fields, const LWT_ISO_EDGE *exc_edge, int exc_fields)
Definition: lwgeom_topo.c:274
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, int myedge_id)
Definition: lwgeom_topo.c:1492
static LWT_ELEMID _lwt_AddFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID sedge, LWT_ELEMID face, int mbr_only)
Definition: lwgeom_topo.c:1856
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, int numelems)
Definition: lwgeom_topo.c:268
#define LWTFMT_ELEMID
Definition: lwgeom_topo.c:44
static int lwt_be_deleteFacesById(const LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, int numelems)
Definition: lwgeom_topo.c:207
static int lwt_be_updateNodes(LWT_TOPOLOGY *topo, const LWT_ISO_NODE *sel_node, int sel_fields, const LWT_ISO_NODE *upd_node, int upd_fields, const LWT_ISO_NODE *exc_node, int exc_fields)
Definition: lwgeom_topo.c:286
POINTARRAY * points
Definition: liblwgeom.h:425
POINTARRAY * point
Definition: liblwgeom.h:414
LWT_ELEMID face_right
LWT_ELEMID next_right
LWT_ELEMID end_node
LWT_ELEMID face_left
LWLINE * geom
LWT_ELEMID next_left
LWT_ELEMID edge_id
LWT_ELEMID start_node
LWT_ELEMID node_id
LWT_ELEMID containing_face
LWPOINT * geom
const LWT_BE_IFACE * be_iface
double y
Definition: liblwgeom.h:331
double x
Definition: liblwgeom.h:331
uint32_t npoints
Definition: liblwgeom.h:374
double myaz
Definition: lwgeom_topo.c:1382
LWT_ELEMID nextCCW
Definition: lwgeom_topo.c:1378
LWT_ELEMID ccwFace
Definition: lwgeom_topo.c:1380
int was_isolated
Definition: lwgeom_topo.c:1381
LWT_ELEMID cwFace
Definition: lwgeom_topo.c:1376
LWT_ELEMID nextCW
Definition: lwgeom_topo.c:1374

References _lwt_AddFaceSplit(), _lwt_CheckEdgeCrossing(), _lwt_FindAdjacentEdges(), _lwt_FirstDistinctVertex2D(), _lwt_release_nodes(), azimuth_pt_pt(), LWT_TOPOLOGY_T::be_iface, edgeend_t::ccwFace, LWT_ISO_NODE::containing_face, edgeend_t::cwFace, LWT_ISO_EDGE::edge_id, LWT_ISO_EDGE::end_node, LWT_ISO_EDGE::face_left, LWT_ISO_EDGE::face_right, LWT_ISO_NODE::geom, LWT_ISO_EDGE::geom, getPoint2d_p(), LWDEBUG, LWDEBUGF, lwerror(), lwgeom_as_lwline(), lwgeom_free(), lwgeom_is_simple(), lwgeom_remove_repeated_points(), lwline_as_lwgeom(), lwt_be_deleteFacesById(), lwt_be_getNextEdgeId(), lwt_be_getNodeById(), lwt_be_insertEdges(), lwt_be_lastErrorMessage(), lwt_be_updateEdges(), lwt_be_updateNodes(), lwt_be_updateTopoGeomFaceSplit(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_NEXT_LEFT, LWT_COL_EDGE_NEXT_RIGHT, LWT_COL_NODE_ALL, LWT_COL_NODE_CONTAINING_FACE, LWT_COL_NODE_NODE_ID, LWTFMT_ELEMID, edgeend_t::myaz, LWT_ISO_EDGE::next_left, LWT_ISO_EDGE::next_right, edgeend_t::nextCCW, edgeend_t::nextCW, LWT_ISO_NODE::node_id, POINTARRAY::npoints, p2d_same(), LWPOINT::point, LWLINE::points, LWT_ISO_EDGE::start_node, edgeend_t::was_isolated, POINT2D::x, and POINT2D::y.

Referenced by _lwt_AddLineEdge(), lwt_AddEdgeModFace(), and lwt_AddEdgeNewFaces().

Here is the call graph for this function:
Here is the caller graph for this function: