PostGIS  3.3.9dev-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 2314 of file lwgeom_topo.c.

2317 {
2318  LWT_ISO_EDGE newedge;
2319  LWGEOM *cleangeom;
2320  edgeend span; /* start point analisys */
2321  edgeend epan; /* end point analisys */
2322  POINT2D p1, pn, p2;
2323  POINTARRAY *pa;
2324  LWT_ELEMID node_ids[2];
2325  const LWPOINT *start_node_geom = NULL;
2326  const LWPOINT *end_node_geom = NULL;
2327  uint64_t num_nodes;
2328  LWT_ISO_NODE *endpoints;
2329  uint64_t i;
2330  int prev_left;
2331  int prev_right;
2332  LWT_ISO_EDGE seledge;
2333  LWT_ISO_EDGE updedge;
2334 
2335  if ( ! skipChecks )
2336  {
2337  /* curve must be simple */
2338  if ( ! lwgeom_is_simple(lwline_as_lwgeom(geom)) )
2339  {
2340  lwerror("SQL/MM Spatial exception - curve not simple");
2341  return -1;
2342  }
2343  }
2344 
2345  newedge.start_node = start_node;
2346  newedge.end_node = end_node;
2347  newedge.geom = geom;
2348  newedge.face_left = -1;
2349  newedge.face_right = -1;
2350  /* TODO: should do the repeated points removal in 2D space */
2351  cleangeom = lwgeom_remove_repeated_points( lwline_as_lwgeom(geom), 0 );
2352 
2353  pa = lwgeom_as_lwline(cleangeom)->points;
2354  if ( pa->npoints < 2 ) {
2355  lwgeom_free(cleangeom);
2356  lwerror("Invalid edge (no two distinct vertices exist)");
2357  return -1;
2358  }
2359 
2360  /* Initialize endpoint info (some of that ) */
2361  span.cwFace = span.ccwFace =
2362  epan.cwFace = epan.ccwFace = -1;
2363 
2364  /* Compute azimuth of first edge end on start node */
2365  getPoint2d_p(pa, 0, &p1);
2366  if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &pn) )
2367  {
2368  lwgeom_free(cleangeom);
2369  lwerror("Invalid edge (no two distinct vertices exist)");
2370  return -1;
2371  }
2372  if ( ! azimuth_pt_pt(&p1, &pn, &span.myaz) ) {
2373  lwgeom_free(cleangeom);
2374  lwerror("error computing azimuth of first edgeend [%.15g %.15g,%.15g %.15g]",
2375  p1.x, p1.y, pn.x, pn.y);
2376  return -1;
2377  }
2378  LWDEBUGF(1, "edge's start node is %g,%g", p1.x, p1.y);
2379 
2380  /* Compute azimuth of last edge end on end node */
2381  getPoint2d_p(pa, pa->npoints-1, &p2);
2382  if ( ! _lwt_FirstDistinctVertex2D(pa, &p2, pa->npoints-1, -1, &pn) )
2383  {
2384  lwgeom_free(cleangeom);
2385  /* This should never happen as we checked the edge while computing first edgend */
2386  lwerror("Invalid clean edge (no two distinct vertices exist) - should not happen");
2387  return -1;
2388  }
2389  lwgeom_free(cleangeom);
2390  if ( ! azimuth_pt_pt(&p2, &pn, &epan.myaz) ) {
2391  lwerror("error computing azimuth of last edgeend [%.15g %.15g,%.15g %.15g]",
2392  p2.x, p2.y, pn.x, pn.y);
2393  return -1;
2394  }
2395  LWDEBUGF(1, "edge's end node is %g,%g", p2.x, p2.y);
2396 
2397  /*
2398  * Check endpoints existence, match with Curve geometry
2399  * and get face information (if any)
2400  */
2401 
2402  if ( start_node != end_node ) {
2403  num_nodes = 2;
2404  node_ids[0] = start_node;
2405  node_ids[1] = end_node;
2406  } else {
2407  num_nodes = 1;
2408  node_ids[0] = start_node;
2409  }
2410 
2411  endpoints = lwt_be_getNodeById( topo, node_ids, &num_nodes, LWT_COL_NODE_ALL );
2412  if (num_nodes == UINT64_MAX)
2413  {
2414  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2415  return -1;
2416  }
2417  for ( i=0; i<num_nodes; ++i )
2418  {
2419  LWT_ISO_NODE* node = &(endpoints[i]);
2420  if ( modFace != -1 && node->containing_face != -1 )
2421  {
2422  if ( newedge.face_left == -1 )
2423  {
2424  newedge.face_left = newedge.face_right = node->containing_face;
2425  }
2426  else if ( newedge.face_left != node->containing_face )
2427  {
2428  _lwt_release_nodes(endpoints, num_nodes);
2429  lwerror("SQL/MM Spatial exception - geometry crosses an edge"
2430  " (endnodes in faces %" LWTFMT_ELEMID " and %" LWTFMT_ELEMID ")",
2431  newedge.face_left, node->containing_face);
2432  }
2433  }
2434 
2435  LWDEBUGF(1, "Node %d, with geom %p (looking for %d and %d)",
2436  node->node_id, node->geom, start_node, end_node);
2437  if ( node->node_id == start_node ) {
2438  start_node_geom = node->geom;
2439  }
2440  if ( node->node_id == end_node ) {
2441  end_node_geom = node->geom;
2442  }
2443  }
2444 
2445  if ( ! skipChecks )
2446  {
2447  if ( ! start_node_geom )
2448  {
2449  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2450  lwerror("SQL/MM Spatial exception - non-existent node");
2451  return -1;
2452  }
2453  else
2454  {
2455  pa = start_node_geom->point;
2456  getPoint2d_p(pa, 0, &pn);
2457  if ( ! P2D_SAME_STRICT(&pn, &p1) )
2458  {
2459  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2460  lwerror("SQL/MM Spatial exception"
2461  " - start node not geometry start point."
2462  //" - start node not geometry start point (%g,%g != %g,%g).", pn.x, pn.y, p1.x, p1.y
2463  );
2464  return -1;
2465  }
2466  }
2467 
2468  if ( ! end_node_geom )
2469  {
2470  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2471  lwerror("SQL/MM Spatial exception - non-existent node");
2472  return -1;
2473  }
2474  else
2475  {
2476  pa = end_node_geom->point;
2477  getPoint2d_p(pa, 0, &pn);
2478  if ( ! P2D_SAME_STRICT(&pn, &p2) )
2479  {
2480  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2481  lwerror("SQL/MM Spatial exception"
2482  " - end node not geometry end point."
2483  //" - end node not geometry end point (%g,%g != %g,%g).", pn.x, pn.y, p2.x, p2.y
2484  );
2485  return -1;
2486  }
2487  }
2488 
2489  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2490 
2491  if ( _lwt_CheckEdgeCrossing( topo, start_node, end_node, geom, 0 ) )
2492  return -1;
2493 
2494  } /* ! skipChecks */
2495 
2496  /*
2497  * All checks passed, time to prepare the new edge
2498  */
2499 
2500  newedge.edge_id = lwt_be_getNextEdgeId( topo );
2501  if ( newedge.edge_id == -1 ) {
2502  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2503  return -1;
2504  }
2505 
2506  /* Find adjacent edges to each endpoint */
2507  int isclosed = start_node == end_node;
2508  int found;
2509  found = _lwt_FindAdjacentEdges( topo, start_node, &span,
2510  isclosed ? &epan : NULL, -1 );
2511  if ( found ) {
2512  span.was_isolated = 0;
2513  newedge.next_right = span.nextCW ? span.nextCW : -newedge.edge_id;
2514  prev_left = span.nextCCW ? -span.nextCCW : newedge.edge_id;
2515  LWDEBUGF(1, "New edge %d is connected on start node, "
2516  "next_right is %d, prev_left is %d",
2517  newedge.edge_id, newedge.next_right, prev_left);
2518  if ( modFace != -1 )
2519  {
2520  if ( newedge.face_right == -1 ) {
2521  newedge.face_right = span.cwFace;
2522  }
2523  if ( newedge.face_left == -1 ) {
2524  newedge.face_left = span.ccwFace;
2525  }
2526  }
2527  } else {
2528  span.was_isolated = 1;
2529  newedge.next_right = isclosed ? -newedge.edge_id : newedge.edge_id;
2530  prev_left = isclosed ? newedge.edge_id : -newedge.edge_id;
2531  LWDEBUGF(1, "New edge %d is isolated on start node, "
2532  "next_right is %d, prev_left is %d",
2533  newedge.edge_id, newedge.next_right, prev_left);
2534  }
2535 
2536  found = _lwt_FindAdjacentEdges( topo, end_node, &epan,
2537  isclosed ? &span : NULL, -1 );
2538  if ( found ) {
2539  epan.was_isolated = 0;
2540  newedge.next_left = epan.nextCW ? epan.nextCW : newedge.edge_id;
2541  prev_right = epan.nextCCW ? -epan.nextCCW : -newedge.edge_id;
2542  LWDEBUGF(1, "New edge %d is connected on end node, "
2543  "next_left is %d, prev_right is %d",
2544  newedge.edge_id, newedge.next_left, prev_right);
2545  if ( modFace != -1 )
2546  {
2547  if ( newedge.face_right == -1 ) {
2548  newedge.face_right = span.ccwFace;
2549  } else if ( newedge.face_right != epan.ccwFace ) {
2550  /* side-location conflict */
2551  lwerror("Side-location conflict: "
2552  "new edge starts in face"
2553  " %" LWTFMT_ELEMID " and ends in face"
2554  " %" LWTFMT_ELEMID,
2555  newedge.face_right, epan.ccwFace
2556  );
2557  return -1;
2558  }
2559  if ( newedge.face_left == -1 ) {
2560  newedge.face_left = span.cwFace;
2561  } else if ( newedge.face_left != epan.cwFace ) {
2562  /* side-location conflict */
2563  lwerror("Side-location conflict: "
2564  "new edge starts in face"
2565  " %" LWTFMT_ELEMID " and ends in face"
2566  " %" LWTFMT_ELEMID,
2567  newedge.face_left, epan.cwFace
2568  );
2569  return -1;
2570  }
2571  }
2572  } else {
2573  epan.was_isolated = 1;
2574  newedge.next_left = isclosed ? newedge.edge_id : -newedge.edge_id;
2575  prev_right = isclosed ? -newedge.edge_id : newedge.edge_id;
2576  LWDEBUGF(1, "New edge %d is isolated on end node, "
2577  "next_left is %d, prev_right is %d",
2578  newedge.edge_id, newedge.next_left, prev_right);
2579  }
2580 
2581  /*
2582  * If we don't have faces setup by now we must have encountered
2583  * a malformed topology (no containing_face on isolated nodes, no
2584  * left/right faces on adjacent edges or mismatching values)
2585  */
2586  if ( modFace > -1 )
2587  {
2588  if ( newedge.face_left != newedge.face_right )
2589  {
2590  lwerror("Left(%" LWTFMT_ELEMID ")/right(%" LWTFMT_ELEMID ")"
2591  " faces mismatch: invalid topology ?",
2592  newedge.face_left, newedge.face_right);
2593  return -1;
2594  }
2595  else if ( newedge.face_left == -1 )
2596  {
2597  lwerror("Could not derive edge face from linked primitives:"
2598  " invalid topology ?");
2599  return -1;
2600  }
2601  }
2602 
2603  /*
2604  * Insert the new edge, and update all linking
2605  */
2606 
2607  int ret = lwt_be_insertEdges(topo, &newedge, 1);
2608  if ( ret == -1 ) {
2609  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2610  return -1;
2611  } else if ( ret == 0 ) {
2612  lwerror("Insertion of split edge failed (no reason)");
2613  return -1;
2614  }
2615 
2616  int updfields;
2617 
2618  /* Link prev_left to us
2619  * (if it's not us already) */
2620  if ( llabs(prev_left) != newedge.edge_id )
2621  {
2622  if ( prev_left > 0 )
2623  {
2624  /* its next_left_edge is us */
2625  updfields = LWT_COL_EDGE_NEXT_LEFT;
2626  updedge.next_left = newedge.edge_id;
2627  seledge.edge_id = prev_left;
2628  }
2629  else
2630  {
2631  /* its next_right_edge is us */
2632  updfields = LWT_COL_EDGE_NEXT_RIGHT;
2633  updedge.next_right = newedge.edge_id;
2634  seledge.edge_id = -prev_left;
2635  }
2636 
2637  ret = lwt_be_updateEdges(topo,
2638  &seledge, LWT_COL_EDGE_EDGE_ID,
2639  &updedge, updfields,
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  /* Link prev_right to us
2648  * (if it's not us already) */
2649  if ( llabs(prev_right) != newedge.edge_id )
2650  {
2651  if ( prev_right > 0 )
2652  {
2653  /* its next_left_edge is -us */
2654  updfields = LWT_COL_EDGE_NEXT_LEFT;
2655  updedge.next_left = -newedge.edge_id;
2656  seledge.edge_id = prev_right;
2657  }
2658  else
2659  {
2660  /* its next_right_edge is -us */
2661  updfields = LWT_COL_EDGE_NEXT_RIGHT;
2662  updedge.next_right = -newedge.edge_id;
2663  seledge.edge_id = -prev_right;
2664  }
2665 
2666  ret = lwt_be_updateEdges(topo,
2667  &seledge, LWT_COL_EDGE_EDGE_ID,
2668  &updedge, updfields,
2669  NULL, 0);
2670  if ( ret == -1 ) {
2671  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2672  return -1;
2673  }
2674  }
2675 
2676  /* NOT IN THE SPECS...
2677  * set containing_face = null for start_node and end_node
2678  * if they where isolated
2679  *
2680  */
2681  LWT_ISO_NODE updnode, selnode;
2682  updnode.containing_face = -1;
2683  if ( span.was_isolated )
2684  {
2685  selnode.node_id = start_node;
2686  ret = lwt_be_updateNodes(topo,
2687  &selnode, LWT_COL_NODE_NODE_ID,
2688  &updnode, LWT_COL_NODE_CONTAINING_FACE,
2689  NULL, 0);
2690  if ( ret == -1 ) {
2691  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2692  return -1;
2693  }
2694  }
2695  if ( epan.was_isolated )
2696  {
2697  selnode.node_id = end_node;
2698  ret = lwt_be_updateNodes(topo,
2699  &selnode, LWT_COL_NODE_NODE_ID,
2700  &updnode, LWT_COL_NODE_CONTAINING_FACE,
2701  NULL, 0);
2702  if ( ret == -1 ) {
2703  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2704  return -1;
2705  }
2706  }
2707 
2708  /* Check face splitting, if required */
2709 
2710  if ( modFace > -1 ) {
2711 
2712  if ( ! isclosed && ( epan.was_isolated || span.was_isolated ) )
2713  {
2714  LWDEBUG(1, "New edge is dangling, so it cannot split any face");
2715  return newedge.edge_id; /* no split */
2716  }
2717 
2718  int newface1 = -1;
2719 
2720  /* IDEA: avoid building edge ring if input is closed, which means we
2721  * know in advance it splits a face */
2722 
2723  if ( ! modFace )
2724  {
2725  newface1 = _lwt_AddFaceSplit( topo, -newedge.edge_id, newedge.face_left, 0 );
2726  if ( newface1 == 0 ) {
2727  LWDEBUG(1, "New edge does not split any face");
2728  return newedge.edge_id; /* no split */
2729  }
2730  }
2731 
2732  int newface = _lwt_AddFaceSplit( topo, newedge.edge_id,
2733  newedge.face_left, 0 );
2734  if ( modFace )
2735  {
2736  if ( newface == 0 ) {
2737  LWDEBUG(1, "New edge does not split any face");
2738  return newedge.edge_id; /* no split */
2739  }
2740 
2741  if ( newface < 0 )
2742  {
2743  /* face on the left is the universe face */
2744  /* must be forming a maximal ring in universal face */
2745  newface = _lwt_AddFaceSplit( topo, -newedge.edge_id,
2746  newedge.face_left, 0 );
2747  if ( newface < 0 ) return newedge.edge_id; /* no split */
2748  }
2749  else
2750  {
2751  _lwt_AddFaceSplit( topo, -newedge.edge_id, newedge.face_left, 1 );
2752  }
2753  }
2754 
2755  /*
2756  * Update topogeometries, if needed
2757  */
2758  if ( newedge.face_left != 0 )
2759  {
2760  ret = lwt_be_updateTopoGeomFaceSplit(topo, newedge.face_left,
2761  newface, newface1);
2762  if ( ret == 0 ) {
2763  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2764  return -1;
2765  }
2766 
2767  if ( ! modFace )
2768  {
2769  /* drop old face from the face table */
2770  ret = lwt_be_deleteFacesById(topo, &(newedge.face_left), 1);
2771  if ( ret == -1 ) {
2772  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2773  return -1;
2774  }
2775  }
2776  }
2777 
2778  } // end of face split checking
2779 
2780  return newedge.edge_id;
2781 }
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:179
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:339
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition: measures.c:2509
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
int lwgeom_is_simple(const LWGEOM *lwgeom)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:343
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition: lwgeom.c:1471
#define P2D_SAME_STRICT(a, b)
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:119
static int lwt_be_deleteFacesById(const LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t numelems)
Definition: lwgeom_topo.c:202
static int _lwt_FirstDistinctVertex2D(const POINTARRAY *pa, POINT2D *ref, int from, int dir, POINT2D *op)
Definition: lwgeom_topo.c:1439
LWT_ELEMID lwt_be_getNextEdgeId(LWT_TOPOLOGY *topo)
Definition: lwgeom_topo.c:214
static int lwt_be_updateTopoGeomFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID split_face, LWT_ELEMID new_face1, LWT_ELEMID new_face2)
Definition: lwgeom_topo.c:329
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:611
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
Definition: lwgeom_topo.c:475
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:267
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, int myedge_id)
Definition: lwgeom_topo.c:1536
LWT_ISO_NODE * lwt_be_getNodeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
Definition: lwgeom_topo.c:155
static LWT_ELEMID _lwt_AddFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID sedge, LWT_ELEMID face, int mbr_only)
Definition: lwgeom_topo.c:1901
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, uint64_t numelems)
Definition: lwgeom_topo.c:261
#define LWTFMT_ELEMID
Definition: lwgeom_topo.c:43
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:279
POINTARRAY * points
Definition: liblwgeom.h:498
POINTARRAY * point
Definition: liblwgeom.h:486
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:405
double x
Definition: liblwgeom.h:405
uint32_t npoints
Definition: liblwgeom.h:442
double myaz
Definition: lwgeom_topo.c:1426
LWT_ELEMID nextCCW
Definition: lwgeom_topo.c:1422
LWT_ELEMID ccwFace
Definition: lwgeom_topo.c:1424
int was_isolated
Definition: lwgeom_topo.c:1425
LWT_ELEMID cwFace
Definition: lwgeom_topo.c:1420
LWT_ELEMID nextCW
Definition: lwgeom_topo.c:1418

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_STRICT, 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: