Пример #1
0
Файл: edge.c Проект: MicBosi/GTS
/**
 * gts_edges_merge:
 * @edges: a list of #GtsEdge.
 *
 * For each edge in @edges check if it is duplicated (as
 * returned by gts_edge_is_duplicate()). If it is replace it by its
 * duplicate, destroy it and remove it from the list.
 *
 * Returns: the updated @edges list.
 */
GList * gts_edges_merge (GList * edges)
{
    GList * i = edges;

    /* we want to control edge destruction */
    gts_allow_floating_edges = TRUE;
    while (i) {
        GtsEdge * e = i->data;
        GtsEdge * de = gts_edge_is_duplicate (e);
        if (de) {
            GList * next = i->next;
            edges = g_list_remove_link (edges, i);
            g_list_free_1 (i);
            i = next;
            gts_edge_replace (e, de);
            gts_object_destroy (GTS_OBJECT (e));
        }
        else
            i = i->next;
    }
    gts_allow_floating_edges = FALSE;;

    return edges;
}
Пример #2
0
void 
pygts_edge_cleanup(GtsSurface *s)
{
  GSList *edges = NULL;
  GSList *i, *ii, *cur, *parents=NULL;
  PygtsEdge *edge;
  GtsEdge *e, *duplicate;

  g_return_if_fail(s != NULL);

  /* build list of edges */
  gts_surface_foreach_edge(s, (GtsFunc)build_list, &edges);

  /* remove degenerate and duplicate edges.
     Note: we could use gts_edges_merge() to remove the duplicates and then
     remove the degenerate edges but it is more efficient to do everything 
     at once (and it's more pedagogical too ...) */

  /* We want to control manually the destruction of edges */
  gts_allow_floating_edges = TRUE;

  i = edges;
  while(i) {
    e = (GtsEdge*)i->data;
    if(GTS_SEGMENT(e)->v1 == GTS_SEGMENT(e)->v2) {
      /* edge is degenerate */
      if( !g_hash_table_lookup(obj_table,GTS_OBJECT(e)) ) {
	/* destroy e */
	gts_object_destroy(GTS_OBJECT(e));
      }
    }
    else {
      if((duplicate = gts_edge_is_duplicate(e))) {

	/* Detach and save any parent triangles */
	if( (edge = PYGTS_EDGE(g_hash_table_lookup(obj_table,GTS_OBJECT(e))))
	    !=NULL ) {
	  ii = e->triangles;
	  while(ii!=NULL) {
	    cur = ii;
	    ii = g_slist_next(ii);
	    if(PYGTS_IS_PARENT_TRIANGLE(cur->data)) {
	      e->triangles = g_slist_remove_link(e->triangles, cur);
	      parents = g_slist_prepend(parents,cur->data);
	      g_slist_free_1(cur);
	    }
	  } 
	}

	/* replace e with its duplicate */
	gts_edge_replace(e, duplicate);

	/* Reattach the parent segments */
	if( edge != NULL ) {
	  ii = parents;
	  while(ii!=NULL) {
	    e->triangles = g_slist_prepend(e->triangles, ii->data);
	    ii = g_slist_next(ii);
	  }
	  g_slist_free(parents);
	  parents = NULL;
	}

	if( !g_hash_table_lookup(obj_table,GTS_OBJECT(e)) ) {
	  /* destroy e */
	  gts_object_destroy(GTS_OBJECT (e));
	}
      }
    }
    i = g_slist_next(i);
  }
  
  /* don't forget to reset to default */
  gts_allow_floating_edges = FALSE;

  /* free list of edges */
  g_slist_free (edges);
}
Пример #3
0
static PyObject *
new_(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
  PyObject *o;
  PygtsObject *obj;
  guint alloc_gtsobj = TRUE;
  PyObject *o1_,*o2_,*o3_;
  GtsVertex *v1=NULL, *v2=NULL, *v3=NULL;
  GtsEdge *e1=NULL,*e2=NULL,*e3=NULL,*e;
  GtsSegment *s1,*s2,*s3;
  gboolean flag=FALSE;  /* Flag when the args are gts.Point objects */
  GtsFace *f;
  GtsTriangle *t;
  guint N;

  /* Parse the args */
  if(kwds) {
    o = PyDict_GetItemString(kwds,"alloc_gtsobj");
    if(o==Py_False) {
      alloc_gtsobj = FALSE;
    }
    if(o!=NULL) {
      PyDict_DelItemString(kwds, "alloc_gtsobj");
    }
  }
  if(kwds) {
    Py_INCREF(Py_False);
    PyDict_SetItemString(kwds,"alloc_gtsobj", Py_False);
  }

  /* Allocate the gtsobj (if needed) */
  if( alloc_gtsobj ) {

    /* Parse the args */
    if( (N = PyTuple_Size(args)) < 3 ) {
      PyErr_SetString(PyExc_TypeError,"expected three Edges or three Vertices");
      return NULL;
    }
    o1_ = PyTuple_GET_ITEM(args,0);
    o2_ = PyTuple_GET_ITEM(args,1);
    o3_ = PyTuple_GET_ITEM(args,2);

    /* Convert to PygtsObjects */
    if( pygts_edge_check(o1_) ) {
      e1 = PYGTS_EDGE_AS_GTS_EDGE(o1_);
    }
    else {
      if( pygts_vertex_check(o1_) ) {
	v1 = PYGTS_VERTEX_AS_GTS_VERTEX(o1_);
	flag = TRUE;
      }
    }

    if( pygts_edge_check(o2_) ) {
      e2 = PYGTS_EDGE_AS_GTS_EDGE(o2_);
    }
    else {
      if( pygts_vertex_check(o2_) ) {
	v2 = PYGTS_VERTEX_AS_GTS_VERTEX(o2_);
	flag = TRUE;
      }
    }

    if( pygts_edge_check(o3_) ) {
      e3 = PYGTS_EDGE_AS_GTS_EDGE(o3_);
    }
    else {
      if(pygts_vertex_check(o3_)) {
	v3 = PYGTS_VERTEX_AS_GTS_VERTEX(o3_);
	flag = TRUE;
      }
    }
    
    /* Check for three edges or three vertices */
    if( !((e1!=NULL && e2!=NULL && e3!=NULL) ||
	  (v1!=NULL && v2!=NULL && v3!=NULL)) ) {
      PyErr_SetString(PyExc_TypeError,
		      "three Edge or three Vertex objects expected");
      return NULL;
    }

    if(flag) {

      /* Create gts edges */
      if( (e1 = gts_edge_new(gts_edge_class(),v1,v2)) == NULL ) {
	PyErr_SetString(PyExc_MemoryError, "could not create Edge");
	return NULL;
      }
      if( (e2 = gts_edge_new(gts_edge_class(),v2,v3)) == NULL ) {
	PyErr_SetString(PyExc_MemoryError, "could not create Edge");
	gts_object_destroy(GTS_OBJECT(e1));
	return NULL;
      }
      if( (e3 = gts_edge_new(gts_edge_class(),v3,v1)) == NULL ) {
	PyErr_SetString(PyExc_MemoryError, "could not create Edge");
	gts_object_destroy(GTS_OBJECT(e1));
	gts_object_destroy(GTS_OBJECT(e2));
	return NULL;
      }
      
      /* Check for duplicates */
      if( (e = gts_edge_is_duplicate(e1)) != NULL ) {
	gts_object_destroy(GTS_OBJECT(e1));
	e1 = e;
      }
      if( (e = gts_edge_is_duplicate(e2)) != NULL ) {
	gts_object_destroy(GTS_OBJECT(e2));
	e2 = e;
      }
      if( (e = gts_edge_is_duplicate(e3)) != NULL ) {
	gts_object_destroy(GTS_OBJECT(e3));
	e3 = e;
      }
    }
  
    /* Check that edges connect */
    s1 = GTS_SEGMENT(e1);
    s2 = GTS_SEGMENT(e2);
    s3 = GTS_SEGMENT(e3);
    if( !((s1->v1==s3->v2 && s1->v2==s2->v1 && s2->v2==s3->v1) ||
	  (s1->v1==s3->v2 && s1->v2==s2->v2 && s2->v1==s3->v1) ||
	  (s1->v1==s3->v1 && s1->v2==s2->v1 && s2->v2==s3->v2) ||
	  (s1->v2==s3->v2 && s1->v1==s2->v1 && s2->v2==s3->v1) ||
	  (s1->v1==s3->v1 && s1->v2==s2->v2 && s2->v1==s3->v2) ||
	  (s1->v2==s3->v2 && s1->v1==s2->v2 && s2->v1==s3->v1) ||
	  (s1->v2==s3->v1 && s1->v1==s2->v1 && s2->v2==s3->v2) ||
	  (s1->v2==s3->v1 && s1->v1==s2->v2 && s2->v1==s3->v2)) ) {
      PyErr_SetString(PyExc_RuntimeError, "Edges in face must connect");
      if(!g_hash_table_lookup(obj_table,GTS_OBJECT(e1))) {
	gts_object_destroy(GTS_OBJECT(e1));
      }
      if(!g_hash_table_lookup(obj_table,GTS_OBJECT(e1))) {
	gts_object_destroy(GTS_OBJECT(e2));
      }
      if(!g_hash_table_lookup(obj_table,GTS_OBJECT(e1))) {
	gts_object_destroy(GTS_OBJECT(e3));
      }
      return NULL;
    }

    /* Create the GtsFace */
    if( (f = gts_face_new(gts_face_class(),e1,e2,e3)) == NULL )  {
      PyErr_SetString(PyExc_MemoryError, "could not create Face");
      if(!g_hash_table_lookup(obj_table,GTS_OBJECT(e1))) {
	gts_object_destroy(GTS_OBJECT(e1));
      }
      if(!g_hash_table_lookup(obj_table,GTS_OBJECT(e1))) {
	gts_object_destroy(GTS_OBJECT(e2));
      }
      if(!g_hash_table_lookup(obj_table,GTS_OBJECT(e1))) {
	gts_object_destroy(GTS_OBJECT(e3));
      }
      return NULL;
    }

    /* Check for duplicate */
    t = gts_triangle_is_duplicate(GTS_TRIANGLE(f));
    if( t != NULL ) {
      gts_object_destroy(GTS_OBJECT(f));
      if(!GTS_IS_FACE(t)) {
	PyErr_SetString(PyExc_TypeError, "expected a Face (internal error)");
      }
      f = GTS_FACE(t);
    }

    /* If corresponding PyObject found in object table, we are done */
    if( (obj=(PygtsObject*)g_hash_table_lookup(obj_table,GTS_OBJECT(f))) != NULL ) {
      Py_INCREF(obj);
      return (PyObject*)obj;
    }
  }
  
  /* Chain up */
  obj = PYGTS_OBJECT(PygtsTriangleType.tp_new(type,args,kwds));

  if( alloc_gtsobj ) {

    obj->gtsobj = GTS_OBJECT(f);

    /* Create the parent GtsSurface */
    if( (obj->gtsobj_parent = parent(GTS_FACE(obj->gtsobj))) == NULL ) {
      gts_object_destroy(obj->gtsobj);
      obj->gtsobj = NULL;
      return NULL;
    }

    pygts_object_register(PYGTS_OBJECT(obj));
  }

  return (PyObject*)obj;
}