Exemple #1
0
void cmp_tests() {
	int a = 1, b = 2;
	
	/* greater tests */
	gtl((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 0);
	gtl((char *)&b, (char *)&a); assert(*(int32_t *)ecx == 1);
	gel((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 0);
	gel((char *)&a, (char *)&a); assert(*(int32_t *)ecx == 1);
	gel((char *)&b, (char *)&a); assert(*(int32_t *)ecx == 1);

	/* less tests */
	ltl((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 1);
	ltl((char *)&b, (char *)&a); assert(*(int32_t *)ecx == 0);
	lel((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 1);
	lel((char *)&a, (char *)&a); assert(*(int32_t *)ecx == 1);
	lel((char *)&b, (char *)&a); assert(*(int32_t *)ecx == 0);

	/* (not) equal tests */
	eql((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 0);
	eql((char *)&b, (char *)&b); assert(*(int32_t *)ecx == 1);
	nel((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 1);
	nel((char *)&a, (char *)&a); assert(*(int32_t *)ecx == 0);

	/* and/or tests */
	a = 0, b = 1;
	andl((char *)&a, (char *)&a); assert(*(int32_t *)ecx == 0);
	andl((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 0);
	andl((char *)&b, (char *)&b); assert(*(int32_t *)ecx == 1);
	orl((char *)&a, (char *)&a); assert(*(int32_t *)ecx == 0);
	orl((char *)&a, (char *)&b); assert(*(int32_t *)ecx == 1);
	orl((char *)&b, (char *)&b); assert(*(int32_t *)ecx == 1);
}
Exemple #2
0
int
bug_a(MENU_ARGS)
{
  int i;

  cup(10, 1);
  println("This is a test of the VT100 'Scroll while toggle softscroll'");
  println("bug.  The cursor may disappear, or move UP the screen, or");
  println("multiple copies of some lines may appear.");
  holdit();

  /*  Invoke the bug  */

  esc("[24H");  /* Simplified cursor movement   */
  decsclm(FALSE);
  for (i = 1; i <= 20; i++)
    printf("\n");

  decsclm(TRUE);
  for (i = 1; i <= 10; i++)
    printf("\n");

  decsclm(FALSE);
  for (i = 1; i <= 5; i++)
    printf("\n");

  /* That should be enough to show the bug. But we'll try another way:  */
  decsclm(TRUE);  /* Set soft scroll              */
  nel();        /* "NextLine", move down        */
  decsclm(FALSE);   /* Reset soft scroll            */
  nel();        /* "NextLine", move down        */
  for (i = 1; i <= 10; i++) {   /* Show the bug                 */
    printf("Softscroll bug test, line %d.  ", i);
    holdit();
  }
  println("That should have been enough to show the bug, if present.");
  return MENU_HOLD;
}
Exemple #3
0
int
tst_movements(MENU_ARGS)
{
  /* Test of:
     CUF (Cursor Forward)
     CUB (Cursor Backward)
     CUD (Cursor Down)      IND (Index)  NEL (Next Line)
     CUU (Cursor Up)        RI  (Reverse Index)
     CUP (Cursor Position)  HVP (Horizontal and Vertical Position)
     ED  (Erase in Display)
     EL  (Erase in Line)
     DECALN (Screen Alignment Display)
     DECAWM (Autowrap)
     <CR> <BS>
     Cursor control characters inside CSI sequences
   */

  int i, row, col, pass, width, hlfxtra;
  const char *ctext = "This is a correct sentence";

  set_tty_crmod(TRUE);  /* want to disable tab/space conversion */

  for (pass = 0; pass <= 1; pass++) {
    int inner_l, inner_r;

    if (pass == 0) {
      deccolm(FALSE);
      width = min_cols;
    } else {
      deccolm(TRUE);
      width = max_cols;
    }

    /* Compute left/right columns for a 60-column box centered in 'width' */
    inner_l = (width - 60) / 2;
    inner_r = 61 + inner_l;
    hlfxtra = (width - 80) / 2;

    if (LOG_ENABLED)
      fprintf(log_fp, "tst_movements box(%d cols)\n", pass ? max_cols : min_cols);

    decaln();
    cup(9, inner_l);
    ed(1);
    cup(18, 60 + hlfxtra);
    ed(0);
    el(1);
    cup(9, inner_r);
    el(0);
    /* 132: 36..97 */
    /*  80: 10..71 */
    for (row = 10; row <= 16; row++) {
      cup(row, inner_l);
      el(1);
      cup(row, inner_r);
      el(0);
    }
    cup(17, 30);
    el(2);
    for (col = 1; col <= width; col++) {
      hvp(max_lines, col);
      printf("*");
      hvp(1, col);
      printf("*");
    }
    cup(2, 2);
    for (row = 2; row <= max_lines - 1; row++) {
      printf("+");
      cub(1);
      ind();
    }
    cup(max_lines - 1, width - 1);
    for (row = max_lines - 1; row >= 2; row--) {
      printf("+");
      cub(1);
      ri();
    }
    cup(2, 1);
    for (row = 2; row <= max_lines - 1; row++) {
      printf("*");
      cup(row, width);
      printf("*");
      cub(10);
      if (row < 10)
        nel();
      else
        printf("\n");
    }
    cup(2, 10);
    cub(42 + hlfxtra);
    cuf(2);
    for (col = 3; col <= width - 2; col++) {
      printf("+");
      cuf(0);
      cub(2);
      cuf(1);
    }
    cup(max_lines - 1, inner_r - 1);
    cuf(42 + hlfxtra);
    cub(2);
    for (col = width - 2; col >= 3; col--) {
      printf("+");
      cub(1);
      cuf(1);
      cub(0);
      printf("%c", 8);
    }
    cup(1, 1);
    cuu(10);
    cuu(1);
    cuu(0);
    cup(max_lines, width);
    cud(10);
    cud(1);
    cud(0);

    cup(10, 2 + inner_l);
    for (row = 10; row <= 15; row++) {
      for (col = 2 + inner_l; col <= inner_r - 2; col++)
        printf(" ");
      cud(1);
      cub(58);
    }
    cuu(5);
    cuf(1);
    printf("The screen should be cleared,  and have an unbroken bor-");
    cup(12, inner_l + 3);
    printf("der of *'s and +'s around the edge,   and exactly in the");
    cup(13, inner_l + 3);
    printf("middle  there should be a frame of E's around this  text");
    cup(14, inner_l + 3);
    printf("with  one (1) free position around it.    ");
    holdit();
  }
  deccolm(FALSE);

  /* DECAWM demo */
  for (pass = 0; pass <= 1; pass++) {
    static char on_left[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static char on_right[] = "abcdefghijklmnopqrstuvwxyz";
    int height = sizeof(on_left) - 1;
    int region = max_lines - 6;

    if (LOG_ENABLED)
      fprintf(log_fp, "tst_movements wrap(%d cols)\n", pass ? max_cols : min_cols);

    /* note: DECCOLM clears the screen */
    if (pass == 0) {
      deccolm(FALSE);
      width = min_cols;
    } else {
      deccolm(TRUE);
      width = max_cols;
    }

    println("Test of autowrap, mixing control and print characters.");
    println("The left/right margins should have letters in order:");

    decstbm(3, region + 3);
    decom(TRUE);  /* this also homes the cursor */
    for (i = 0; i < height; ++i) {
      switch (i % 4) {
      case 0:
        /* draw characters as-is, for reference */
        __(cup(region + 1, 1), printf("%c", on_left[i]));
        __(cup(region + 1, width), printf("%c", on_right[i]));
        printf("\n");
        break;
      case 1:
        /* simple wrapping */
        __(cup(region, width), printf("%c%c", on_right[i - 1], on_left[i]));
        /* backspace at right margin */
        __(cup(region + 1, width), printf("%c%c %c",
                                          on_left[i], BS, on_right[i]));
        printf("\n");
        break;
      case 2:
        /* tab to right margin */
        __(cup(region + 1, width), printf("%c%c%c%c%c%c",
                                          on_left[i], BS, BS,
                                          TAB, TAB, on_right[i]));
        __(cup(region + 1, 2), printf("%c%c\n", BS, on_left[i]));
        break;
      default:
        /* newline at right margin */
        __(cup(region + 1, width), printf("\n"));
        __(cup(region, 1), printf("%c", on_left[i]));
        __(cup(region, width), printf("%c", on_right[i]));
        break;
      }
    }
    decom(FALSE);
    decstbm(0, 0);
    cup(max_lines - 2, 1);
    holdit();
  }
  deccolm(FALSE);   /* 80 cols */

  if (LOG_ENABLED)
    fprintf(log_fp, "tst_movements cursor-controls in ESC sequences\n");

  vt_clear(2);
  vt_move(1, 1);
  println("Test of cursor-control characters inside ESC sequences.");
  println("Below should be four identical lines:");
  println("");
  println("A B C D E F G H I");
  for (i = 1; i < 10; i++) {
    printf("%c", '@' + i);
    do_csi("2%cC", BS);   /* Two forward, one backspace */
  }
  println("");
  /* Now put CR in CUF sequence. */
  printf("A ");
  for (i = 2; i < 10; i++)
    printf("%s%c%dC%c", csi_output(), CR, 2 * i - 2, '@' + i);
  println("");
  /* Now put VT in CUU sequence. */
  rm("20");
  for (i = 1; i < 10; i++) {
    printf("%c ", '@' + i);
    do_csi("1\013A");
  }
  println("");
  println("");
  holdit();

  if (LOG_ENABLED)
    fprintf(log_fp, "tst_movements leading zeros in ESC sequences\n");

  vt_clear(2);
  vt_move(1, 1);
  println("Test of leading zeros in ESC sequences.");
  printf("Two lines below you should see the sentence \"%s\".", ctext);
  for (col = 1; *ctext; col++)
    printf("%s00000000004;00000000%dH%c", csi_output(), col, *ctext++);
  cup(20, 1);

  restore_ttymodes();
  return MENU_HOLD;
}
  void MeshOptimize2d :: GenericImprove (Mesh & mesh)
  {
    if (!faceindex)
      {
	if (writestatus)
	  PrintMessage (3, "Generic Improve");

	for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
	  GenericImprove (mesh);
      
	faceindex = 0;
      }

    // int j, k, l, ri;
    int np = mesh.GetNP();
    int ne = mesh.GetNSE();
    //    SurfaceElementIndex sei;

    
//     for (SurfaceElementIndex sei = 0; sei < ne; sei++)
//       {
// 	const Element2d & el = mesh[sei];
// 	(*testout) << "element " << sei << ": " <<flush;
// 	for(int j=0; j<el.GetNP(); j++)
// 	  (*testout) << el[j] << " " << flush;
// 	(*testout) << "IsDeleted() " << el.IsDeleted()<< endl;
//       }

    bool ok;
    int olddef, newdef;

    ARRAY<ImprovementRule*> rules;
    ARRAY<SurfaceElementIndex> elmap;
    ARRAY<int> elrot;
    ARRAY<PointIndex> pmap;
    ARRAY<PointGeomInfo> pgi;

    int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr();
  
    ImprovementRule * r1;

    // 2 triangles to quad
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3));
    r1->oldels.Append (Element2d (3, 2, 4));
    r1->newels.Append (Element2d (1, 2, 4, 3));
    r1->deledges.Append (INDEX_2 (2,3));
    r1->onp = 4;
    r1->bonus = 2;
    rules.Append (r1);

    // 2 quad to 1 quad
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (4, 3, 2, 5));
    r1->newels.Append (Element2d (1, 2, 5, 4));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->deledges.Append (INDEX_2 (3, 4));
    r1->onp = 5;
    r1->bonus = 0;
    rules.Append (r1);

    // swap quads
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (3, 2, 5, 6));
    r1->newels.Append (Element2d (1, 6, 3, 4));
    r1->newels.Append (Element2d (1, 2, 5, 6));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->onp = 6;
    r1->bonus = 0;
    rules.Append (r1);

    // three quads to 2
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (2, 5, 6, 3));
    r1->oldels.Append (Element2d (3, 6, 7, 4));
    r1->newels.Append (Element2d (1, 2, 5, 4));
    r1->newels.Append (Element2d (4, 5, 6, 7));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->deledges.Append (INDEX_2 (3, 4));
    r1->deledges.Append (INDEX_2 (3, 6));
    r1->onp = 7;
    r1->bonus = -1;
    rules.Append (r1);

    // quad + 2 connected trigs to quad
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (2, 5, 3));
    r1->oldels.Append (Element2d (3, 5, 4));
    r1->newels.Append (Element2d (1, 2, 5, 4));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->deledges.Append (INDEX_2 (3, 4));
    r1->deledges.Append (INDEX_2 (3, 5));
    r1->onp = 5;
    r1->bonus = 0;
    rules.Append (r1);

    // quad + 2 non-connected trigs to quad (a and b)
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (2, 6, 3));
    r1->oldels.Append (Element2d (1, 4, 5));
    r1->newels.Append (Element2d (1, 3, 4, 5));
    r1->newels.Append (Element2d (1, 2, 6, 3));
    r1->deledges.Append (INDEX_2 (1, 4));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->onp = 6;
    r1->bonus = 0;
    rules.Append (r1);

    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (2, 6, 3));
    r1->oldels.Append (Element2d (1, 4, 5));
    r1->newels.Append (Element2d (1, 2, 4, 5));
    r1->newels.Append (Element2d (4, 2, 6, 3));
    r1->deledges.Append (INDEX_2 (1, 4));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->onp = 6;
    r1->bonus = 0;
    rules.Append (r1);

    // two quad + trig -> one quad + trig
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (2, 5, 6, 3));
    r1->oldels.Append (Element2d (4, 3, 6));
    r1->newels.Append (Element2d (1, 2, 6, 4));
    r1->newels.Append (Element2d (2, 5, 6));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->deledges.Append (INDEX_2 (3, 4));
    r1->deledges.Append (INDEX_2 (3, 6));
    r1->onp = 6;
    r1->bonus = -1;
    rules.Append (r1);

    // swap quad + trig (a and b)
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (2, 5, 3));
    r1->newels.Append (Element2d (2, 5, 3, 4));
    r1->newels.Append (Element2d (1, 2, 4));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->onp = 5;
    r1->bonus = 0;
    rules.Append (r1);

    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (2, 5, 3));
    r1->newels.Append (Element2d (1, 2, 5, 3));
    r1->newels.Append (Element2d (1, 3, 4));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->onp = 5;
    r1->bonus = 0;
    rules.Append (r1);


    // 2 quads to quad + 2 trigs
    r1 = new ImprovementRule;
    r1->oldels.Append (Element2d (1, 2, 3, 4));
    r1->oldels.Append (Element2d (3, 2, 5, 6));
    r1->newels.Append (Element2d (1, 5, 6, 4));
    r1->newels.Append (Element2d (1, 2, 5));
    r1->newels.Append (Element2d (4, 6, 3));
    r1->deledges.Append (INDEX_2 (2, 3));
    r1->onp = 6;
    r1->bonus = 0;
    //    rules.Append (r1);




    ARRAY<int> mapped(rules.Size());
    ARRAY<int> used(rules.Size());
    used = 0;
    mapped = 0;

  

    for (int ri = 0; ri < rules.Size(); ri++)
      {
	ImprovementRule & rule = *rules[ri];
	rule.incelsonnode.SetSize (rule.onp);
	rule.reused.SetSize (rule.onp);

	for (int j = 1; j <= rule.onp; j++)
	  {
	    rule.incelsonnode.Elem(j) = 0;
	    rule.reused.Elem(j) = 0;
	  }

	for (int j = 1; j <= rule.oldels.Size(); j++)
	  {
	    const Element2d & el = rule.oldels.Elem(j);
	    for (int k = 1; k <= el.GetNP(); k++)
	      rule.incelsonnode.Elem(el.PNum(k))--;
	  }

	for (int j = 1; j <= rule.newels.Size(); j++)
	  {
	    const Element2d & el = rule.newels.Elem(j);
	    for (int k = 1; k <= el.GetNP(); k++)
	      {
		rule.incelsonnode.Elem(el.PNum(k))++;
		rule.reused.Elem(el.PNum(k)) = 1;
	      }
	  }
      }



  
    TABLE<int,PointIndex::BASE> elonnode(np);
    ARRAY<int,PointIndex::BASE> nelonnode(np);
    TABLE<SurfaceElementIndex> nbels(ne);

    nelonnode = -4;

    for (SurfaceElementIndex sei = 0; sei < ne; sei++)
      {
	const Element2d & el = mesh[sei];

	if (el.GetIndex() == faceindex && !el.IsDeleted())
	  {
	    for (int j = 0; j < el.GetNP(); j++)
	      elonnode.Add (el[j], sei);
	  }
	if(!el.IsDeleted())
	  {
	    for (int j = 0; j < el.GetNP(); j++)
	      nelonnode[el[j]]++;
	  }
      }

    for (SurfaceElementIndex sei = 0; sei < ne; sei++)
      {
	const Element2d & el = mesh[sei];
	if (el.GetIndex() == faceindex && !el.IsDeleted())
	  {
	    for (int j = 0; j < el.GetNP(); j++)
	      {
		for (int k = 0; k < elonnode[el[j]].Size(); k++)
		  {
		    int nbel = elonnode[el[j]] [k];
		    bool inuse = false;
		    for (int l = 0; l < nbels[sei].Size(); l++)
		      if (nbels[sei][l] == nbel)
			inuse = true;
		    if (!inuse)
		      nbels.Add (sei, nbel);
		  }
	      }
	  }
      }


    for (int ri = 0; ri < rules.Size(); ri++)
      {
	const ImprovementRule & rule = *rules[ri];
      
	elmap.SetSize (rule.oldels.Size());
	elrot.SetSize (rule.oldels.Size());
	pmap.SetSize (rule.onp);
	pgi.SetSize (rule.onp);


	for (SurfaceElementIndex sei = 0; sei < ne; sei++)
	  {
	    if (multithread.terminate)
	      break;
	    if (mesh[sei].IsDeleted()) continue;

	    elmap[0] = sei;
	    FlatArray<SurfaceElementIndex> neighbours = nbels[sei];
	    
	    for (elrot[0] = 0; elrot[0] < mesh[sei].GetNP(); elrot[0]++)
	      {
		const Element2d & el0 = mesh[sei];
		const Element2d & rel0 = rule.oldels[0];

		if (el0.GetIndex() != faceindex) continue;
		if (el0.IsDeleted()) continue;
		if (el0.GetNP() != rel0.GetNP()) continue;


		pmap = -1;
 
		for (int k = 0; k < el0.GetNP(); k++)
		  {
		    pmap.Elem(rel0[k]) = el0.PNumMod(k+elrot[0]+1);
		    pgi.Elem(rel0[k]) = el0.GeomInfoPiMod(k+elrot[0]+1);
		  }
		
		ok = 1;
		for (int i = 1; i < elmap.Size(); i++)
		  {
		    // try to find a mapping for reference-element i

		    const Element2d & rel = rule.oldels[i];
		    bool possible = 0;

		    for (elmap[i] = 0; elmap[i] < neighbours.Size(); elmap[i]++)
		      {
			const Element2d & el = mesh[neighbours[elmap[i]]];
			if (el.IsDeleted()) continue;
			if (el.GetNP() != rel.GetNP()) continue;

			for (elrot[i] = 0; elrot[i] < rel.GetNP(); elrot[i]++)
			  {
			    possible = 1;

			    for (int k = 0; k < rel.GetNP(); k++)
			      if (pmap.Elem(rel[k]) != -1 &&
				  pmap.Elem(rel[k]) != el.PNumMod (k+elrot[i]+1))
				possible = 0;

			    if (possible) 
			      {
				for (int k = 0; k < el.GetNP(); k++)
				  {
				    pmap.Elem(rel[k]) = el.PNumMod(k+elrot[i]+1);
				    pgi.Elem(rel[k]) = el.GeomInfoPiMod(k+elrot[i]+1);
				  }
				break;
			      }
			  }
			if (possible) break;
		      }

		    if (!possible) 
		      {
			ok = 0;
			break;
		      }

		    elmap[i] = neighbours[elmap[i]];
		  }

		for(int i=0; ok && i<rule.deledges.Size(); i++)
		  {
		    ok = !mesh.IsSegment(pmap.Elem(rule.deledges[i].I1()),
					 pmap.Elem(rule.deledges[i].I2()));
		  }
								    
								    
		
		
		if (!ok) continue;

		mapped[ri]++;

		olddef = 0;
		for (int j = 1; j <= pmap.Size(); j++)
		  olddef += sqr (nelonnode[pmap.Get(j)]);
		olddef += rule.bonus;

		newdef = 0;
		for (int j = 1; j <= pmap.Size(); j++)
		  if (rule.reused.Get(j))
		    newdef += sqr (nelonnode[pmap.Get(j)] + 
				   rule.incelsonnode.Get(j));

		if (newdef > olddef)
		  continue;

		// calc metric badness
		double bad1 = 0, bad2 = 0;
		Vec<3> n;

		SelectSurfaceOfPoint (mesh.Point(pmap.Get(1)), pgi.Get(1));
		GetNormalVector (surfnr, mesh.Point(pmap.Get(1)), pgi.Elem(1), n);
		  
		for (int j = 1; j <= rule.oldels.Size(); j++)
		  bad1 += mesh.SurfaceElement(elmap.Get(j)).CalcJacobianBadness (mesh.Points(), n);
		  
		// check new element:
		for (int j = 1; j <= rule.newels.Size(); j++)
		  {
		    const Element2d & rnel = rule.newels.Get(j);
		    Element2d nel(rnel.GetNP());
		    for (int k = 1; k <= rnel.GetNP(); k++)
		      nel.PNum(k) = pmap.Get(rnel.PNum(k));

		    bad2 += nel.CalcJacobianBadness (mesh.Points(), n);
		  }

		if (bad2 > 1e3) continue;

		if (newdef == olddef && bad2 > bad1) continue;
		  

		// generate new element:
		for (int j = 1; j <= rule.newels.Size(); j++)
		  {
		    const Element2d & rnel = rule.newels.Get(j);
		    Element2d nel(rnel.GetNP());
		    nel.SetIndex (faceindex);
		    for (int k = 1; k <= rnel.GetNP(); k++)
		      {
			nel.PNum(k) = pmap.Get(rnel.PNum(k));
			nel.GeomInfoPi(k) = pgi.Get(rnel.PNum(k));
		      }
		      
		    mesh.AddSurfaceElement(nel);
		  }
		  
		for (int j = 0; j < rule.oldels.Size(); j++)
		  mesh.DeleteSurfaceElement ( elmap[j] );

		for (int j = 1; j <= pmap.Size(); j++)
		  nelonnode[pmap.Get(j)] += rule.incelsonnode.Get(j);

		used[ri]++;
	      }
	  }
      }

    mesh.Compress();

    for (int ri = 0; ri < rules.Size(); ri++)
      {
	PrintMessage (5, "rule ", ri+1, " ",
		      mapped[ri], "/", used[ri], " mapped/used");
      }
  }