PostGIS  3.0.6dev-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 2267 of file lwgeom_topo.c.

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

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: