Пример #1
0
        static int call(I0 const& i0, F f)
        {
            int ct = unrolled_count_if<n-4>::
                call(fusion::advance_c<4>(i0), f);
            if(f(*i0))
                ++ct;

            typedef typename result_of::next<I0>::type I1;
            I1 i1(fusion::next(i0));
            if(f(*i1))
                ++ct;

            typedef typename result_of::next<I1>::type I2;
            I2 i2(fusion::next(i1));
            if(f(*i2))
                ++ct;

            typedef typename result_of::next<I2>::type I3;
            I3 i3(fusion::next(i2));
            if(f(*i3))
                ++ct;

            return ct;
        }
Пример #2
0
int main(int argc, char **argv)
{
#if 0//ndef _WIN32
    int i = 1;
    if (Fl::args(argc,argv,i,arg) < argc) {
        fprintf(stderr," -v # : use visual\n%s\n",Fl::help);
        exit(1);
    }

    if (visid >= 0) {
        fl_open_display();
        XVisualInfo templt; int num;
        templt.visualid = visid;
        fl_visual = XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
        if (!fl_visual) {
            fprintf(stderr, "No visual with id %d, use one of:\n",visid);
            list_visuals();
            exit(1);
        }
        fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
                                      fl_visual->visual, AllocNone);
        fl_xpixel(FL_BLACK); // make sure black is allocated in overlay visuals
    } else {
        Fl::visual(FL_RGB);
    }
#endif

    Fl_Renderer::system_init();
    //Fl_Double_Window window(300,300); ::w = &window;
    Fl_Window window(400,300); ::w = &window;
    char title[64];
    sprintf(title, "System byte order is '%s'", Fl_Renderer::big_endian()?"BIG-ENDIAN":"LIL-ENDIAN");
    window.label(title);

    Fl_Toggle_Button b(10,10,200,200,"Fl_Pixmap");
    //Fl_Box b(10,10,200,200,"Fl_Pixmap");
    //b.box(FL_ENGRAVED_BOX);
    ::b = &b;
    b.image(pixmap);
    b.tooltip("This Fl_Toggle_Button has:\n"
              "image() set to the Fl_Image class selected below.\n"
              "label() set to the name of that class.\n"
              "align() set to the flags selected below.\n"
              "Be sure to resize the window to see how it lays out");

#define BWIDTH 60
#define BHEIGHT 21

    Fl_Group controls(10, 300-3*BHEIGHT-20, 380, 3*BHEIGHT+10);
    controls.box(FL_ENGRAVED_BOX);

    Fl_Choice choice(5, 5, 110, BHEIGHT);
    choice.begin();
    Fl_Item i1("Fl_Bitmap");
    i1.callback(choice_cb, &bitmap);
    Fl_Item i2("Fl_Pixmap");
    i2.callback(choice_cb, &pixmap);
    Fl_Item i3("Fl_RGB_Image");
    i3.callback(choice_cb, &rgb_image);
    choice.end();
    choice.value(1); // set it to pixmap
    choice.tooltip("Subclass of Fl_Image to use");

    int y = 5+BHEIGHT;
    int x = 5;
    topb = new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "top"); x += BWIDTH;
    topb->callback(button_cb);
    topb->tooltip("FL_ALIGN_TOP");
    bottomb= new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "bottom");x += BWIDTH;
    bottomb->callback(button_cb);
    bottomb->tooltip("FL_ALIGN_BOTTOM");
    leftb = new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "left"); x += BWIDTH;
    leftb->callback(button_cb);
    leftb->tooltip("FL_ALIGN_LEFT");
    rightb = new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "right"); x += BWIDTH;
    rightb->callback(button_cb);
    rightb->tooltip("FL_ALIGN_RIGHT");
    scaleb = new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "scale"); x += BWIDTH;
    scaleb->callback(button_cb);
    scaleb->tooltip("FL_ALIGN_SCALE");
    y += BHEIGHT;
    x = 5;
    insideb= new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "inside");x += BWIDTH;
    insideb->callback(button_cb);
    insideb->tooltip("FL_ALIGN_INSIDE");
    clipb= new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "clip"); x += BWIDTH;
    clipb->callback(button_cb);
    clipb->tooltip("FL_ALIGN_CLIP");
    wrapb= new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "wrap"); x += BWIDTH;
    wrapb->callback(button_cb);
    wrapb->tooltip("FL_ALIGN_WRAP");
    tileb= new Fl_Check_Button(x, y, BWIDTH, BHEIGHT, "tile"); x += BWIDTH;
    tileb->callback(button_cb);
    tileb->tooltip("FL_ALIGN_TILED");

    controls.end();

/*    Fl_Box box(10,0,290,controls.y());
    box.hide();
    window.resizable(box);*/
    
    p2 = new Fl_Button(10,0,290,controls.y(),"Print to file");
    p2->callback(print,&controls);

    
    window.end();
    window.show(argc, argv);

    return Fl::run();
}
Пример #3
0
void test()
{
  // This function tests C++0x 5.16

  // p1 (contextually convert to bool)
  int i1 = ToBool() ? 0 : 1;

  // p2 (one or both void, and throwing)
  i1 ? throw 0 : throw 1;
  i1 ? test() : throw 1;
  i1 ? throw 0 : test();
  i1 ? test() : test();
  i1 = i1 ? throw 0 : 0;
  i1 = i1 ? 0 : throw 0;
  i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
  i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
  (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}
  (i1 ? i1 : throw 0) = 0; // expected-error {{expression is not assignable}}

  // p3 (one or both class type, convert to each other)
  // b1 (lvalues)
  Base base;
  Derived derived;
  Convertible conv;
  Base &bar1 = i1 ? base : derived;
  Base &bar2 = i1 ? derived : base;
  Base &bar3 = i1 ? base : conv;
  Base &bar4 = i1 ? conv : base;
  // these are ambiguous
  BadBase bb;
  BadDerived bd;
  (void)(i1 ? bb : bd); // expected-error {{conditional expression is ambiguous; 'BadBase' can be converted to 'BadDerived' and vice versa}}
  (void)(i1 ? bd : bb); // expected-error {{conditional expression is ambiguous}}
  // curiously enough (and a defect?), these are not
  // for rvalues, hierarchy takes precedence over other conversions
  (void)(i1 ? BadBase() : BadDerived());
  (void)(i1 ? BadDerived() : BadBase());

  // b2.1 (hierarchy stuff)
  extern const Base constret();
  extern const Derived constder();
  // should use const overload
  A a1((i1 ? constret() : Base()).trick());
  A a2((i1 ? Base() : constret()).trick());
  A a3((i1 ? constret() : Derived()).trick());
  A a4((i1 ? Derived() : constret()).trick());
  // should use non-const overload
  i1 = (i1 ? Base() : Base()).trick();
  i1 = (i1 ? Base() : Base()).trick();
  i1 = (i1 ? Base() : Derived()).trick();
  i1 = (i1 ? Derived() : Base()).trick();
  // should fail: const lost
  (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('Base' and 'const Derived')}}
  (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('const Derived' and 'Base')}}

  Priv priv;
  Fin fin;
  (void)(i1 ? Base() : Priv()); // expected-error{{private base class}}
  (void)(i1 ? Priv() : Base()); // expected-error{{private base class}}
  (void)(i1 ? Base() : Fin()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
  (void)(i1 ? Fin() : Base()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
  (void)(i1 ? base : priv); // expected-error {{private base class}}
  (void)(i1 ? priv : base); // expected-error {{private base class}}
  (void)(i1 ? base : fin); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
  (void)(i1 ? fin : base); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}

  // b2.2 (non-hierarchy)
  i1 = i1 ? I() : i1;
  i1 = i1 ? i1 : I();
  I i2(i1 ? I() : J());
  I i3(i1 ? J() : I());
  // "the type [it] woud have if E2 were converted to an rvalue"
  vfn pfn = i1 ? F() : test;
  pfn = i1 ? test : F();
  (void)(i1 ? A() : B()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
  (void)(i1 ? B() : A()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
  (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
  (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
  // By the way, this isn't an lvalue:
  &(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}}

  // p4 (lvalue, same type)
  Fields flds;
  int &ir1 = i1 ? flds.i1 : flds.i2;
  (i1 ? flds.b1 : flds.i2) = 0;
  (i1 ? flds.i1 : flds.b2) = 0;
  (i1 ? flds.b1 : flds.b2) = 0;

  // p5 (conversion to built-in types)
  // GCC 4.3 fails these
  double d1 = i1 ? I() : K();
  pfn = i1 ? F() : G();
  DFnPtr pfm;
  pfm = i1 ? DFnPtr() : &Base::fn1;
  pfm = i1 ? &Base::fn1 : DFnPtr();

  // p6 (final conversions)
  i1 = i1 ? i1 : ir1;
  int *pi1 = i1 ? &i1 : 0;
  pi1 = i1 ? 0 : &i1;
  i1 = i1 ? i1 : EVal;
  i1 = i1 ? EVal : i1;
  d1 = i1 ? 'c' : 4.0;
  d1 = i1 ? 4.0 : 'c';
  Base *pb = i1 ? (Base*)0 : (Derived*)0;
  pb = i1 ? (Derived*)0 : (Base*)0;
  pfm = i1 ? &Base::fn1 : &Derived::fn2;
  pfm = i1 ? &Derived::fn2 : &Base::fn1;
  pfm = i1 ? &Derived::fn2 : 0;
  pfm = i1 ? 0 : &Derived::fn2;
  const int (MixedFieldsDerived::*mp1) =
    i1 ? &MixedFields::ci : &MixedFieldsDerived::i;
  const volatile int (MixedFields::*mp2) =
    i1 ? &MixedFields::ci : &MixedFields::cvi;
  (void)(i1 ? &MixedFields::ci : &MixedFields::vi);
  // Conversion of primitives does not result in an lvalue.
  &(i1 ? i1 : d1); // expected-error {{address expression must be an lvalue or a function designator}}

  (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}}
  (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}}
  

  unsigned long test0 = 5;
  test0 = test0 ? (long) test0 : test0; // expected-warning {{operand of ? changes signedness: 'long' to 'unsigned long'}}
  test0 = test0 ? (int) test0 : test0; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
  test0 = test0 ? (short) test0 : test0; // expected-warning {{operand of ? changes signedness: 'short' to 'unsigned long'}}
  test0 = test0 ? test0 : (long) test0; // expected-warning {{operand of ? changes signedness: 'long' to 'unsigned long'}}
  test0 = test0 ? test0 : (int) test0; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
  test0 = test0 ? test0 : (short) test0; // expected-warning {{operand of ? changes signedness: 'short' to 'unsigned long'}}
  test0 = test0 ? test0 : (long) 10;
  test0 = test0 ? test0 : (int) 10;
  test0 = test0 ? test0 : (short) 10;
  test0 = test0 ? (long) 10 : test0;
  test0 = test0 ? (int) 10 : test0;
  test0 = test0 ? (short) 10 : test0;

  int test1;
  test0 = test0 ? EVal : test0;
  test1 = test0 ? EVal : (int) test0;

  test0 = test0 ? EVal : test1; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
  test0 = test0 ? test1 : EVal; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}

  test1 = test0 ? EVal : (int) test0;
  test1 = test0 ? (int) test0 : EVal;

  // Note the thing that this does not test: since DR446, various situations
  // *must* create a separate temporary copy of class objects. This can only
  // be properly tested at runtime, though.
}
Пример #4
0
TEST(TypesTests, VectorScalarArithmetic) {
    float2 f2(1.0f, -2.0f);
    float2 f2_a;
    f2_a = f2+2.2f;
    EXPECT_FLOAT_EQ(3.2f, f2_a.x);
    EXPECT_FLOAT_EQ(0.2f, f2_a.y);
    f2_a = 2.2f+f2;
    EXPECT_FLOAT_EQ(3.2f, f2_a.x);
    EXPECT_FLOAT_EQ(0.2f, f2_a.y);

    f2_a = f2-0.2f;
    EXPECT_FLOAT_EQ(0.8f, f2_a.x);
    EXPECT_FLOAT_EQ(-2.2f, f2_a.y);
    f2_a = 0.2f-f2;
    EXPECT_FLOAT_EQ(-0.8f, f2_a.x);
    EXPECT_FLOAT_EQ(2.2f, f2_a.y);

    f2_a = f2*2;
    EXPECT_FLOAT_EQ(2.0f, f2_a.x);
    EXPECT_FLOAT_EQ(-4.0f, f2_a.y);
    f2_a = 2*f2;
    EXPECT_FLOAT_EQ(2.0f, f2_a.x);
    EXPECT_FLOAT_EQ(-4.0f, f2_a.y);

    float3 f3(1.0f, 0.5f, -1.0f);
    float3 f3_a;
    f3_a = f3+2.2f;
    EXPECT_FLOAT_EQ(3.2f, f3_a.x);
    EXPECT_FLOAT_EQ(2.7f, f3_a.y);
    EXPECT_FLOAT_EQ(1.2f, f3_a.z);
    f3_a = 2.2f+f3;
    EXPECT_FLOAT_EQ(3.2f, f3_a.x);
    EXPECT_FLOAT_EQ(2.7f, f3_a.y);
    EXPECT_FLOAT_EQ(1.2f, f3_a.z);

    f3_a = f3-0.2f;
    EXPECT_FLOAT_EQ(0.8f, f3_a.x);
    EXPECT_FLOAT_EQ(0.3f, f3_a.y);
    EXPECT_FLOAT_EQ(-1.2f, f3_a.z);
    f3_a = 0.2f-f3;
    EXPECT_FLOAT_EQ(-0.8f, f3_a.x);
    EXPECT_FLOAT_EQ(-0.3f, f3_a.y);
    EXPECT_FLOAT_EQ(1.2f, f3_a.z);

    f3_a = f3*2;
    EXPECT_FLOAT_EQ(2.0f, f3_a.x);
    EXPECT_FLOAT_EQ(1.0f, f3_a.y);
    EXPECT_FLOAT_EQ(-2.0f, f3_a.z);
    f3_a = 2*f3;
    EXPECT_FLOAT_EQ(2.0f, f3_a.x);
    EXPECT_FLOAT_EQ(1.0f, f3_a.y);
    EXPECT_FLOAT_EQ(-2.0f, f3_a.z);

    int2 i2(4,-1);
    float2 i2_a;
    i2_a = i2+2.1f;
    EXPECT_FLOAT_EQ(6.1f, i2_a.x);
    EXPECT_FLOAT_EQ(1.1f, i2_a.y);
    i2_a = 2.1f+i2;
    EXPECT_FLOAT_EQ(6.1f, i2_a.x);
    EXPECT_FLOAT_EQ(1.1f, i2_a.y);

    i2_a = i2-2.1f;
    EXPECT_FLOAT_EQ(1.9f, i2_a.x);
    EXPECT_FLOAT_EQ(-3.1f, i2_a.y);
    i2_a = 2.1f-i2;
    EXPECT_FLOAT_EQ(-1.9f, i2_a.x);
    EXPECT_FLOAT_EQ(3.1f, i2_a.y);

    i2_a = i2*2;
    EXPECT_FLOAT_EQ(8, i2_a.x);
    EXPECT_FLOAT_EQ(-2, i2_a.y);
    i2_a = 2*i2;
    EXPECT_FLOAT_EQ(8, i2_a.x);
    EXPECT_FLOAT_EQ(-2, i2_a.y);

    int3 i3(2,1,-1);
    float3 i3_a;
    i3_a = i3+2.1f;
    EXPECT_FLOAT_EQ(4.1f, i3_a.x);
    EXPECT_FLOAT_EQ(3.1f, i3_a.y);
    EXPECT_FLOAT_EQ(1.1f, i3_a.z);
    i3_a = 2.1f+i3;
    EXPECT_FLOAT_EQ(4.1f, i3_a.x);
    EXPECT_FLOAT_EQ(3.1f, i3_a.y);
    EXPECT_FLOAT_EQ(1.1f, i3_a.z);

    i3_a = i3-2.2f;
    EXPECT_FLOAT_EQ(-0.2f, i3_a.x);
    EXPECT_FLOAT_EQ(-1.2f, i3_a.y);
    EXPECT_FLOAT_EQ(-3.2f, i3_a.z);
    i3_a = 2.2f-i3;
    EXPECT_FLOAT_EQ(0.2f, i3_a.x);
    EXPECT_FLOAT_EQ(1.2f, i3_a.y);
    EXPECT_FLOAT_EQ(3.2f, i3_a.z);

    i3_a = i3*2;
    EXPECT_FLOAT_EQ(4, i3_a.x);
    EXPECT_FLOAT_EQ(2, i3_a.y);
    EXPECT_FLOAT_EQ(-2, i3_a.z);
    i3_a = 2*i3;
    EXPECT_FLOAT_EQ(4, i3_a.x);
    EXPECT_FLOAT_EQ(2, i3_a.y);
    EXPECT_FLOAT_EQ(-2, i3_a.z);
}
Пример #5
0
void GraphMetrics::computeGraphMetrics( Data::Graph* activeGraph )
{
	QMutableMapIterator<qlonglong, osg::ref_ptr<Data::Node> > i( *activeGraph->getNodes() );

	int numVertices = activeGraph->getNodes()->size();
	QVector<QLinkedList<osg::ref_ptr<Data::Node> > >**   paths;

	paths = new QVector<QLinkedList<osg::ref_ptr<Data::Node> > >* [numVertices]();

	int idx = 0;

	Util::ApplicationConfig* appConf = Util::ApplicationConfig::get();
	QString regexp = appConf->getValue( "Graph.Metrics.Regexp" );

	QRegExp re( regexp );
	re.setPatternSyntax( QRegExp::Wildcard );

	// compute metrics for all nodes in graph
	while ( i.hasNext() ) {
		i.next();

		// compute node degree

		float nodeDegree = static_cast<float>( i.value()->getEdges()->size() ) / static_cast<float>( numVertices - 1 );
		i.value()->setNodeDegree( nodeDegree );

		// get all shortest paths
		DjikstraAlg* alg = new DjikstraAlg( activeGraph );
		QMap<qlonglong, qlonglong> shortestPaths = alg->execute( i.value() );

		QMutableMapIterator<qlonglong, qlonglong> i2( shortestPaths );

		paths[idx] = new QVector<QLinkedList<osg::ref_ptr<Data::Node> > > [numVertices];

		// compute node closeness
		qlonglong pathSum = 0;
		while ( i2.hasNext() ) {
			i2.next();
			pathSum += i2.value();
		}

		if ( numVertices == 1 ) {
			numVertices = 2;
		}

		i.value()->setNodeCloseness( static_cast<float>( pathSum ) / static_cast<float>( numVertices - 1 ) );

		// check for regexp match
		if ( re.exactMatch( ( ( Data::AbsNode* )i.value() )->getName() ) ) {
			i.value()->setNodeMatched( true );
		}

		int idx2 = 0;

		// get shortest paths to all nodes for node betweenness
		QMutableMapIterator<qlonglong, osg::ref_ptr<Data::Node> > i3( *activeGraph->getNodes() );
		while ( i3.hasNext() ) {
			i3.next();
			paths[idx][idx2++] = alg->getAllPaths( i3.value() );
		}

		idx++;
	}

	i.toFront();
	float nodeDegreeWeigth = appConf->getValue( "Graph.Metrics.NodeDegreeWeigth" ).toFloat();
	float betweennessWeigth = appConf->getValue( "Graph.Metrics.BetweennessWeigth" ).toFloat();
	float closenessWeigth = appConf->getValue( "Graph.Metrics.ClosenessWeigth" ).toFloat();
	float regexpWeigth = appConf->getValue( "Graph.Metrics.RgexpWeigth" ).toFloat();

	// iterate through all nodes
	while ( i.hasNext() ) {

		i.next();
		float sum = 0;

		// compute node betweenness
		for ( int x = 0; x < numVertices; x++ ) {
			for ( int y = 0; y < numVertices; y++ ) {
				int cnt = 0;

				for ( int z = 0; z < paths[x][y].size(); z++ ) {
					if ( paths[x][y].at( z ).contains( i.value() ) ) {
						cnt++;
					}
				}

				if ( cnt != 0 ) {
					sum += static_cast<float>( cnt ) / static_cast<float>( paths[x][y].size() );
				}
			}
		}

		i.value()->setNodeBetweeness( sum / ( static_cast<float>( numVertices - 1 ) * static_cast<float>( numVertices - 2 ) )	);

		float base = i.value()->isNodeMatched() ? regexpWeigth : 0;

		// compute overall node metric
		float overallWeight = nodeDegreeWeigth * i.value()->getNodeDegree() + closenessWeigth * i.value()->getNodeCloseness() + betweennessWeigth * i.value()->getNodeBetweeness() + base;

		i.value()->setOverallWeight( overallWeight );
	}
}
Пример #6
0
HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, 
				BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, 
				INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint, int dim, const FaceDescriptor & fd)
{
  HPREF_ELEMENT_TYPE type = HP_NONE; 
  
  int pnums[3]; 
	      
  INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]);
  i3.Sort();
  bool sing_face = faces.Used (i3);
   
  
  for (int j = 1; j <= 3; j++)
    {
      int ep1 = edgepoint.Test (el.PNumMod (j));
      int ep2 = edgepoint.Test (el.PNumMod (j+1));
      int ep3 = edgepoint.Test (el.PNumMod (j+2));
      
      if (dim == 2)
	{
	  // JS, Dec 11
	  ep1 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j))) ||
	    edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j)));
	  ep2 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+1))) ||
	    edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+1)));
	  ep3 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+2))) ||
	    edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+2)));
	  /*
            ep1 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j)));
            ep2 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+1)));
            ep3 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+2)));
	  */
	  // ep3 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+2)));
	}
      
      
      
      int cp1 = cornerpoint.Test (el.PNumMod (j));
      int cp2 = cornerpoint.Test (el.PNumMod (j+1));
      int cp3 = cornerpoint.Test (el.PNumMod (j+2));
      
      ep1 |= cp1;
      ep2 |= cp2;
      ep3 |= cp3;
      
      
      // (*testout) << "cp = " << cp1 << cp2 << cp3 << ", ep = " << ep1 << ep2 << ep3 << endl;

      int p[3] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2)};
      if(ep1)
	{
	  INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); 
	  INDEX_2 i2b=INDEX_2::Sort(p[0], p[2]); 
	  if(!edges.Used(i2a) && !edges.Used(i2b)) 
	    cp1 = 1; 
	}
      if(ep2)
	{
	  INDEX_2 i2a=INDEX_2::Sort(p[1], p[0]); 
	  INDEX_2 i2b=INDEX_2::Sort(p[1], p[2]); 
	  if(!edges.Used(i2a) && !edges.Used(i2b)) 
	    cp2 = 1; 
	}
      if(ep3)
	{
	  INDEX_2 i2a=INDEX_2::Sort(p[2], p[0]); 
	  INDEX_2 i2b=INDEX_2::Sort(p[2], p[1]); 
	  if(!edges.Used(i2a) && !edges.Used(i2b)) 
	    cp3= 1; 
	}		      
      
      
      int isedge1=0, isedge2=0, isedge3=0; 
      if(dim == 3 )
	{
	  INDEX_2 i2;
	  i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1));
	  isedge1 = edges.Used (i2);
	  i2.Sort();
	  if(surf_edges.Used(i2) &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && 
	     (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
	    {
	      isedge1=1;
	      ep1 = 1; ep2=1;
	    }
	  
	  i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2));
	  isedge2 = edges.Used (i2);
	  i2.Sort();
	  if(surf_edges.Used(i2) &&  surf_edges.Get(i2)   != fd.SurfNr()+1 &&
	     (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
	    {
	      isedge2=1;
	      ep2 = 1; ep3=1;
	    }
	  i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3));
	  isedge3 = edges.Used (i2);
	  i2.Sort();
	  if(surf_edges.Used(i2) &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && 
	     (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
	    {
	      isedge3=1;
	      ep1 = 1; ep3=1;
	    }
	  
	  // cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl;  
	
	  if (!sing_face)
            {
              /*
                if (!isedge1)  { cp1 |= ep1; cp2 |= ep2; }
                if (!isedge2)  { cp2 |= ep2; cp3 |= ep3; }
                if (!isedge3)  { cp3 |= ep3; cp1 |= ep1; }
              */
              ep1 |= facepoint [el.PNumMod(j)] != 0;
              ep2 |= facepoint [el.PNumMod(j+1)] != 0;
              ep3 |= facepoint [el.PNumMod(j+2)] != 0;
	  
	  
              isedge1 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1)));
              isedge2 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+1), el.PNumMod(j+2)));
              isedge3 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+2), el.PNumMod(j+3)));
            }
	}
      
      if(dim ==2) 
	{ 
	  INDEX_2 i2;
	  i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1));
	  i2.Sort();
	  isedge1 = edges.Used (i2);
	  if(isedge1)
	    {
	      ep1 = 1; ep2=1;
	    }
	  
	  i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2));
	  i2.Sort();
	  isedge2 = edges.Used (i2);
	  if(isedge2)
	    {
	      ep2 = 1; ep3=1;
	    }
	  i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3));
	  i2.Sort();
	  isedge3 = edges.Used (i2);
	  if(isedge3)
	    {
	      ep1 = 1; ep3=1;
	    }
	  
	  
	}
      
		  
      /*
        cout << " used " << face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1))) << endl; 

        cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl; 
        cout << " ep " << ep1 << "\t" << ep2 << " \t " << ep3 << endl; 
        cout << " cp " << cp1 << "\t" << cp2 << " \t " << cp3 << endl; 
      */
		  

      
      if (isedge1 + isedge2 + isedge3 == 0)
	{
	  if (!ep1 && !ep2 && !ep3)
	    type = HP_TRIG;
	  
	  if (ep1 && !ep2 && !ep3)
	    type = HP_TRIG_SINGCORNER;
	  
	  if (ep1 && ep2 && !ep3)
	    type = HP_TRIG_SINGCORNER12;
	  
	  if (ep1 && ep2 && ep3)
	    {
	      if (dim == 2)
                type = HP_TRIG_SINGCORNER123_2D;
	      else
		type = HP_TRIG_SINGCORNER123;
	    }
	  
	  if (type != HP_NONE)
	    {
	      pnums[0] = el.PNumMod (j);
	      pnums[1] = el.PNumMod (j+1);
	      pnums[2] = el.PNumMod (j+2);
	      break;
	    }
	}
      
      if (isedge1 && !isedge2 && !isedge3)
	{
	  int code = 0;
	  if (cp1) code += 1;
	  if (cp2) code += 2;
	  if (ep3) code += 4;
	  
	  HPREF_ELEMENT_TYPE types[] =
	    {
	      HP_TRIG_SINGEDGE, 
	      HP_TRIG_SINGEDGECORNER1, 
	      HP_TRIG_SINGEDGECORNER2,
	      HP_TRIG_SINGEDGECORNER12, 
	      HP_TRIG_SINGEDGECORNER3, 
	      HP_TRIG_SINGEDGECORNER13, 
	      HP_TRIG_SINGEDGECORNER23, 
	      HP_TRIG_SINGEDGECORNER123, 
	    };
	  type = types[code];
	  pnums[0] = el.PNumMod (j);
	  pnums[1] = el.PNumMod (j+1);
	  pnums[2] = el.PNumMod (j+2);
	  break;
	}
      
      
      if (isedge1 && !isedge2 && isedge3)
	{
	  if (!cp3)
	    {
	      if (!cp2) type = HP_TRIG_SINGEDGES;
	      else      type = HP_TRIG_SINGEDGES2;
	    }
	  else
	    { 
	      if (!cp2) type = HP_TRIG_SINGEDGES3;
	      else      type = HP_TRIG_SINGEDGES23;
	    }
	  
	  pnums[0] = el.PNumMod (j);
	  pnums[1] = el.PNumMod (j+1);
	  pnums[2] = el.PNumMod (j+2);
	  break;
	}
       
      if (isedge1 && isedge2 && isedge3)
	{
	  type = HP_TRIG_3SINGEDGES;
	  pnums[0] = el.PNumMod (j);
	  pnums[1] = el.PNumMod (j+1);
	  pnums[2] = el.PNumMod (j+2);
	  break;
	}
    }
  
  for(int k=0;k<3;k++) el[k] = pnums[k]; 
  /*if(type != HP_NONE) 
    {
     
    cout << " TRIG with pnums " << pnums[0] << "\t"  << 
    pnums[1] << "\t"  << pnums[2] << endl; 
    cout << " type "  << type << endl; 
    }
  */
  return(type);
}
Пример #7
0
// #ifdef SABINE 
HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, 
                                BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int>  & face_edges, 
				INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint, int dim, const FaceDescriptor & fd)

{
  HPREF_ELEMENT_TYPE type = HP_NONE; 
  
  int pnums[3]; 
  int p[3];   
  
  INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]);
  i3.Sort();
  bool sing_face = faces.Used (i3);
  
  // *testout << " facepoint " << facepoint << endl;  
      

  // Try all rotations of the trig 
  for (int j=0;j<3;j++) 
    {
      int point_sing[3] = {0,0,0}; 
      int edge_sing[3] = {0,0,0}; 
      // *testout << " actual rotation of trig points " ;  
      for(int m=0;m<3;m++) 
	{ 
	  p[m] = (j+m)%3 +1; // local vertex number
	  pnums[m] = el.PNum(p[m]); // global vertex number 
	  // *testout << pnums[m] << " \t "; 
	}
      // *testout << endl ; 
      
      if(dim == 3) 
	{
	  // face point 
	  for(int k=0;k<3;k++)
	    if(!sing_face)
	      { 
		//	*testout << " fp [" << k << "] = " << facepoint[pnums[k]] << endl;   
		//	*testout << " fd.DomainIn()" <<  fd.DomainIn() << endl; 
		//	*testout  << " fd.DomainOut()" <<  fd.DomainOut() << endl; 
		if( facepoint[pnums[k]]  && (facepoint[pnums[k]] ==-1 || 
					     facepoint[pnums[k]] == fd.DomainIn() ||   facepoint[pnums[k]] == fd.DomainOut()))
		  point_sing[p[k]-1] = 1; 
	      } 
	  // if point is on face_edge in next step sing = 2 

	  /*	  *testout << " pointsing NACH FACEPOints ... FALLS EDGEPOINT UMSETZEN" ; 
            for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ;
            *testout << endl; */
	}
      
      const ELEMENT_EDGE * eledges = MeshTopology::GetEdges(TRIG); 
      
      if(dim==3)
	{
	  for(int k=0;k<3;k++) 
	    { 
	      int ep1=p[eledges[k][0]-1];  
	      int ep2=p[eledges[k][1]-1];  
	      INDEX_2 i2(el.PNum(ep1),el.PNum(ep2)); 
	      
	      if(edges.Used(i2)) 
		{
		  
		  edge_sing[k]=2;
		  point_sing[ep1-1] = 2; 
		  point_sing[ep2-1] = 2; 
		}
	      else // face_edge? 
		{	  
		  i2.Sort();  
		  if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1)  // edge not face_edge acc. to surface in which trig lies
		    if(face_edges.Get(i2)==-1 ||face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut() )
		      { 
			edge_sing[k]=1;
		      } 
		    else
		      { 
			point_sing[ep1-1] = 0; // set to edge_point 
			point_sing[ep2-1] = 0; // set to edge_point
		      } 
		}
	      
	      /*  *testout << " pointsing NACH edges UND FACEEDGES UMSETZEN ... " ; 
                  for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ; 
                  *testout << endl;          
                  */
	    }
	}
      /*
       *testout << " dim " << dim << endl; 
       *testout << " edgepoint_dom " << edgepoint_dom << endl; 
       */
      if(dim==2)
	{
	  for(int k=0;k<3;k++) 
	    { 
	      int ep1=p[eledges[k][0]-1];  
	      int ep2=p[eledges[k][1]-1];  
	     
	      INDEX_2 i2(el.PNum(ep1),el.PNum(ep2));  
	     
	      if(edges.Used(i2)) 
		{
		  
		  if(edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep1-1])) || 
		     edgepoint_dom.Used(INDEX_2(-1,pnums[ep1-1])) || 
		     edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep2-1])) || 
		     edgepoint_dom.Used(INDEX_2(-1,pnums[ep2-1]))) 
		    {
		      edge_sing[k]=2;
		      point_sing[ep1-1] = 2;
		      point_sing[ep2-1] = 2; 
		    }
		}
	     
	    }
	}

     
	 
      for(int k=0;k<3;k++) 
	if(edgepoint.Test(pnums[k])) //edgepoint, but not member of sing_edge on trig -> cp 
	  {
	    INDEX_2 i2a=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+1)%3])); 
	    INDEX_2 i2b=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+2)%3])); 
	    
	    if(!edges.Used(i2a) && !edges.Used(i2b)) 
	      point_sing[p[k]-1] = 3; 	
	  } 
      
      for(int k=0;k<3;k++) 
	if(cornerpoint.Test(el.PNum(p[k]))) 
	  point_sing[p[k]-1] = 3; 
      
      *testout << "point_sing = " << point_sing[0] << point_sing[1] << point_sing[2] << endl;

      if(edge_sing[0] + edge_sing[1] + edge_sing[2] == 0) 
        { 
          int ps = point_sing[0] + point_sing[1] + point_sing[2]; 
	 
          if(ps==0) 
            type = HP_TRIG; 
          else if(point_sing[p[0]-1]  && !point_sing[p[1]-1] && !point_sing[p[2]-1])
            type = HP_TRIG_SINGCORNER;
          else if(point_sing[p[0]-1] && point_sing[p[1]-1] && !point_sing[p[2]-1]) 
            type = HP_TRIG_SINGCORNER12; 
          else if(point_sing[p[0]-1] && point_sing[p[1]-1] && point_sing[p[2]-1]) 
            { 
              if(dim==2) type = HP_TRIG_SINGCORNER123_2D; 
              else type = HP_TRIG_SINGCORNER123; 
            } 
        } 
      else
        if (edge_sing[2] && !edge_sing[0] && !edge_sing[1]) //E[2]=(1,2) 
          { 
            int code = 0; 
            if(point_sing[p[0]-1] > edge_sing[2]) code+=1; 
            if(point_sing[p[1]-1] > edge_sing[2]) code+=2; 
            if(point_sing[p[2]-1]) code+=4; 
	
            HPREF_ELEMENT_TYPE types[] =
              {
                HP_TRIG_SINGEDGE, 
                HP_TRIG_SINGEDGECORNER1, 
                HP_TRIG_SINGEDGECORNER2,
                HP_TRIG_SINGEDGECORNER12, 
                HP_TRIG_SINGEDGECORNER3, 
                HP_TRIG_SINGEDGECORNER13, 
                HP_TRIG_SINGEDGECORNER23, 
                HP_TRIG_SINGEDGECORNER123, 
              };
            type = types[code]; 
	
          }  // E[0] = [0,2], E[1] =[1,2], E[2] = [0,1]
        else 
          if(edge_sing[2] && !edge_sing[1] && edge_sing[0])
            {
              if(point_sing[p[2]-1] <= edge_sing[0] ) 
                { 
                  if(point_sing[p[1]-1]<= edge_sing[2]) type = HP_TRIG_SINGEDGES; 
                  else type = HP_TRIG_SINGEDGES2; 
                } 
              else 
                {
                  if(point_sing[p[1]-1]<= edge_sing[2]) 
                    type = HP_TRIG_SINGEDGES3; 
                  else type = HP_TRIG_SINGEDGES23; 
                }
            }
          else if (edge_sing[2] && edge_sing[1] && edge_sing[0])
            type = HP_TRIG_3SINGEDGES; 
     
      //  cout << " run for " <<  j << " gives type " << type << endl; 
      //*testout << " run for " <<  j << " gives type " << type << endl; 

      if(type!=HP_NONE) break;
    }

  *testout << "type = " << type << endl;
    
  for(int k=0;k<3;k++) el[k] = pnums[k]; 
  /*if(type != HP_NONE) 
    {
     
    cout << " TRIG with pnums " << pnums[0] << "\t"  << 
    pnums[1] << "\t"  << pnums[2] << endl; 
    cout << " type "  << type << endl; 
    }
  */
      return(type);
}
//-----------------------------------------------------------------------------
//! 
//-----------------------------------------------------------------------------
tApTurnSelectWidgetAC1242AC7080::tApTurnSelectWidgetAC1242AC7080( tPilotController& pilotDevice, QWidget* parent )
    :   tApWidget( pilotDevice, parent ),
        m_RequestedTurn( tPilotCommandInterface::PILOT_MODE_STANDBY )
{
    m_pGridMenu = new tGridMenu( 3, 3, this, false );
    m_pGridMenu->SetIndexing( true );

    setFocusProxy( m_pGridMenu );

    QFont f = font();
    f.setPixelSize( style()->pixelMetric( NPM( tNOSStyle::NPM_FontSizeSmallest ) ) );
    m_pGridMenu->setFont( f );

    QAction* pUTurnAction = new QAction( this );   
    QIcon i( QPixmap( tPath::ResourceFile( "simrad/autopilot/uturn.png" ) ) );
    pUTurnAction->setText( m_PilotDevice.GetCommandInterface()->ModeAbbreviation( tPilotCommandInterface::PILOT_MODE_U_TURN ) );
    pUTurnAction->setIcon( i );
    pUTurnAction->setProperty( "turnID", (int)tPilotCommandInterface::PILOT_MODE_U_TURN );
    m_pGridMenu->AddAction( pUTurnAction, true );
    Connect( pUTurnAction, SIGNAL( triggered() ), this, SLOT( OnTurnAction() ) );
        
    QAction* pCTurnAction = new QAction( this );
    QIcon i2( QPixmap( tPath::ResourceFile( "simrad/autopilot/cturn.png" ) ) );
    pCTurnAction->setText( m_PilotDevice.GetCommandInterface()->ModeAbbreviation( tPilotCommandInterface::PILOT_MODE_C_TURN ) );
    pCTurnAction->setIcon( i2 );
    pCTurnAction->setProperty( "turnID", (int)tPilotCommandInterface::PILOT_MODE_C_TURN );
    m_pGridMenu->AddAction( pCTurnAction, true );
    Connect( pCTurnAction, SIGNAL( triggered() ), this, SLOT( OnTurnAction() ) );

    QAction* pSpiralAction = new QAction( this );
    QIcon i3( QPixmap( tPath::ResourceFile( "simrad/autopilot/spiral.png" ) ) );
    pSpiralAction->setText( m_PilotDevice.GetCommandInterface()->ModeAbbreviation( tPilotCommandInterface::PILOT_MODE_SPIRAL ) );
    pSpiralAction->setIcon( i3 );
    pSpiralAction->setProperty( "turnID", (int)tPilotCommandInterface::PILOT_MODE_SPIRAL );
    m_pGridMenu->AddAction( pSpiralAction, true );
    Connect( pSpiralAction, SIGNAL( triggered() ), this, SLOT( OnTurnAction() ) );

    QAction* pZigzagAction = new QAction( this );
    QIcon i4( QPixmap( tPath::ResourceFile( "simrad/autopilot/zigzag.png" ) ) );
    pZigzagAction->setText( m_PilotDevice.GetCommandInterface()->ModeAbbreviation( tPilotCommandInterface::PILOT_MODE_ZIGZAG ) );
    pZigzagAction->setIcon( i4 );
    pZigzagAction->setProperty( "turnID", (int)tPilotCommandInterface::PILOT_MODE_ZIGZAG );
    m_pGridMenu->AddAction( pZigzagAction, true );
    Connect( pZigzagAction, SIGNAL( triggered() ), this, SLOT( OnTurnAction() ) );

    QAction* pSquareAction = new QAction( this );
    QIcon i5( QPixmap( tPath::ResourceFile( "simrad/autopilot/square.png" ) ) );
    pSquareAction->setText( m_PilotDevice.GetCommandInterface()->ModeAbbreviation( tPilotCommandInterface::PILOT_MODE_SQUARE ) );
    pSquareAction->setIcon( i5 );
    pSquareAction->setProperty( "turnID", (int)tPilotCommandInterface::PILOT_MODE_SQUARE );
    m_pGridMenu->AddAction( pSquareAction, true );
    Connect( pSquareAction, SIGNAL( triggered() ), this, SLOT( OnTurnAction() ) );

    QAction* pLazySAction = new QAction( this );
    QIcon i6( QPixmap( tPath::ResourceFile( "simrad/autopilot/lazys.png" ) ) );
    pLazySAction->setText( m_PilotDevice.GetCommandInterface()->ModeAbbreviation( tPilotCommandInterface::PILOT_MODE_LAZY_S ) );
    pLazySAction->setIcon( i6 );
    pLazySAction->setProperty( "turnID", (int)tPilotCommandInterface::PILOT_MODE_LAZY_S );
    m_pGridMenu->AddAction( pLazySAction, true );    
    Connect( pLazySAction, SIGNAL( triggered() ), this, SLOT( OnTurnAction() ) );

    QAction* pDCTAction = new QAction( this );
    QIcon i7( QPixmap( tPath::ResourceFile( "simrad/autopilot/depth.png" ) ) );
    pDCTAction->setText( m_PilotDevice.GetCommandInterface()->ModeAbbreviation( tPilotCommandInterface::PILOT_MODE_DEPTH_CONTOUR ) );
    pDCTAction->setIcon( i7 );
    pDCTAction->setProperty( "turnID", (int)tPilotCommandInterface::PILOT_MODE_DEPTH_CONTOUR );
    m_pGridMenu->InsertAction( pDCTAction, 2, 1, true );
    Connect( pDCTAction, SIGNAL( triggered() ), this, SLOT( OnTurnAction() ) );

    QVBoxLayout* pMainLayout = new QVBoxLayout();  
    pMainLayout->setContentsMargins( 5, 5, 5, 5 );
    pMainLayout->setSpacing( 5 );
    pMainLayout->addWidget( m_pGridMenu, 0 );
    setLayout( pMainLayout );

    m_pGridMenu->SetSelectedItem( 1, 1 );

    ShowCloseButton();
}
void calculateTangents( const void* pVertices, size_t numVertices,
                        uint32 posOff, uint32 texOff, uint32 normOff, uint32 vertStride,
                        const void* pIndices, size_t numIndices, gfx::IndexStride indexStride,
                        he::PrimitiveList<vec3>& outTangents)
{
    he::PrimitiveList<vec3> tan1(numVertices);
    tan1.resize(numVertices);

    const char* pCharVertices(static_cast<const char*>(pVertices));

    const uint16* indicesUShort(nullptr); 
    const uint32* indicesUInt(nullptr); 
    
    if (indexStride == gfx::IndexStride_UShort)
        indicesUShort = static_cast<const uint16*>(pIndices);
    else if (indexStride == gfx::IndexStride_UInt)
        indicesUInt = static_cast<const uint32*>(pIndices);
    else
        LOG(LogType_ProgrammerAssert, "unkown index stride: %d", indexStride);
    
    for (uint32 i = 0; i < numIndices; i += 3) //per triangle
    {
        uint32 i1(0), i2(0), i3(0);
        if (indexStride == gfx::IndexStride_UShort)
        {
            i1 = indicesUShort[i];
            i2 = indicesUShort[i + 1];
            i3 = indicesUShort[i + 2];
        }
        else if (indexStride == gfx::IndexStride_UInt)
        {
            i1 = indicesUInt[i];
            i2 = indicesUInt[i + 1];
            i3 = indicesUInt[i + 2];
        }

        const vec3& v1 = *reinterpret_cast<const vec3*>(pCharVertices + (i1 * vertStride + posOff));
        const vec3& v2 = *reinterpret_cast<const vec3*>(pCharVertices + (i2 * vertStride + posOff));
        const vec3& v3 = *reinterpret_cast<const vec3*>(pCharVertices + (i3 * vertStride + posOff));

        const vec2& tx1 = *reinterpret_cast<const vec2*>(pCharVertices + (i1 * vertStride + texOff));
        const vec2& tx2 = *reinterpret_cast<const vec2*>(pCharVertices + (i2 * vertStride + texOff));
        const vec2& tx3 = *reinterpret_cast<const vec2*>(pCharVertices + (i3 * vertStride + texOff));

        float x1 = v2.x - v1.x;
        float x2 = v3.x - v1.x;
        float y1 = v2.y - v1.y;
        float y2 = v3.y - v1.y;
        float z1 = v2.z - v1.z;
        float z2 = v3.z - v1.z;

        float s1 = tx2.x - tx1.x;
        float s2 = tx3.x - tx1.x;
        float t1 = tx2.y - tx1.y;
        float t2 = tx3.y - tx1.y;

        float r = 1.0f / (s1 * t2 - s2 * t1);

        vec3 sdir(
            (t2 * x1 - t1 * x2) * r, 
            (t2 * y1 - t1 * y2) * r, 
            (t2 * z1 - t1 * z2) * r );
        vec3 tdir(
            (s1 * x2 - s2 * x1) * r, 
            (s1 * y2 - s2 * y1) * r, 
            (s1 * z2 - s2 * z1) * r );

        tan1[i1] += sdir;
        tan1[i2] += sdir;
        tan1[i3] += sdir;
    }

    for (uint32 i = 0; i < numVertices; ++i)
    {
        const vec3& n = *reinterpret_cast<const vec3*>(pCharVertices + (i * vertStride + normOff));
        const vec3& t = tan1[i];

        outTangents.add(normalize(t - n * dot(n, t)));
    }
}
Пример #10
0
	void MarchingCubeTriangulator::Triangulate(ScalarFieldBuilders::ScalarFieldCreator& inData,const SpatialDiscretization::weight_t& volId, progressOperation& mainProcess)
	{
		weigh_parameters_t weigh_parameters;
		weigh_parameters.volId=volId;
		BeginFeedingFaces();


		ivec3 coordinates;
		long cellCount_m_one(inData.GetDomainSize()-1);
		ivec3 i1(1,0,0),
			  i2(1,0,1),
			  i3(0,0,1),
			  i4(0,1,0),
			  i5(1,1,0),
			  i6(1,1,1),
			  i7(0,1,1);
		PolygoniseAlgo::GRIDCELL grid;
		PolygoniseAlgo::TRIANGLE triList[5];
		int nbtri;
		progressOperation thisProcess(&mainProcess, (unsigned int) (cellCount_m_one * cellCount_m_one));
		for(coordinates.x=0;coordinates.x<cellCount_m_one;coordinates.x++)
		{
			for(coordinates.y=0;coordinates.y<cellCount_m_one;coordinates.y++)
			{
				progressOperation thisSubProcess(&thisProcess,1);
				if(VariationWithinFourZ(ivec2(coordinates.x,coordinates.y),inData))
				{
					grid.p[3] = inData.GetCenterCellCoordinates(coordinates+i3);
					grid.p[2] = inData.GetCenterCellCoordinates(coordinates+i2);
					grid.p[7] = inData.GetCenterCellCoordinates(coordinates+i7);
					grid.p[6] = inData.GetCenterCellCoordinates(coordinates+i6);
					grid.val[3]=WeightEvaluation(inData.GetMatrixValue(coordinates),weigh_parameters);
					grid.val[2]=WeightEvaluation(inData.GetMatrixValue(coordinates+i1),weigh_parameters);
					grid.val[7]=WeightEvaluation(inData.GetMatrixValue(coordinates+i4),weigh_parameters);
					grid.val[6]=WeightEvaluation(inData.GetMatrixValue(coordinates+i5),weigh_parameters);
					for(coordinates.z=0;coordinates.z<cellCount_m_one;coordinates.z++)
					{
						//TODO Computation on x,y loop
						grid.p[0] = grid.p[3];
						grid.p[1] = grid.p[2];
						grid.p[4]=  grid.p[7];
						grid.p[5] = grid.p[6];
						grid.p[2] = inData.GetCenterCellCoordinates(coordinates+i2);
						grid.p[3] = inData.GetCenterCellCoordinates(coordinates+i3);
						grid.p[6] = inData.GetCenterCellCoordinates(coordinates+i6);
						grid.p[7] = inData.GetCenterCellCoordinates(coordinates+i7);


						grid.val[0]=grid.val[3];
						grid.val[1]=grid.val[2];
						grid.val[4]=grid.val[7];
						grid.val[5]=grid.val[6];
						grid.val[2]=WeightEvaluation(inData.GetMatrixValue(coordinates+i2),weigh_parameters);
						grid.val[3]=WeightEvaluation(inData.GetMatrixValue(coordinates+i3),weigh_parameters);
						grid.val[6]=WeightEvaluation(inData.GetMatrixValue(coordinates+i6),weigh_parameters);
						grid.val[7]=WeightEvaluation(inData.GetMatrixValue(coordinates+i7),weigh_parameters);

						nbtri=PolygoniseAlgo::Polygonise(grid,0,triList);
						if(nbtri>0)
						{
							for(int idtri=0;idtri<nbtri;idtri++)
							{
								AddFace((const decimal *)&(triList[idtri].p[2]),
										(const decimal *)&(triList[idtri].p[1]),
										(const decimal *)&(triList[idtri].p[0]));
							}
						}
					}
				}
			}
		}
		FinishFeedingFaces();
	}
Пример #11
0
void velocity_read(sf_file velocity,float *vel,sf_file wave,float theta,int ix_center)
/*< read velocity or anisotropy parameter in tilted coordinates >*/
{
  float *tmpvel;
  int nvel[2],ntmpvel[2];
  int mig_nx, mig_nz, vel_nx, vel_nz;
  float mig_dx,mig_dz,mig_ox,mig_oz;
  float vel_dx,vel_dz,vel_ox,vel_oz;
  int iy,ix,iz,n_block; 
  float tmp_x,tmp_z,tmp_wx,tmp_wz,dtmp_x,dtmp_z;
  int tmp_ix,tmp_iz;
 
  sf_histfloat(wave,"d2",&mig_dx); sf_histfloat(wave,"o2",&mig_ox); sf_histint(wave,"n2",&mig_nx); 
  sf_histfloat(wave,"d1",&mig_dz); sf_histfloat(wave,"o1",&mig_oz); sf_histint(wave,"n1",&mig_nz); 

  sf_histfloat(velocity,"d2",&vel_dx); sf_histfloat(velocity,"o2",&vel_ox); sf_histint(velocity,"n2",&vel_nx); 
  sf_histfloat(velocity,"d1",&vel_dz); sf_histfloat(velocity,"o1",&vel_oz); sf_histint(velocity,"n1",&vel_nz); 

  d3(mig_nx,mig_nz,nvel);
  d3(vel_nx,vel_nz,ntmpvel);

  tmpvel=sf_floatalloc(vel_nz*vel_nx);
  if (theta >=0)
  {
    for(iy=0;iy<1;iy++){    //do iy=1,ny
      n_block=iy*vel_nx;
      sf_seek(velocity,n_block*vel_nz*sizeof(float),SEEK_SET);
      sf_floatread(tmpvel,vel_nz*vel_nx,velocity);

      for(ix=0;ix<mig_nx;ix++){
        dtmp_x=ix*mig_dx-(ix_center-1.0)*mig_dx;
        for(iz=0;iz<mig_nz;iz++){
          dtmp_z=iz*mig_dz;

          tmp_x=mig_ox+dtmp_x*cos(theta)+dtmp_z*sin(theta);
          tmp_x=(tmp_x-vel_ox)/vel_dx;
          tmp_ix=(int)(tmp_x);  tmp_wx=tmp_x-tmp_ix;
          if (tmp_x <0){
            tmp_ix=0;  tmp_wx=0.5;
          }
          if (tmp_ix >= vel_nx-1 ){
            tmp_ix=vel_nx-2;  tmp_wx=0.5;
          }

          tmp_z=mig_oz-dtmp_x*sin(theta)+dtmp_z*cos(theta);
          tmp_z=(tmp_z- vel_oz)/vel_dz;
          tmp_iz=(int)(tmp_z); tmp_wz=tmp_z-tmp_iz;
          if (tmp_z < 0){
            tmp_iz=0;   tmp_wz=0.5;
          }
          if (tmp_iz >= vel_nz-1 ){ 
            tmp_iz=vel_nz-2; tmp_wz=0.5;
          }
         
          vel[i3(iy,ix,iz,nvel)]=tmpvel[i3(0,tmp_ix,tmp_iz,ntmpvel)]*(1-tmp_wz)*(1-tmp_wx)+ 
                                 tmpvel[i3(0,tmp_ix,tmp_iz+1,ntmpvel)]*tmp_wz*(1-tmp_wx)  + 
                                 tmpvel[i3(0,tmp_ix+1,tmp_iz,ntmpvel)]*(1-tmp_wz)*tmp_wx  + 
                                 tmpvel[i3(0,tmp_ix+1,tmp_iz+1,ntmpvel)]*tmp_wz*tmp_wx;    
        }
      }
    }
  }
  else
  
  {
    theta=-theta;
    for(iy=0;iy<1;iy++){
      n_block=iy*vel_nx;
      sf_seek(velocity,n_block*vel_nz*sizeof(float),SEEK_SET);
      sf_floatread(tmpvel,vel_nz*vel_nx,velocity);
        
      for(ix=mig_nx-1;ix>=0;ix--){
        dtmp_x=(mig_nx-1-ix)*mig_dx-(ix_center-1)*mig_dx;
        for(iz=0;iz<mig_nz;iz++){
          dtmp_z=iz*mig_dz;

          tmp_x=mig_ox-dtmp_x*cos(theta)-dtmp_z*sin(theta);
          tmp_x=(tmp_x-vel_ox)/vel_dx;
          tmp_ix=(int)(tmp_x);  tmp_wx=tmp_x-tmp_ix;
          if (tmp_x <0){ 
            tmp_ix=0;  tmp_wx=0.5;
          }
          if (tmp_ix >= vel_nx-1 ){
            tmp_ix=vel_nx-2;  tmp_wx=0.5;
          }
          tmp_z=mig_oz-dtmp_x*sin(theta)+dtmp_z*cos(theta);
          tmp_z=(tmp_z-vel_oz)/vel_dz;
          tmp_iz=(int)(tmp_z); tmp_wz=tmp_z-tmp_iz;
          if (tmp_z < 0){
            tmp_iz=0;   tmp_wz=0.5;
          }
          if (tmp_iz >= vel_nz-1 ){
            tmp_iz=vel_nz-2; tmp_wz=0.5;
          }
          vel[i3(iy,(mig_nx-1)-ix,iz,nvel)]=tmpvel[i3(0,tmp_ix,tmp_iz,ntmpvel)]*(1-tmp_wz)*(1-tmp_wx)+ 
                                      tmpvel[i3(0,tmp_ix,tmp_iz+1,ntmpvel)]*tmp_wz*(1-tmp_wx)  + 
                                      tmpvel[i3(0,tmp_ix+1,tmp_iz,ntmpvel)]*(1-tmp_wz)*tmp_wx  + 
                                      tmpvel[i3(0,tmp_ix+1,tmp_iz+1,ntmpvel)]*tmp_wz*tmp_wx;
        }
      }        
    }  
 
  }
 
  free(tmpvel);
}
Пример #12
0
void QhullLinkedList_test::
t_iterator()
{
    RboxPoints rcube("c");
    {
        Qhull q(rcube,"QR0");  // rotated unit cube
        QhullVertexList vs = q.vertexList();
        QhullVertexList::Iterator i= vs.begin();
        QhullVertexList::iterator i2= vs.begin();
        QVERIFY(i==i2);
        // No comparisons
        i= vs.begin();
        QVERIFY(i==i2);
        i2= vs.end();
        QVERIFY(i!=i2);
        QhullVertex v3(*i);
        i2--;
        QhullVertex v8= *i2;
        QhullVertex v= vs.first();
        QhullVertex v2= v.next();
        QCOMPARE(v3.id(), v.id());
        QCOMPARE(v8.id(), vs.last().id());
        QhullVertexList::Iterator i3(i2);
        QCOMPARE(*i2, *i3);

        (i3= i)++;
        QCOMPARE((*i3).id(), v2.id());
        QVERIFY(i==i);
        QVERIFY(i!=i2);

        QhullVertexList::ConstIterator i4= vs.begin();
        QVERIFY(i==i4); // iterator COMP const_iterator
        QVERIFY(i4==i); // const_iterator COMP iterator
        QVERIFY(i2!=i4);
        QVERIFY(i4!=i2);
        ++i4;

        i= vs.begin();
        i2= vs.begin();
        QCOMPARE(i, i2++);
        QCOMPARE(*i2, v2);
        QCOMPARE(++i, i2);
        QCOMPARE(i, i2--);
        QCOMPARE(i2, vs.begin());
        QCOMPARE(--i, i2);
        QCOMPARE(i2 += 8, vs.end());
        QCOMPARE(i2 -= 8, vs.begin());
        QCOMPARE(i2+0, vs.begin());
        QCOMPARE(i2+8, vs.end());
        i2 += 8;
        i= i2-0;
        QCOMPARE(i, i2);
        i= i2-8;
        QCOMPARE(i, vs.begin());

        //vs.begin end tested above

        // QhullVertexList is const-only
        q.checkAndFreeQhullMemory();
    }
}//t_iterator
Пример #13
0
void KdeObservatory::updateSources()
{
    kDebug();
    setBusy(true);

    QString commitFrom = "";
    QString commitTo = "";

    if (m_activityRangeType == 2)
    {
        commitFrom = m_commitFrom;
        commitTo   = m_commitTo;
    }
    else if (m_activityRangeType == 1)
    {
        QDate currentDate = QDate::currentDate();
        commitTo   = currentDate.toString("yyyyMMdd");
        commitFrom = currentDate.addDays(-m_commitExtent).toString("yyyyMMdd");
    }

    m_sourceCounter = 0;
    uint appletId = id();

    QListIterator< QPair<QString, bool> > i (m_activeViews);
    while (i.hasNext())
    {
        const QPair<QString, bool> &pair = i.next();

        if (pair.first == i18n("Top Active Projects") && pair.second)
        {
            KConfigGroup ops = m_service->operationDescription("topActiveProjects");
            ops.writeEntry("appletId", appletId);
            ops.writeEntry("commitFrom", commitFrom);
            ops.writeEntry("commitTo"  , commitTo);
            m_service->startOperationCall(ops);
            ++m_sourceCounter;
        }

        if (pair.first == i18n("Top Developers") && pair.second)
        {
            QHashIterator<QString, bool> i1(m_topDevelopersViewProjects);
            while (i1.hasNext())
            {
                i1.next();
                if (i1.value())
                {
                    KConfigGroup ops = m_service->operationDescription("topProjectDevelopers");
                    ops.writeEntry("appletId", appletId);
                    ops.writeEntry("project", i1.key());
                    ops.writeEntry("commitFrom", commitFrom);
                    ops.writeEntry("commitTo"  , commitTo);
                    m_service->startOperationCall(ops);
                    ++m_sourceCounter;
                }
            }
        }

        if (pair.first == i18n("Commit History") && pair.second)
        {
            QHashIterator<QString, bool> i2(m_commitHistoryViewProjects);
            while (i2.hasNext())
            {
                i2.next();
                if (i2.value())
                {
                    KConfigGroup ops = m_service->operationDescription("commitHistory");
                    ops.writeEntry("appletId", appletId);
                    ops.writeEntry("project", i2.key());
                    ops.writeEntry("commitFrom", commitFrom);
                    ops.writeEntry("commitTo"  , commitTo);
                    m_service->startOperationCall(ops);
                    ++m_sourceCounter;
                }
            }    
        }

        if (pair.first == i18n("Krazy Report") && pair.second)
        {
            QHashIterator<QString, bool> i3(m_krazyReportViewProjects);
            while (i3.hasNext())
            {
                i3.next();
                if (i3.value() && (m_projects[i3.key()].krazyReport.contains("reports") || m_projects[i3.key()].krazyReport.contains("component=")))
                {
                    KConfigGroup ops = m_service->operationDescription("krazyReport");
                    ops.writeEntry("appletId", appletId);
                    ops.writeEntry("project", i3.key());
                    ops.writeEntry("krazyReport", m_projects[i3.key()].krazyReport);
                    ops.writeEntry("krazyFilePrefix", m_projects[i3.key()].krazyFilePrefix);
                    m_service->startOperationCall(ops);
                    ++m_sourceCounter;
                }
            }
        }
    }

    m_collectorProgress->setMaximum(m_sourceCounter);
    m_collectorProgress->setValue(0);
}
Пример #14
0
  void WriteTETFormat (const Mesh & mesh,
		       const string & filename)//, const string& problemType )
  {
    string problemType = "";
    if(!mesh.PureTetMesh())
      throw NgException("Can only export pure tet mesh in this format");

    cout << "starting .tet export to file " << filename << endl;


    ARRAY<int> point_ids,edge_ids,face_ids;
    ARRAY<int> elnum(mesh.GetNE());
    elnum = -1;

    
    ARRAY<int> userdata_int;
    ARRAY<double> userdata_double;
    ARRAY<int> ports;

    ARRAY<int> uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D;

    int pos_int = 0;
    int pos_double = 0;
    
    bool haveuserdata = 
      (mesh.GetUserData("TETmesh:double",userdata_double) &&
       mesh.GetUserData("TETmesh:int",userdata_int) && 
       mesh.GetUserData("TETmesh:ports",ports) &&
       mesh.GetUserData("TETmesh:point_id",point_ids,PointIndex::BASE) &&
       mesh.GetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D) &&
       mesh.GetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D) &&
       mesh.GetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D) &&
       mesh.GetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D));


    int version,subversion;

    if(haveuserdata)
      {
	version = int(userdata_double[0]);
	subversion = int(10*(userdata_double[0] - version));
	pos_double++;
      }
    else
      {
	version = 2;
	subversion = 0;
      }

    
    if(version >= 2)
      {
	// test if ids are disjunct, if not version 2.0 not possible
	int maxbc(-1),mindomain(-1);
	
	for(ElementIndex i=0; i<mesh.GetNE(); i++)
	  if(i==0 || mesh[i].GetIndex() < mindomain)
	    mindomain = mesh[i].GetIndex();
	for(int i=1; i<=mesh.GetNFD(); i++)
	  if(i==1 || mesh.GetFaceDescriptor(i).BCProperty() > maxbc)
	    maxbc = mesh.GetFaceDescriptor(i).BCProperty();
	
	if(maxbc >= mindomain)
	  {
	    cout << "WARNING: writing version " << version << "." << subversion << " tetfile not possible, ";
	    version = 1; subversion = 1;
	    cout << "using version " << version << "." << subversion << endl;
	  }
      }



    int startsize = point_ids.Size();
    point_ids.SetSize(mesh.GetNP()+1);
    for(int i=startsize; i<point_ids.Size(); i++)
      point_ids[i] = -1;


    for(int i=0; i<PointIndex::BASE; i++)
      point_ids[i] = -1;


    INDEX_2_CLOSED_HASHTABLE<int> edgenumbers(6*mesh.GetNE()+3*mesh.GetNSE());;
    INDEX_3_CLOSED_HASHTABLE<int> facenumbers(4*mesh.GetNE()+mesh.GetNSE());

    ARRAY<INDEX_2> edge2node;
    ARRAY<INDEX_3> face2edge;
    ARRAY<INDEX_4> element2face;

    int numelems(0),numfaces(0),numedges(0),numnodes(0);

    for(SegmentIndex si = 0; si < mesh.GetNSeg(); si++)
      {
	const Segment & seg = mesh[si];
	INDEX_2 i2(seg.p1,seg.p2);
	i2.Sort();
	if(edgenumbers.Used(i2))
	  continue;

	numedges++;
	edgenumbers.Set(i2,numedges);
	edge2node.Append(i2);

	edge_ids.Append(seg.edgenr);

	if(point_ids[seg.p1] == -1)
	  point_ids[seg.p1] = (version >= 2) ? seg.edgenr : 0;
	if(point_ids[seg.p2] == -1)
	  point_ids[seg.p2] = (version >= 2) ? seg.edgenr : 0;
      }

    for(SurfaceElementIndex si = 0; si < mesh.GetNSE(); si++)
      {
	if(mesh[si].IsDeleted())
	  continue;

	const Element2d & elem = mesh[si];

	numfaces++;
	INDEX_3 i3(elem[0], elem[1], elem[2]);

	int min = i3[0];
	int minpos = 0;
	for(int j=1; j<3; j++)
	  if(i3[j] < min)
	    {
	      min = i3[j]; minpos = j;
	    }
	if(minpos == 1)
	  {
	    int aux = i3[0]; i3[0] = i3[1]; i3[1] = i3[2]; i3[2] = aux;
	  }
	else if(minpos == 2)
	  {
	    int aux = i3[0]; i3[0] = i3[2]; i3[2] = i3[1]; i3[1] = aux;
	  }
	facenumbers.Set(i3,numfaces);

	int bc = mesh.GetFaceDescriptor(elem.GetIndex()).BCProperty();
	face_ids.Append(bc);

	for(int j=0; j<3; j++)
	  if(point_ids[elem[j]] == -1)
	    point_ids[elem[j]] = (version >= 2) ? bc : 0;

	INDEX_2 i2a,i2b;
	INDEX_3 f_to_n;
	for(int j=0; j<3; j++)
	  {
	    i2a = INDEX_2(i3[j],i3[(j+1)%3]);
	    i2b[0] = i2a[1]; i2b[1] = i2a[0];
	    if(edgenumbers.Used(i2a))
	      f_to_n[j] = edgenumbers.Get(i2a);
	    else if(edgenumbers.Used(i2b))
	      f_to_n[j] = -edgenumbers.Get(i2b);
	    else
	      {
		numedges++;
		edgenumbers.Set(i2a,numedges);
		edge2node.Append(i2a);
		f_to_n[j] = numedges;
		if(version >= 2)
		  edge_ids.Append(bc);
		else
		  edge_ids.Append(0);
	      }
	  }
	face2edge.Append(f_to_n);
      }
    
    for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)
      {
	const Element & el = mesh[ei];

	if(el.IsDeleted())
	  continue;

	numelems++;
	elnum[ei] = numelems;

	static int tetfaces[4][3] =
	  { { 0, 2, 1 },
	    { 0, 1, 3 },
	    { 1, 2, 3 },
	    { 2, 0, 3 } };
	
	for(int j=0; j<4; j++)
	  if(point_ids[el[j]] == -1)
	    point_ids[el[j]] = (version >= 2) ? el.GetIndex() : 0;

	INDEX_4 e_to_f;

	for(int i = 0; i < 4; i++)
	  {
	    INDEX_3 i3a(el[tetfaces[i][0]],el[tetfaces[i][1]],el[tetfaces[i][2]]);
	    
	    int min = i3a[0];
	    int minpos = 0;
	    for(int j=1; j<3; j++)
	      if(i3a[j] < min)
		{
		  min = i3a[j]; minpos = j;
		}
	    if(minpos == 1)
	      {
		int aux = i3a[0]; i3a[0] = i3a[1]; i3a[1] = i3a[2]; i3a[2] = aux;
	      }
	    else if(minpos == 2)
	      {
		int aux = i3a[0]; i3a[0] = i3a[2]; i3a[2] = i3a[1]; i3a[1] = aux;
	      }
	    INDEX_3 i3b(i3a[0],i3a[2],i3a[1]);
	    

	    if(facenumbers.Used(i3a))
	      e_to_f[i] = facenumbers.Get(i3a);
	    else if(facenumbers.Used(i3b))
	      e_to_f[i] = -facenumbers.Get(i3b);
	    else
	      {
		numfaces++;
		facenumbers.Set(i3a,numfaces);
		e_to_f[i] = numfaces;
		if(version >= 2)
		  face_ids.Append(el.GetIndex());
		else
		  face_ids.Append(0);

		INDEX_2 i2a,i2b;
		INDEX_3 f_to_n;
		for(int j=0; j<3; j++)
		  {
		    i2a = INDEX_2(i3a[j],i3a[(j+1)%3]);
		    i2b[0] = i2a[1]; i2b[1] = i2a[0];
		    if(edgenumbers.Used(i2a))
		      f_to_n[j] = edgenumbers.Get(i2a);
		    else if(edgenumbers.Used(i2b))
		      f_to_n[j] = -edgenumbers.Get(i2b);
		    else
		      {
			numedges++;
			edgenumbers.Set(i2a,numedges);
			edge2node.Append(i2a);
			f_to_n[j] = numedges;
			if(version >= 2)
			  edge_ids.Append(el.GetIndex());
			else
			  edge_ids.Append(0);
		      }
		  }
		face2edge.Append(f_to_n);	  
	      }
	  }
	element2face.Append(e_to_f);
      }




    ofstream outfile(filename.c_str());

    outfile.precision(16);

    int unitcode;
    double tolerance;
    double dS1,dS2, alphaDeg;
    double x3D,y3D,z3D;
    int modelverts(0), modeledges(0), modelfaces(0), modelcells(0);

    int numObj0D,numObj1D,numObj2D,numObj3D;
    int numports = ports.Size();

    ARRAY<int> nodenum(point_ids.Size()+1);

    nodenum = -1;
	    


    numnodes = 0;
    for(int i=0; i<point_ids.Size(); i++)
      {
	if(point_ids[i] != -1)
	  {
	    numnodes++;
	    nodenum[i] = numnodes;
	  }
      }


    if(haveuserdata)
      {
	unitcode = userdata_int[pos_int];
	pos_int++;

	tolerance = userdata_double[pos_double];
	pos_double++;

	dS1 = userdata_double[pos_double];
	pos_double++;
	dS2 = userdata_double[pos_double];
	pos_double++;
	alphaDeg = userdata_double[pos_double];
	pos_double++;

	x3D = userdata_double[pos_double];
	pos_double++;
	y3D = userdata_double[pos_double];
	pos_double++;
	z3D = userdata_double[pos_double];
	pos_double++;

	if(version == 2)
	  {
	    modelverts = userdata_int[pos_int];
	    pos_int++;
	    modeledges = userdata_int[pos_int];
	    pos_int++;
	    modelfaces = userdata_int[pos_int];
	    pos_int++;
	    modelcells = userdata_int[pos_int];
	    pos_int++;
	  }

	numObj3D = userdata_int[pos_int];
	pos_int++;
	numObj2D = userdata_int[pos_int];
	pos_int++;
	numObj1D = userdata_int[pos_int];
	pos_int++;
	numObj0D = userdata_int[pos_int];
	pos_int++;
      }
    else
      {
	unitcode = 3;

	tolerance = 1e-5;

	dS1 = dS2 = alphaDeg = 0;

	x3D = y3D = z3D = 0;

	modelverts = modeledges = modelfaces = modelcells = 0;
	
	numObj3D = numObj2D = numObj1D = numObj0D = 0;
      }

    string uidpid;
    if(version == 1)
      uidpid = "PID";
    else if (version == 2)
      uidpid = "UID";
    

    ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps;
    for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)
      {
	if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)
	  {
	    idmaps.Append(new ARRAY<int,PointIndex::BASE>);
	    mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true);
	  }
      }

    ARRAY<int> id_num,id_type;
    ARRAY< ARRAY<int> *> id_groups;


	// sst 2008-03-12: Write problem class...
	{
		std::string block;
		block  = "// CST Tetrahedral ";
		block += !problemType.empty() ? problemType : "High Frequency";
		block += " Mesh, Version no.:\n";
		
		size_t size = block.size()-3;
		block += "// ";
		block.append( size, '^' );
		block += "\n";

		outfile
			<< block
			<< version << "." << subversion << "\n\n";
	}

	outfile 
	    << "// User Units Code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL):\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << unitcode << "\n\n"					\
	    << "// Geometric coord \"zero\" tolerance threshold:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << tolerance << "\n\n"				  \
	    << "// Periodic UnitCell dS1 , dS2 , alphaDeg:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << dS1 << " " << dS2 << " " << alphaDeg <<"\n\n"	\
	    << "// Periodic UnitCell origin in global coords (x3D,y3D,z3D):\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << x3D << " " << y3D << " " << z3D << "\n" << endl;

    if(version == 2)
      {
	outfile << "// Model entity count: Vertices, Edges, Faces, Cells:\n" \
		<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
		<< modelverts << " " << modeledges << " " << modelfaces << " " << modelcells << endl << endl;
      }


    outfile << "// Topological mesh-entity counts (#elements,#faces,#edges,#nodes):\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    outfile << numelems << " " 
	    << numfaces << " "
	    << numedges << " " 
	    << numnodes << endl << endl;

    outfile << "// NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<< uidpid <<":\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
       


    id_num.SetSize(mesh.GetNP()+1);
    id_type.SetSize(mesh.GetNP()+1);
    id_num = 0;
    id_type = 0;

    int n2,n4,n8;
    n2 = n4 = n8 = 0;

 
    for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
      {
	if(id_num[i] != 0)
	  continue;

	if(nodenum[i] == -1)
	  continue;

	ARRAY<int> group;
	group.Append(i);
	for(int j=0; j<idmaps.Size(); j++)
	  {
	    startsize = group.Size();
	    for(int k=0; k<startsize; k++)
	      {
		int id = (*idmaps[j])[group[k]];
		if(id != 0 && !group.Contains(id) && nodenum[id] != -1)
		  {
		    group.Append(id);
		    id_num[id] = j+1+id_num[group[k]];
		  }
	      }
	  }
	if(group.Size() > 1)
	  {
	    id_groups.Append(new ARRAY<int>(group));
	    if(group.Size() == 2)
	      {
		id_type[i] = 1;
		id_type[group[1]] = 2;
		n2++;
	      }
	    else if(group.Size() == 4)
	      {
		id_type[i] = 3;
		for(int j=1; j<group.Size(); j++)
		  id_type[group[j]] = 4;
		n4++;
	      }
	    else if(group.Size() == 8)
	      {
		id_type[i] = 5;
		for(int j=1; j<group.Size(); j++)
		  id_type[group[j]] = 6;
		n8++;
	      }
	    else
	      cerr << "ERROR: Identification group size = " << group.Size() << endl;
	  }
	
      }


    for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
      {
	if(nodenum[i] == -1)
	  continue;
	outfile << nodenum[i] << " "
		<< mesh[i](0) << " "
		<< mesh[i](1) << " "
		<< mesh[i](2) << " " << id_type[i] << " ";
	if(i-PointIndex::BASE < point_ids.Size())
	  outfile << point_ids[i];
	else
	  outfile << "0";
	outfile << "\n";
      }
    outfile << endl;

    outfile << "\n// Number of Periodic Master Nodes:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << n2 << "\n"			       \
	    << "\n" \
	    << "// MasterNodeID, SlaveNodeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<id_groups.Size(); i++)
      {
	if(id_groups[i]->Size() != 2)
	  continue;

	for(int j=0; j<id_groups[i]->Size(); j++)
	  outfile << nodenum[(*id_groups[i])[j]] << " ";
	for(int j=1; j<id_groups[i]->Size(); j++)
	  outfile << id_num[(*id_groups[i])[j]] << " ";
	outfile << "\n";

	delete id_groups[i];
	id_groups[i] = NULL;
      }
    outfile << endl;
	
	
    outfile << "// Number of Corner Periodic Master Nodes:\n"	      \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << n4 << "\n"				      \
	    << "\n" \
	    << "// MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2):\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";


    for(int i=0; i<id_groups.Size(); i++)
      {
	if(!id_groups[i] || id_groups[i]->Size() != 4)
	  continue;

	for(int j=0; j<id_groups[i]->Size(); j++)
	  outfile << nodenum[(*id_groups[i])[j]] << " ";
	for(int j=1; j<id_groups[i]->Size(); j++)
	  {
	    outfile << id_num[(*id_groups[i])[j]] << " ";
	  }
	outfile << "\n";

	delete id_groups[i];
	id_groups[i] = NULL;
      }
    outfile << endl;


    outfile << "// Number of Cubic Periodic Master Nodes:\n"	     \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << n8 << "\n"				     \
	    << "\n" \
	    << "// MasterNodeID, 7-SlaveNodeID's, TranslCodes:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<id_groups.Size(); i++)
      {
	if(!id_groups[i] || id_groups[i]->Size() != 8)
	  continue;

	for(int j=0; j<id_groups[i]->Size(); j++)
	  outfile << nodenum[(*id_groups[i])[j]] << " ";
	for(int j=1; j<id_groups[i]->Size(); j++)
	  outfile << id_num[(*id_groups[i])[j]] << " ";
	outfile << "\n";

	delete id_groups[i];
	id_groups[i] = NULL;
      }
    outfile << endl;

    


    outfile << "// EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<<uidpid<<":\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";

    
      
    ARRAY< ARRAY<int>* > vertex_to_edge(mesh.GetNP()+1);
    for(int i=0; i<=mesh.GetNP(); i++)
      vertex_to_edge[i] = new ARRAY<int>;

    ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps_edge(idmaps.Size());
    for(int i=0; i<idmaps_edge.Size(); i++)
      {
	idmaps_edge[i] = new ARRAY<int,PointIndex::BASE>(numedges);
	(*idmaps_edge[i]) = 0;
      }

    ARRAY<int> possible;
    for(int i=0; i<edge2node.Size(); i++)
      {
	const INDEX_2 & v = edge2node[i];
	for(int j=0; j<idmaps.Size(); j++)
	  {
	    INDEX_2 vid((*idmaps[j])[v[0]], (*idmaps[j])[v[1]]);
	    if(vid[0] != 0 && vid[0] != v[0] && vid[1] != 0 && vid[1] != v[1])
	      {
		Intersection(*vertex_to_edge[vid[0]],*vertex_to_edge[vid[1]],possible);
		if(possible.Size() == 1)
		  {
		    (*idmaps_edge[j])[possible[0]] = i+1;
		    (*idmaps_edge[j])[i+1] = possible[0];
		  }
		else if(possible.Size() > 0)
		  {
		    cerr << "ERROR: too many possible edge identifications" << endl;
		    (*testout) << "ERROR: too many possible edge identifications" << endl
			       << "*vertex_to_edge["<<vid[0]<<"] " << *vertex_to_edge[vid[0]] << endl
			       << "*vertex_to_edge["<<vid[1]<<"] " << *vertex_to_edge[vid[1]] << endl
			       << "possible " << possible << endl;
		  }
	      }
	  }
	vertex_to_edge[v[0]]->Append(i+1);
	vertex_to_edge[v[1]]->Append(i+1);
      }


    for(int i=0; i<vertex_to_edge.Size(); i++)
      delete vertex_to_edge[i];


    id_groups.SetSize(0);
    id_num.SetSize(numedges+1);
    id_num = 0;
    id_type.SetSize(numedges+1);
    id_type = 0;

    n2 = n4 = n8 = 0;

    for(int i=1; i<=edge2node.Size(); i++)
      {
	if(id_num[i] != 0)
	  continue;


	ARRAY<int> group;
	group.Append(i);
	for(int j=0; j<idmaps_edge.Size(); j++)
	  {
	    startsize = group.Size();
	    for(int k=0; k<startsize; k++)
	      {
		int id = (*idmaps_edge[j])[group[k]];
		if(id != 0 && !group.Contains(id))
		  {
		    group.Append(id);
		    id_num[id] = j+1+id_num[group[k]];
		  }
	      }
	  }
	if(group.Size() > 1)
	  {
	    id_num[i] = 1;
	    id_groups.Append(new ARRAY<int>(group));
	    if(group.Size() == 2)
	      {
		id_type[i] = 1;
		id_type[group[1]] = 2;
		n2++;
	      }
	    else if(group.Size() == 4)
	      {
		id_type[i] = 3;
		for(int j=1; j<group.Size(); j++)
		  id_type[group[j]] = 4;
		n4++;
	      }
	    else
	      {
		cerr << "ERROR: edge identification group size = " << group.Size() << endl;
		(*testout) << "edge group " << group << endl;
		for(int j=0; j<idmaps_edge.Size(); j++)
		  {
		    (*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl;
		  }
	      }
	  }
      }



    for(int i=1; i<=edge2node.Size(); i++)
      {
	if(id_num[i] != 0)
	  continue;


	ARRAY<int> group;
	group.Append(i);
	for(int j=0; j<idmaps_edge.Size(); j++)
	  {
	    startsize = group.Size();
	    for(int k=0; k<startsize; k++)
	      {
		int id = (*idmaps_edge[j])[group[k]];
		if(id != 0 && !group.Contains(id))
		  {
		    group.Append(id);
		    id_num[id] = j+1+id_num[group[k]];
		  }
	      }
	  }
	if(group.Size() > 1)
	  {
	    id_num[i] = 1;
	    id_groups.Append(new ARRAY<int>(group));
	    if(group.Size() == 2)
	      {
		id_type[i] = 1;
		id_type[group[1]] = 2;
		n2++;
	      }
	    else if(group.Size() == 4)
	      {
		id_type[i] = 3;
		for(int j=1; j<group.Size(); j++)
		  id_type[group[j]] = 4;
		n4++;
	      }
	    else
	      {
		cerr << "ERROR: edge identification group size = " << group.Size() << endl;
		(*testout) << "edge group " << group << endl;
		for(int j=0; j<idmaps_edge.Size(); j++)
		  {
		    (*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl;
		  }
	      }
	  }
	
      }

    
    for(int i=0; i<edge2node.Size(); i++)
      outfile << i+1 << " " << nodenum[edge2node[i][0]] << " " << nodenum[edge2node[i][1]] 
	      << " " << id_type[i+1] << " " << edge_ids[i] << "\n";

    outfile << endl;

    

    outfile << "// Number of Periodic Master Edges:\n"\
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\
	    << n2 << "\n"			      \
	    << "\n"\
	    << "// MasterEdgeID, SlaveEdgeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<id_groups.Size(); i++)
      {
	if(id_groups[i]->Size() != 2)
	  continue;

	for(int j=0; j<id_groups[i]->Size(); j++)
	  outfile << (*id_groups[i])[j] << " ";
	for(int j=1; j<id_groups[i]->Size(); j++)
	  outfile << id_num[(*id_groups[i])[j]] << " ";
	outfile << "\n";

	delete id_groups[i];
	id_groups[i] = NULL;
      }
    outfile << endl;

    outfile << "// Number of Corner Periodic Master Edges:\n"		\
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\
	    << n4 << "\n"				     \
	    << "\n"\
	    << "// MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<id_groups.Size(); i++)
      {
	if(!id_groups[i] || id_groups[i]->Size() != 4)
	  continue;

	for(int j=0; j<id_groups[i]->Size(); j++)
	  outfile << (*id_groups[i])[j] << " ";
	for(int j=1; j<id_groups[i]->Size(); j++)
	  outfile << id_num[(*id_groups[i])[j]] << " ";
	outfile << "\n";

	delete id_groups[i];
	id_groups[i] = NULL;
      }
    outfile << endl;


    outfile << "// FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), "<<uidpid<<":\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";

    
    
    ARRAY< ARRAY<int>* > edge_to_face(numedges+1);
    for(int i=0; i<edge_to_face.Size(); i++)
      edge_to_face[i] = new ARRAY<int>;

    
    for(int i=0; i<idmaps.Size(); i++)
      {
	idmaps[i]->SetSize(numfaces);
	(*idmaps[i]) = 0;
      }

    
    for(int i=0; i<face2edge.Size(); i++)
      {
	for(int j=0; j<idmaps_edge.Size(); j++)
	  {
	    int e1id,e2id,e3id;
	    e1id = (*idmaps_edge[j])[abs(face2edge[i][0])];
	    e2id = (*idmaps_edge[j])[abs(face2edge[i][1])];
	    e3id = (*idmaps_edge[j])[abs(face2edge[i][2])];
	    if(e1id != 0 && e1id != abs(face2edge[i][0]) &&
	       e2id != 0 && e2id != abs(face2edge[i][1]) &&
	       e3id != 0 && e3id != abs(face2edge[i][2]))
	      {
		Intersection(*edge_to_face[e1id],*edge_to_face[e2id],*edge_to_face[e3id],possible);
		if(possible.Size() == 1)
		  {
		    (*idmaps[j])[possible[0]] = i+1;
		    (*idmaps[j])[i+1] = possible[0];
		  }
		else if(possible.Size() > 0)
		  cerr << "ERROR: too many possible face identifications" << endl;
	      }
	  }

	edge_to_face[abs(face2edge[i][0])]->Append(i+1);
	edge_to_face[abs(face2edge[i][1])]->Append(i+1);
	edge_to_face[abs(face2edge[i][2])]->Append(i+1);
      }

    for(int i=0; i<edge_to_face.Size(); i++)
      delete edge_to_face[i];


    for(int i=0; i<idmaps_edge.Size(); i++)
      delete idmaps_edge[i];

    
    id_groups.SetSize(0);
    id_num.SetSize(numfaces+1);
    id_num = 0;

    n2 = n4 = n8 = 0;

    for(int i=1; i<=numfaces; i++)
      {
	if(id_num[i] != 0)
	  continue;

	ARRAY<int> group;
	group.Append(i);
	for(int j=0; j<idmaps.Size(); j++)
	  {
	    startsize = group.Size();
	    for(int k=0; k<startsize; k++)
	      {
		int id = (*idmaps[j])[group[k]];
		if(id != 0 && !group.Contains(id))
		  {
		    group.Append(id);
		    id_num[id] = j+1+id_num[group[k]];
		  }
	      }
	  }
	if(group.Size() > 1)
	  {
	    id_num[i] = -1;
	    id_groups.Append(new ARRAY<int>(group));
	    if(group.Size() == 2)
	      n2++;
	    else
	      cerr << "ERROR: face identification group size = " << group.Size() << endl;
	  }
	
      }


    for(int i=0; i<idmaps.Size(); i++)
      delete idmaps[i];




    for(int i=0; i<face2edge.Size(); i++)
      {	
	outfile << i+1 << " ";
	for(int j=0; j<3; j++)
	  outfile << face2edge[i][j] << " ";

	if(id_num[i+1] == 0)
	  outfile << 0;
	else if(id_num[i+1] == -1)
	  outfile << 1;
	else
	  outfile << 2;

	outfile << " " << face_ids[i] <<"\n";
      }
    outfile << endl;


    outfile << "// Number of Periodic Master Faces:\n"\
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\
	    << n2 << "\n"			      \
	    << "\n"\
	    << "// MasterFaceID, SlaveFaceID, TranslCode (1=dS1 2=dS2):\n"\
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<id_groups.Size(); i++)
      {
	if(id_groups[i]->Size() != 2)
	  continue;

	for(int j=0; j<id_groups[i]->Size(); j++)
	  outfile << (*id_groups[i])[j] << " ";
	for(int j=1; j<id_groups[i]->Size(); j++)
	  outfile << id_num[(*id_groups[i])[j]] << " ";
	outfile << "\n";

	delete id_groups[i];
      }
    outfile << endl;

    


    outfile << "// ElemID, FaceID0, FaceID1, FaceID2, FaceID3, "<<uidpid<<":\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";

    for(ElementIndex i=0; i<mesh.GetNE(); i++)
      {
	if(elnum[i] >= 0)
	  {
	    outfile << elnum[i] << " ";
	    for(int j=0; j<4; j++)
	      outfile << element2face[elnum[i]-1][j] << " ";

	    outfile << mesh[i].GetIndex() << "\n";
	  }
      }
    outfile << endl;

    outfile << "// ElemID, NodeID0, NodeID1, NodeID2, NodeID3:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";

    
    for(ElementIndex i=0; i<mesh.GetNE(); i++)
      {
	if(elnum[i] >= 0)
	  outfile << elnum[i] << " "
		  << nodenum[mesh[i][1]] << " " << nodenum[mesh[i][0]] << " " << nodenum[mesh[i][2]] << " " << nodenum[mesh[i][3]] << "\n";
      }
    outfile << endl;
    

    

    outfile << "// Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D):\n"
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
	    << " "<< numObj3D << " " << numObj2D << " " << numObj1D << " " << numObj0D << "\n" \
	    << "\n" \
	    << "// Number of Ports (Ports are a subset of Object2D list):\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \
	    << numports << "\n"						\
	    << endl;


    ARRAY< ARRAY<int> * > groups;

    int maxg = -1;
    for(int i = 0; i<uid_to_group_3D.Size(); i++)
      if(uid_to_group_3D[i] > maxg)
	maxg = uid_to_group_3D[i];
    for(int i = 0; i<uid_to_group_2D.Size(); i++)
      if(uid_to_group_2D[i] > maxg)
	maxg = uid_to_group_2D[i];
    for(int i = 0; i<uid_to_group_1D.Size(); i++)
      if(uid_to_group_1D[i] > maxg)
	maxg = uid_to_group_1D[i];
    for(int i = 0; i<uid_to_group_0D.Size(); i++)
      if(uid_to_group_0D[i] > maxg)
	maxg = uid_to_group_0D[i];

    groups.SetSize(maxg+1);
    for(int i=0; i<groups.Size(); i++)
      groups[i] = new ARRAY<int>;

    for(ElementIndex i=0; i<mesh.GetNE(); i++)
      if(uid_to_group_3D[mesh[i].GetIndex()] >= 0)
	groups[uid_to_group_3D[mesh[i].GetIndex()]]->Append(i+1);
      
    


    outfile << "// Object3D GroupID, #Elems <immediately followed by> ElemID List:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<numObj3D; i++)
      {
	outfile << i << " " << groups[i]->Size() << "\n";
	for(int j=0; j<groups[i]->Size(); j++)
	  outfile << (*groups[i])[j] << "\n";
      }

    for(int i=0; i<groups.Size(); i++)
      groups[i]->SetSize(0);

    for(int i=0; i<face_ids.Size(); i++)
      if(uid_to_group_2D[face_ids[i]] >= 0)
	groups[uid_to_group_2D[face_ids[i]]]->Append(i+1);
      

    outfile << "// Object2D GroupID, #Faces <immediately followed by> FaceID List:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<numObj2D; i++)
      {
	outfile << i << " " << groups[i]->Size() << "\n";
	for(int j=0; j<groups[i]->Size(); j++)
	  {
	    outfile << (*groups[i])[j];
	    if(ports.Contains(face_ids[(*groups[i])[j]-1]))
	      outfile << " P";
	    outfile << "\n";
	  }
      }
    outfile << endl;

    
    for(int i=0; i<groups.Size(); i++)
      groups[i]->SetSize(0);

    for(int i=0; i<edge_ids.Size(); i++)
      if(uid_to_group_1D[edge_ids[i]] >= 0)
	groups[uid_to_group_1D[edge_ids[i]]]->Append(i+1);



    outfile << "// Object1D GroupID, #Edges <immediately followed by> EdgeID List:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<numObj1D; i++)
      {
	outfile << i << " " << groups[i]->Size() << "\n";
	for(int j=0; j<groups[i]->Size(); j++)
	  outfile << (*groups[i])[j] << "\n";
      }
    outfile << endl;

    
    for(int i=0; i<groups.Size(); i++)
      groups[i]->SetSize(0);
    for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)
      {
	if(i-PointIndex::BASE < point_ids.Size())
	  {
	    if(uid_to_group_0D[point_ids[i]] >= 0)
	      groups[uid_to_group_0D[point_ids[i]]]->Append(i+1-PointIndex::BASE);
	  }
	else
	  groups[uid_to_group_0D[0]]->Append(i+1-PointIndex::BASE);
      }


    outfile << "// Object0D GroupID, #Nodes <immediately followed by> NodeID List:\n" \
	    << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
    for(int i=0; i<numObj0D; i++)
      {
	outfile << i << " " << groups[i]->Size() << "\n";
	for(int j=0; j<groups[i]->Size(); j++)
	  outfile << (*groups[i])[j] << "\n";
      }
    outfile << endl;

    for(int i=0; i<groups.Size(); i++)
      delete groups[i];


    outfile.close();

    cout << ".tet export done" << endl;
  }
Пример #15
0
HPREF_ELEMENT_TYPE ClassifyTet(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, 
                               BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, 
                               INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint)
{
  int ep1(0), ep2(0), ep3(0), ep4(0), cp1(0), cp2(0), cp3(0), cp4(0), fp1, fp2, fp3, fp4;
  int isedge1(0), isedge2(0), isedge3(0), isedge4(0), isedge5(0), isedge6(0);
  int isfedge1, isfedge2, isfedge3, isfedge4, isfedge5, isfedge6;
  int isface1(0), isface2(0), isface3(0), isface4(0);

  HPREF_ELEMENT_TYPE type = HP_NONE; 
  

  int debug = 0;
  for (int j = 0;j < 4; j++)
    {
      if (el.pnums[j] == 444) debug++;
      if (el.pnums[j] == 115) debug++;
      if (el.pnums[j] == 382) debug++;
      if (el.pnums[j] == 281) debug++;
    }
  if (debug < 4) debug = 0;
  


  for (int j = 0; j < 4; j++)
    for (int k = 0; k < 4; k++)
      {
	if (j == k) continue;
	if (type) break;
	
	int pi3 = 0;
	while (pi3 == j || pi3 == k) pi3++;
	int pi4 = 6 - j - k - pi3;
	
	// preserve orientation
	int sort[4];
	sort[0] = j; sort[1] = k; sort[2] = pi3; sort[3] = pi4;
	int cnt = 0;
	for (int jj = 0; jj < 4; jj++)
	  for (int kk = 0; kk < 3; kk++)
	    if (sort[kk] > sort[kk+1])
	      {
		cnt++;
		Swap (sort[kk], sort[kk+1]); 
	      }
	if (cnt % 2 == 1) Swap (pi3, pi4);
	
	ep1 = edgepoint.Test (el.pnums[j]);
	ep2 = edgepoint.Test (el.pnums[k]);
	ep3 = edgepoint.Test (el.pnums[pi3]);
	ep4 = edgepoint.Test (el.pnums[pi4]);
	
	cp1 = cornerpoint.Test (el.pnums[j]);
	cp2 = cornerpoint.Test (el.pnums[k]);
	cp3 = cornerpoint.Test (el.pnums[pi3]);
	cp4 = cornerpoint.Test (el.pnums[pi4]);
	
	isedge1 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[k]));
	isedge2 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi3]));
	isedge3 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi4]));
	isedge4 = edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi3]));
	isedge5 = edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi4]));
	isedge6 = edges.Used (INDEX_2::Sort (el.pnums[pi3], el.pnums[pi4]));
	
	if (debug)
	  {
	    cout << "debug" << endl;
	    *testout  << "debug" << endl;
	    *testout << "ep = " << ep1 << ep2 << ep3 << ep4 << endl;
	    *testout << "cp = " << cp1 << cp2 << cp3 << cp4 << endl;
	    *testout << "edge = " << isedge1 << isedge2 << isedge3 << isedge4 << isedge5 << isedge6 << endl;
	  }


	isface1 = isface2 = isface3 = isface4 = 0;
	for (int l = 0; l < 4; l++)
	  {
	    INDEX_3 i3(0,0,0);
	    switch (l)
	      {
              case 0: i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi3]; i3.I1() = el.pnums[pi4]; break;
              case 1: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[pi3]; i3.I1() = el.pnums[pi4]; break;
              case 2: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi4]; break;
              case 3: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi3]; break;
	      }
	    i3.Sort();
	    if (faces.Used (i3))
	      {
		int domnr = faces.Get(i3);
		if (domnr == -1 || domnr == el.GetIndex())
		  {
		    switch (l)
		      {
		      case 0: isface1 = 1; break;
		      case 1: isface2 = 1; break;
		      case 2: isface3 = 1; break;
		      case 3: isface4 = 1; break;
		      }
		  }
	      }
	  }
	/*
	  isface1 = faces.Used (INDEX_3::Sort (el.pnums[k], el.pnums[pi3], el.pnums[pi4]));
	  isface2 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[pi3], el.pnums[pi4]));
	  isface3 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[k], el.pnums[pi4]));
	  isface4 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[k], el.pnums[pi3]));
	*/
	
	isfedge1 = isfedge2 = isfedge3 = isfedge4 = isfedge5 = isfedge6 = 0;
	for (int l = 0; l < 6; l++)
	  {
	    INDEX_2 i2(0,0);
	    switch (l)
	      {
              case 0: i2.I1() = el.pnums[j]; i2.I2() = el[k]; break;
              case 1: i2.I1() = el.pnums[j]; i2.I2() = el.pnums[pi3]; break;
              case 2: i2.I1() = el.pnums[j]; i2.I2() = el.pnums[pi4]; break;
              case 3: i2.I1() = el.pnums[k]; i2.I2() = el.pnums[pi3]; break;
              case 4: i2.I1() = el.pnums[k]; i2.I2() = el.pnums[pi4]; break;
              case 5: i2.I1() = el.pnums[pi3]; i2.I2() = el.pnums[pi4]; break;
	      }
	    i2.Sort();
	    if (face_edges.Used (i2))
	      {
		int domnr = face_edges.Get(i2);
		if (domnr == -1 || domnr == el.GetIndex())
		  {
		    switch (l)
		      {
		      case 0: isfedge1 = 1; break;
		      case 1: isfedge2 = 1; break;
		      case 2: isfedge3 = 1; break;
		      case 3: isfedge4 = 1; break;
		      case 4: isfedge5 = 1; break;
		      case 5: isfedge6 = 1; break;
		      }
		  }
	      }
	  }
	/*
	  isfedge1 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[k]));
	  isfedge2 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi3]));
	  isfedge3 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi4]));
	  isfedge4 = face_edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi3]));
	  isfedge5 = face_edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi4]));
	  isfedge6 = face_edges.Used (INDEX_2::Sort (el.pnums[pi3], el.pnums[pi4]));
	*/
	
	fp1 = fp2 = fp3 = fp4 = 0;
	for (int l = 0; l < 4; l++)
	  {
	    int pti(0);
	    switch (l)
	      {
	      case 0: pti = el.pnums[j]; break;
	      case 1: pti = el.pnums[k]; break;
	      case 2: pti = el.pnums[pi3]; break;
	      case 3: pti = el.pnums[pi4]; break;
	      }
	    int domnr = facepoint[pti];
	    if (domnr == -1 || domnr == el.GetIndex())
	      {
		switch (l)
		  {
		  case 0: fp1 = 1; break;
		  case 1: fp2 = 1; break;
		  case 2: fp3 = 1; break;
		  case 3: fp4 = 1; break;
		  }
	      }
	  }
	
	/*
	  fp1 = facepoint[el.pnums[j]] != 0;
	  fp2 = facepoint[el.pnums[k]] != 0;
	  fp3 = facepoint[el.pnums[pi3]] != 0;
	  fp4 = facepoint[el.pnums[pi4]] != 0;
	*/
	
	
	switch (isface1+isface2+isface3+isface4)
	  {
	  case 0:
	    {
	      isedge1 |= isfedge1;
	      isedge2 |= isfedge2;
	      isedge3 |= isfedge3;
	      isedge4 |= isfedge4;
	      isedge5 |= isfedge5;
	      isedge6 |= isfedge6;
	      
	      ep1 |= fp1;
	      ep2 |= fp2;
	      ep3 |= fp3;
	      ep4 |= fp4;
	      
	      switch (isedge1+isedge2+isedge3+isedge4+isedge5+isedge6)
		{
		case 0:
		  {		
		    if (!ep1 && !ep2 && !ep3 && !ep4)
		      type = HP_TET;
				
		    if (ep1 && !ep2 && !ep3 && !ep4)
		      type = HP_TET_0E_1V;
		    
		    if (ep1 && ep2 && !ep3 && !ep4)
		      type = HP_TET_0E_2V;
		    
		    if (ep1 && ep2 && ep3 && !ep4)
		      type = HP_TET_0E_3V;
		    
		    if (ep1 && ep2 && ep3 && ep4)
		      type = HP_TET_0E_4V;
		    
		    break;
		  }
		  
		case 1:
		  {
		    if (!isedge1) break;
		    
		    if (!cp1 && !cp2 && !ep3 && !ep4)
		      type = HP_TET_1E_0V;
		    
		    if (cp1 && !cp2 && !ep3 && !ep4)
		      type = HP_TET_1E_1VA;
		    
		    if (!cp1 && !cp2 && !ep3 && ep4)
		      type = HP_TET_1E_1VB;
		    
		    if (cp1 && cp2 && !ep3 && !ep4)
		      type = HP_TET_1E_2VA;
		    
		    if (cp1 && !cp2 && ep3 && !ep4)
		      type = HP_TET_1E_2VB;
		    
		    if (cp1 && !cp2 && !ep3 && ep4)
		      type = HP_TET_1E_2VC;
		    
		    if (!cp1 && !cp2 && ep3 && ep4)
		      type = HP_TET_1E_2VD;
		    
		    if (cp1 && cp2 && ep3 && !ep4)
		      type = HP_TET_1E_3VA;
		    
		    if (cp1 && !cp2 && ep3 && ep4)
		      type = HP_TET_1E_3VB;
		    
		    if (cp1 && cp2 && ep3 && ep4)
		      type = HP_TET_1E_4V;
		    
		    break;
		  }
		case 2:
		  {
		    if (isedge1 && isedge2)
		      {
			if (!cp2 && !cp3 && !ep4)
			  type = HP_TET_2EA_0V;
			
			if (cp2 && !cp3 && !ep4)
			  type = HP_TET_2EA_1VA;
			if (!cp2 && cp3 && !ep4)
			  type = HP_TET_2EA_1VB;
			
			if (!cp2 && !cp3 && ep4)
			  type = HP_TET_2EA_1VC;
			
			if (cp2 && cp3 && !ep4)
			  type = HP_TET_2EA_2VA;
			if (cp2 && !cp3 && ep4)
			  type = HP_TET_2EA_2VB;
			if (!cp2 && cp3 && ep4)
			  type = HP_TET_2EA_2VC;
			
			if (cp2 && cp3 && ep4)
			  type = HP_TET_2EA_3V;
		      }
		    if (isedge1 && isedge6)
		      {
			if (!cp1 && !cp2 && !cp3 && !cp4)
			  type = HP_TET_2EB_0V;
			if (cp1 && !cp2 && !cp3 && !cp4)
			  type = HP_TET_2EB_1V;
			if (cp1 && cp2 && !cp3 && !cp4)
			  type = HP_TET_2EB_2VA;
			if (cp1 && !cp2 && cp3 && !cp4)
			  type = HP_TET_2EB_2VB;
			if (cp1 && !cp2 && !cp3 && cp4)
			  type = HP_TET_2EB_2VC;
			if (cp1 && cp2 && cp3 && !cp4)
			  type = HP_TET_2EB_3V;
			if (cp1 && cp2 && cp3 && cp4)
			  type = HP_TET_2EB_4V;
		      }
		    break;
		  }
		case 3:
		  {
		    if (isedge1 && isedge2 && isedge3)
		      {
			if (!cp2 && !cp3 && !cp4)
			  type = HP_TET_3EA_0V;
			if (cp2 && !cp3 && !cp4)
			  type = HP_TET_3EA_1V;
			if (cp2 && cp3 && !cp4)
			  type = HP_TET_3EA_2V;
			if (cp2 && cp3 && cp4)
			  type = HP_TET_3EA_3V;
		      }
		    if (isedge1 && isedge3 && isedge4)
		      {
			if (!cp3 && !cp4)
			  type = HP_TET_3EB_0V;
			if (cp3 && !cp4)
                          type = HP_TET_3EB_1V;
			if (cp3 && cp4)
			  type = HP_TET_3EB_2V;
		      }
		    if (isedge1 && isedge2 && isedge5)
		      {
			if (!cp3 && !cp4)
			  type = HP_TET_3EC_0V;
			if (cp3 && !cp4)
			  type = HP_TET_3EC_1V;
			if (cp3 && cp4)
			  type = HP_TET_3EC_2V;
		      }
		    break;
		  }
		}
	      break;
	    }
	    
	    
	    
	  case 1:  // one singular face
	    {
	      if (!isface1) break;
	      
	      switch (isfedge1+isfedge2+isfedge3+isedge4+isedge5+isedge6)
		{
		case 0:
		  {
		    if (!fp1 && !ep2 && !ep3 && !ep4)
		      type = HP_TET_1F_0E_0V;
		    if (fp1 && !ep2 && !ep3 && !ep4)
		      type = HP_TET_1F_0E_1VB;
		    if (!fp1 && ep2 && !ep3 & !ep4)
		      type = HP_TET_1F_0E_1VA;
		    break;
		  }
		case 1:
		  {
		    if (isfedge1)
		      {
			if (!ep1 && !ep3 && !ep4)
			  type = HP_TET_1F_1EA_0V;
		      }
		    if (isedge4) // V1-V3
		      {
			if (!ep1 && !cp2 && !cp3 && !ep4)
			  type = HP_TET_1F_1EB_0V;
		      }
		    break;
		  }
		}
	      break;
	    }
	    
	    
	  case 2:  // two singular faces
	    {
	      if (!isface1 || !isface2) break;
	      
	      switch (isfedge1+isedge2+isedge3+isedge4+isedge5)
		{
		case 0:
		  {
		    if (!ep1 && !ep2 && !cp3 && !cp4)
		      type = HP_TET_2F_0E_0V;
		    break;
		  }
		}
	      break;
	    }
	    
	    
	  }
	
	if (type != HP_NONE)
	  {
	    int pnums[4]; 
	    pnums[0] = el.pnums[j];
	    pnums[1] = el.pnums[k];
	    pnums[2] = el.pnums[pi3];
	    pnums[3] = el.pnums[pi4];
	    for(k=0;k<4;k++) el.pnums[k] = pnums[k]; 
	    break;
	  }
      }
  
  
  if (debug) cout << "type = " << type << endl;

  if (type == HP_NONE)
    {
      //     cnt_undef++;
      (*testout) << "undefined element" << endl
		 << "cp = " << cp1 << cp2 << cp3 << cp4 << endl
		 << "ep = " << ep1 << ep2 << ep3 << ep4 << endl
		 << "isedge = " << isedge1 << isedge2 << isedge3 
		 << isedge4 << isedge5 << isedge6 << endl
		 << "isface = " << isface1 << isface2 << isface3 << isface4 << endl;
      cout << "undefined element !!! " << endl;

      
    }
  return(type); 
}
Пример #16
0
    void run ()
    {
        testcase ("add/traverse");

        beast::Journal const j;                            // debug journal
        tests::TestFamily f(j);

        // h3 and h4 differ only in the leaf, same terminal node (level 19)
        uint256 h1, h2, h3, h4, h5;
        h1.SetHex ("092891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
        h2.SetHex ("436ccbac3347baa1f1e53baeef1f43334da88f1f6d70d963b833afd6dfa289fe");
        h3.SetHex ("b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
        h4.SetHex ("b92891fe4ef6cee585fdc6fda2e09eb4d386363158ec3321b8123e5a772c6ca8");
        h5.SetHex ("a92891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");

        SHAMap sMap (SHAMapType::FREE, f);
        SHAMapItem i1 (h1, IntToVUC (1)), i2 (h2, IntToVUC (2)), i3 (h3, IntToVUC (3)), i4 (h4, IntToVUC (4)), i5 (h5, IntToVUC (5));
        unexpected (!sMap.addItem (i2, true, false), "no add");
        unexpected (!sMap.addItem (i1, true, false), "no add");

        auto i = sMap.begin();
        auto e = sMap.end();
        unexpected (i == e || (*i != i1), "bad traverse");
        ++i;
        unexpected (i == e || (*i != i2), "bad traverse");
        ++i;
        unexpected (i != e, "bad traverse");
        sMap.addItem (i4, true, false);
        sMap.delItem (i2.key());
        sMap.addItem (i3, true, false);
        i = sMap.begin();
        e = sMap.end();
        unexpected (i == e || (*i != i1), "bad traverse");
        ++i;
        unexpected (i == e || (*i != i3), "bad traverse");
        ++i;
        unexpected (i == e || (*i != i4), "bad traverse");
        ++i;
        unexpected (i != e, "bad traverse");

        testcase ("snapshot");
        SHAMapHash mapHash = sMap.getHash ();
        std::shared_ptr<SHAMap> map2 = sMap.snapShot (false);
        unexpected (sMap.getHash () != mapHash, "bad snapshot");
        unexpected (map2->getHash () != mapHash, "bad snapshot");
        unexpected (!sMap.delItem (sMap.begin()->key()), "bad mod");
        unexpected (sMap.getHash () == mapHash, "bad snapshot");
        unexpected (map2->getHash () != mapHash, "bad snapshot");

        testcase ("build/tear");
        {
            std::vector<uint256> keys(8);
            keys[0].SetHex ("b92891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
            keys[1].SetHex ("b92881fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
            keys[2].SetHex ("b92691fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
            keys[3].SetHex ("b92791fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
            keys[4].SetHex ("b91891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
            keys[5].SetHex ("b99891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
            keys[6].SetHex ("f22891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");
            keys[7].SetHex ("292891fe4ef6cee585fdc6fda1e09eb4d386363158ec3321b8123e5a772c6ca8");

            std::vector<uint256> hashes(8);
            hashes[0].SetHex ("B7387CFEA0465759ADC718E8C42B52D2309D179B326E239EB5075C64B6281F7F");
            hashes[1].SetHex ("FBC195A9592A54AB44010274163CB6BA95F497EC5BA0A8831845467FB2ECE266");
            hashes[2].SetHex ("4E7D2684B65DFD48937FFB775E20175C43AF0C94066F7D5679F51AE756795B75");
            hashes[3].SetHex ("7A2F312EB203695FFD164E038E281839EEF06A1B99BFC263F3CECC6C74F93E07");
            hashes[4].SetHex ("395A6691A372387A703FB0F2C6D2C405DAF307D0817F8F0E207596462B0E3A3E");
            hashes[5].SetHex ("D044C0A696DE3169CC70AE216A1564D69DE96582865796142CE7D98A84D9DDE4");
            hashes[6].SetHex ("76DCC77C4027309B5A91AD164083264D70B77B5E43E08AEDA5EBF94361143615");
            hashes[7].SetHex ("DF4220E93ADC6F5569063A01B4DC79F8DB9553B6A3222ADE23DEA02BBE7230E5");

            SHAMap map (SHAMapType::FREE, f);

            expect (map.getHash() == zero, "bad initial empty map hash");
            for (int i = 0; i < keys.size(); ++i)
            {
                SHAMapItem item (keys[i], IntToVUC (i));
                map.addItem (item, true, false);
                expect (map.getHash().as_uint256() == hashes[i], "bad buildup map hash");
            }
            for (int i = keys.size() - 1; i >= 0; --i)
            {
                expect (map.getHash().as_uint256() == hashes[i], "bad teardown hash");
                map.delItem (keys[i]);
            }
            expect (map.getHash() == zero, "bad final empty map hash");
        }
    }
Пример #17
0
void simdetect (
    int    *detect,     /* detector -1 single, 0 multi, 1 proximity, 2 count,... */
    double *gsb0val,    /* Parameter values (matrix nr= comb of g0,sigma,b nc=3) [naive animal] */
    double *gsb1val,    /* Parameter values (matrix nr= comb of g0,sigma,b nc=3) [caught before] */
    int    *cc0,        /* number of g0/sigma/b combinations for naive animals */
    int    *cc1,        /* number of g0/sigma/b combinations for caught before */
    int    *gsb0,       /* lookup which g0/sigma/b combination to use for given g, S, K
                           [naive animal] */
    int    *gsb1,       /* lookup which g0/sigma/b combination to use for given n, S, K 
                           [caught before] */
    int    *N,          /* number of animals */
    int    *ss,         /* number of occasions */
    int    *kk,         /* number of traps */
    int    *nmix,       /* number of classes */
    int    *knownclass, /* known membership of 'latent' classes */
    double *animals,    /* x,y points of animal range centres (first x, then y) */
    double *traps,      /* x,y locations of traps (first x, then y) */
    double *dist2,      /* distances squared (optional: -1 if unused) */
    double *Tsk,        /* ss x kk array of 0/1 usage codes or effort */
    int    *btype,      /* code for behavioural response 
                           0 none
                           1 individual
                           2 individual, trap-specific
                           3 trap-specific
                        */
    int    *Markov,     /* learned vs transient behavioural response 
                           0 learned
                           1 Markov 
                        */
    int    *binomN,     /* number of trials for 'count' detector modelled with binomial */
    double *miscparm,   /* detection threshold on transformed scale, etc. */
    int    *fn,         /* code 0 = halfnormal, 1 = hazard, 2 = exponential, 3 = uniform */
    int    *maxperpoly, /*  */
    int    *n,          /* number of individuals caught */
    int    *caught,     /* sequence number in session (0 if not caught) */
    double *detectedXY, /* x,y locations of detections  */
    double *signal,     /* vector of signal strengths, one per detection */
    int    *value,      /* return value array of trap locations n x s */
    int    *resultcode
)
{
    double d2val;
    double p;
    int    i,j,k,l,s;
    int    ik;
    int    nc = 0;
    int    nk = 0;             /* number of detectors (polygons or transects when *detect==6,7) */
    int    count = 0;
    int    *caughtbefore;
    int    *x;                 /* mixture class of animal i */
    double *pmix;
    double runif;
    int    wxi = 0;
    int    c = 0;
    int    gpar = 2;
    double g0 = 0;
    double sigma = 0;
    double z = 0;
    double Tski = 1.0;  
    double *work = NULL;
    double *noise = NULL;   /* detectfn 12,13 only */
    int    *sortorder = NULL;
    double *sortkey = NULL;

    /*
        *detect may take values -
       -1  single-catch traps
        0  multi-catch traps
        1  binary proximity detectors
        2  count  proximity detectors
        5  signal detectors
        6  polygon detectors
        7  transect detectors
    */
    /*========================================================*/
    /* 'single-catch only' declarations */
    int    tr_an_indx = 0;
    int    nanimals;
    int    ntraps;
    int    *occupied = NULL;
    int    *intrap = NULL;
    struct trap_animal *tran = NULL;
    double event_time;
    int    anum = 0;
    int    tnum = 0;
    int    nextcombo;
    int    finished;
    int    OK;

    /*========================================================*/
    /* 'multi-catch only' declarations */
    double *h = NULL;          /* multi-catch only */
    double *hsum = NULL;       /* multi-catch only */
    double *cump = NULL;       /* multi-catch only */

    /*========================================================*/
    /* 'polygon & transect only' declarations */
    int    nd = 0;
    int    cumk[maxnpoly+1];
    int    sumk;               /* total number of vertices */
    int    g=0;
    int    *gotcha;
    double xy[2];
    int    n1,n2,t;
    double par[3];
    int    np = 1;             /* n points each call of gxy */
    double w, ws;
    int    maxdet=1;
    double *cumd = NULL;
    struct rpoint *line = NULL;
    struct rpoint xyp;
    struct rpoint animal;
    double lx;
    double maxg = 0;
    double lambdak;  /* temp value for Poisson rate */
    double grx;      /* temp value for integral gr */
    double H;
    int    J;
    int    maybecaught;
    double dx,dy,d;
    double pks;
    double sumhaz;
    /*========================================================*/
    /* 'signal-strength only' declarations */
    double beta0;
    double beta1;
    double muS;
    double sdS;
    double muN = 0;
    double sdN = 1;
    double signalvalue;
    double noisevalue;
    double cut;
    double *ex;
    /*========================================================*/
    /* MAIN LINE */

    gotcha = &g;
    *resultcode = 1;
    caughtbefore = (int *) R_alloc(*N * *kk, sizeof(int));
    x = (int *) R_alloc(*N, sizeof(int));
    for (i=0; i<*N; i++) x[i] = 0;
    pmix = (double *) R_alloc(*nmix, sizeof(double));

    /* ------------------------------------------------------ */
    /* pre-compute distances */
    if (dist2[0] < 0) {
	dist2 = (double *) S_alloc(*kk * *N, sizeof(double));
	makedist2 (*kk, *N, traps, animals, dist2);
    }
    else {
	squaredist (*kk, *N, dist2);
    }
    /* ------------------------------------------------------ */

    if ((*detect < -1) || (*detect > 7)) return;

    if (*detect == -1) {                                   /* single-catch only */
        occupied = (int*) R_alloc(*kk, sizeof(int));
        intrap = (int*) R_alloc(*N, sizeof(int));
        tran = (struct trap_animal *) R_alloc(*N * *kk,
            sizeof(struct trap_animal));
	    /*  2*sizeof(int) + sizeof(double)); */
    }
    if (*detect == 0) {                                    /* multi-catch only */
        h = (double *) R_alloc(*N * *kk, sizeof(double));
        hsum = (double *) R_alloc(*N, sizeof(double));
        cump = (double *) R_alloc(*kk+1, sizeof(double));
        cump[0] = 0;
    }

    if (*detect == 5) {                                    /* signal only */
        maxdet = *N * *ss * *kk;
        if (!((*fn == 10) || (*fn == 11)))
            error ("simsecr not implemented for this combination of detector & detectfn");
    }

    if ((*detect == 3) || (*detect == 4) || (*detect == 6) || (*detect == 7)) {
        /* polygon or transect */
        cumk[0] = 0;
        for (i=0; i<maxnpoly; i++) {                       /* maxnpoly much larger than npoly */
            if (kk[i]<=0) break;
            cumk[i+1] = cumk[i] + kk[i];
            nk++;
        }
        sumk = cumk[nk];
        if ((*detect == 6) || (*detect == 7))
            maxdet = *N * *ss * nk * *maxperpoly;
        else 
            maxdet = *N * *ss;
    }
    else nk = *kk;

    if ((*detect == 4) || (*detect == 7)) {                            /* transect only */
        line = (struct rpoint *) R_alloc(sumk, sizeof(struct rpoint));
        cumd = (double *) R_alloc(sumk, sizeof(double));
        /* coordinates of vertices */
        for (i=0; i<sumk; i++) {
            line[i].x = traps[i];
            line[i].y = traps[i+sumk];
        }
        /* cumulative distance along line; all transects end on end */
        for (k=0; k<nk; k++) {
            cumd[cumk[k]] = 0;
            for (i=cumk[k]; i<(cumk[k+1]-1); i++) {
                cumd[i+1] = cumd[i] + distance(line[i], line[i+1]);
            }
        }
    }

    if ((*detect==3) || (*detect==4) || (*detect==5) || (*detect==6) || (*detect==7)) {
        work = (double*) R_alloc(maxdet*2, sizeof(double));   /* twice size needed for signal */
        sortorder = (int*) R_alloc(maxdet, sizeof(int));
        sortkey = (double*) R_alloc(maxdet, sizeof(double));
    }
    if ((*fn==12) || (*fn==13)) {
        noise = (double*) R_alloc(maxdet*2, sizeof(double));   /* twice size needed for signal */
    }

    GetRNGstate();

    gpar = 2;
    if ((*fn == 1) || (*fn == 3) || (*fn == 5)|| (*fn == 6) || (*fn == 7) || (*fn == 8) ||
        (*fn == 10) || (*fn == 11)) gpar ++;

    /* ------------------------------------------------------------------------- */
    /* mixture models */
    /* may be better to pass pmix */
    if (*nmix>1) {
        if (*nmix>2)
            error("simsecr nmix>2 not implemented");
        gpar++;   /* these models have one more detection parameter */
        for (i=0; i<*nmix; i++) {
            wxi = i4(0,0,0,i,*N,*ss,nk);
            c = gsb0[wxi] - 1;
            pmix[i] = gsb0val[*cc0 * (gpar-1) + c];    /* assuming 4-column gsb */
        }
        for (i=0; i<*N; i++) {
	    if (knownclass[i] > 1) 
		x[i] = knownclass[i] - 2;      /* knownclass=2 maps to x=0 etc. */
	    else
		x[i] = rdiscrete(*nmix, pmix) - 1;
        }
    }

    /* ------------------------------------------------------------------------- */
    /* zero caught status */
    for (i=0; i<*N; i++) 
        caught[i] = 0;    
    for (i=0; i<*N; i++) 
        for (k=0; k < nk; k++)
            caughtbefore[k * (*N-1) + i] = 0;

    /* ------------------------------------------------------------------------- */
    /* MAIN LOOP */
    for (s=0; s<*ss; s++) {

        /* ------------------ */
        /* single-catch traps */
        if (*detect == -1) {
            /* initialise day */
            tr_an_indx = 0;
            nanimals = *N;
            ntraps   = nk;
            for (i=0; i<*N; i++) intrap[i] = 0;
            for (k=0; k<nk; k++) occupied[k] = 0;
            nextcombo = 0;

            /* make tran */
            for (i=0; i<*N; i++) {  /* animals */
                for (k=0; k<nk; k++) { /* traps */
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
			/* d2val = d2(i,k, animals, traps, *N, nk); */
			d2val = d2L(k, i, dist2, nk);
                        p = pfn(*fn, d2val, g0, sigma, z, miscparm, 1e20);  /* effectively inf w2 */

			if (fabs(Tski-1) > 1e-10) 
			    p = 1 - pow(1-p, Tski);
                        
                        event_time = randomtime(p);
                        if (event_time <= 1) {
                            tran[tr_an_indx].time   = event_time;
                            tran[tr_an_indx].animal = i;    /* 0..*N-1 */
                            tran[tr_an_indx].trap   = k;    /* 0..nk-1 */
                            tr_an_indx++;
                        }
                    }
                }
            }
            /* end of make tran */

            if (tr_an_indx > 1) probsort (tr_an_indx, tran);

            while ((nextcombo < tr_an_indx) && (nanimals>0) && (ntraps>0)) {
                    finished = 0;
                OK       = 0;
                    while ((1-finished)*(1-OK) > 0) {      /* until finished or OK */
                    if (nextcombo >= (tr_an_indx))
                            finished = 1;                  /* no more to process */
                    else {
                            anum = tran[nextcombo].animal;
                        tnum = tran[nextcombo].trap;
                            OK = (1-occupied[tnum]) * (1-intrap[anum]); /* not occupied and not intrap */
                        nextcombo++;
                        }
                }
                    if (finished==0) {
                       /* Record this capture */
                          occupied[tnum] = 1;
                      intrap[anum]   = tnum+1;         /* trap = k+1 */
                          nanimals--;
                      ntraps--;
                    }
            }
                for (i=0; i<*N; i++) {
                if (intrap[i]>0) {
                    if (caught[i]==0) {                    /* first capture of this animal */
                       nc++;
                       caught[i] = nc;                     /* nc-th animal to be captured */
                       for (j=0; j<*ss; j++)
                           value[*ss * (nc-1) + j] = 0;
                    }
                    value[*ss * (caught[i]-1) + s] = intrap[i];  /* trap = k+1 */
                }
            }
        }

        /* -------------------------------------------------------------------------- */
        /* multi-catch trap; only one site per occasion (drop last dimension of capt) */
        else if (*detect == 0) {
            for (i=0; i<*N; i++) {
                hsum[i] = 0;
                for (k=0; k<nk; k++) {
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
			getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
				bswitch (*btype, *N, i, k, caughtbefore), 
				gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
			/* d2val = d2(i,k, animals, traps, *N, nk); */
			d2val = d2L(k, i, dist2, nk);
			p = pfn(*fn, d2val, g0, sigma, z, miscparm, 1e20);
			h[k * *N + i] = - Tski * log(1 - p);
			hsum[i] += h[k * *N + i];
		    }
                }

                for (k=0; k<nk; k++) {
                    cump[k+1] = cump[k] + h[k * *N + i]/hsum[i];
                }
                if (Random() < (1-exp(-hsum[i]))) {
                    if (caught[i]==0)  {        /* first capture of this animal */
                        nc++;
                        caught[i] = nc;
                        for (j=0; j<*ss; j++)
                            value[*ss * (nc-1) + j] = 0;
                    }
                    /* find trap with probability proportional to p
                       searches cumulative distribution of p  */
                    runif = Random();
                    k = 0;
                    while ((runif > cump[k]) && (k<nk)) k++;
                    value[*ss * (caught[i]-1) + s] = k;  /* trap = k+1 */
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* the 'proximity' group of detectors 1:2 - proximity, count */
        else if ((*detect >= 1) && (*detect <= 2)) {
            for (i=0; i<*N; i++) {
                for (k=0; k<nk; k++) {
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
			/* d2val = d2(i,k, animals, traps, *N, nk); */
			d2val = d2L(k, i, dist2, nk);
                        p = pfn(*fn, d2val, g0, sigma, z, miscparm, 1e20);

                        if (p < -0.1) { PutRNGstate(); return; }   /* error */

                        if (p>0) {
                            if (*detect == 1) {
				if (fabs(Tski-1) > 1e-10)
				    p = 1 - pow(1-p, Tski);
                                count = Random() < p;            /* binary proximity */
                            }
                            else if (*detect == 2) {             /* count proximity */
				if (*binomN == 1)
				    count = rcount(round(Tski), p, 1);
				else
				    count = rcount(*binomN, p, Tski);
                            }
                            if (count>0) {
                                if (caught[i]==0) {              /* first capture of this animal */
                                    nc++;
                                    caught[i] = nc;
                                    for (j=0; j<*ss; j++)
                                      for (l=0; l<nk; l++)
                                        value[*ss * ((nc-1) * nk + l) + j] = 0;
                                }
                                value[*ss * ((caught[i]-1) * nk + k) + s] = count;
                            }
                        }
                    }
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* exclusive polygon detectors  */
        else if (*detect == 3) {
            /* find maximum distance between animal and detector vertex */
            w = 0;
            J = cumk[nk];
            for (i = 0; i< *N; i++) {
                for (j = 0; j < J; j++) {
                    dx = animals[i] - traps[j];
                    dy = animals[*N + i] - traps[J + j];
        	    d = sqrt(dx*dx + dy*dy);
                    if (d > w) w = d;
                }
            } 

            for (i=0; i<*N; i++) {
                /* this implementation assumes NO VARIATION AMONG DETECTORS */
                getpar (i, s, 0, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
		    bswitch (*btype, *N, i, 0, caughtbefore), 
                    gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);

                maybecaught = Random() < g0;

                if (w > (10 * sigma)) 
                    ws = 10 * sigma;
                else 
                    ws = w;

                par[0] = 1;
                par[1] = sigma;
                par[2] = z;
                
                if (maybecaught) {
                    gxy (&np, fn, par, &ws, xy);                 /* simulate location */
                    xy[0] = xy[0] + animals[i];
                    xy[1] = xy[1] + animals[*N + i];
                    for (k=0; k<nk; k++) {                      /* each polygon */
			Tski = Tsk[s * nk + k];
			if (fabs(Tski) > 1e-10) {
                            n1 = cumk[k];
                            n2 = cumk[k+1]-1;
                            inside(xy, &n1, &n2, &sumk, traps, gotcha);  /* assume closed */
                            if (*gotcha > 0) {
                                if (caught[i]==0) {             /* first capture of this animal */
                                    nc++;
                                    caught[i] = nc;
                                    for (t=0; t<*ss; t++)
                                            value[*ss * (nc-1) + t] = 0;
                                }
                                nd++;
                                value[*ss * (caught[i]-1) + s] = k+1;
                                work[(nd-1)*2] = xy[0];
                                work[(nd-1)*2+1] = xy[1];
                                sortkey[nd-1] = (double) (s * *N + caught[i]);
                                break;   /* no need to look at more poly */
                            }
                        }
                    }
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* exclusive transect detectors  */
        else if (*detect == 4) {
	    ex = (double *) R_alloc(10 + 2 * maxvertices, sizeof(double));
            for (i=0; i<*N; i++) {                            /* each animal */
                animal.x = animals[i];
                animal.y = animals[i + *N];
                sumhaz = 0;
                /* ------------------------------------ */
                /* sum hazard */
                for (k=0; k<nk; k++) {            
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
				bswitch (*btype, *N, i, k, caughtbefore), 
				gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
	                par[0] = g0;
                        par[1] = sigma;
                        par[2] = z;
                        n1 = cumk[k];
                        n2 = cumk[k+1]-1;
                        H = hintegral1(*fn, par);
                        sumhaz += -log(1 - par[0] * integral1D (*fn, i, 0, par, 1, traps, 
			    animals, n1, n2, sumk, *N, ex) / H);
                    }
                }
                /* ------------------------------------ */

                for (k=0; k<nk; k++) {                        /* each transect */
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
   			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
	                par[0] = g0;
                        par[1] = sigma;
                        par[2] = z;
                        n1 = cumk[k];
                        n2 = cumk[k+1]-1;
                        H = hintegral1(*fn, par);
                        lambdak = par[0] * integral1D (*fn, i, 0, par, 1, traps, animals,
						       n1, n2, sumk, *N, ex) / H;
    	                pks = (1 - exp(-sumhaz)) * (-log(1-lambdak)) / sumhaz;
                        count = Random() < pks;
                        maxg = 0;
                        if (count>0) {                       /* find maximum - approximate */
                            for (l=0; l<=100; l++) {
                                lx = (cumd[n2] - cumd[n1]) * l/100;
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            for (l=n1; l<=n2; l++) {
                                xyp = line[l];
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            maxg= 1.2 * maxg;                 /* safety margin */
                            if (maxg<=0)
                                Rprintf("maxg error in simsecr\n"); /* not found */
                            *gotcha = 0;
                            l = 0;
                            while (*gotcha == 0) {
                                lx = Random() * (cumd[n2] - cumd[n1]);     /* simulate location */
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (Random() < (grx/maxg))    /* rejection sampling */
                                    *gotcha = 1;
                                l++;
                                if (l % 10000 == 0)
                                    R_CheckUserInterrupt();
                                if (l>1e8) *gotcha = 1;       /* give up and accept anything!!!! */
                            }
                            if (caught[i]==0) {               /* first capture of this animal */
                                nc++;
                                caught[i] = nc;
                                for (t=0; t<*ss; t++)
                                        value[*ss * (nc-1) + t] = 0;
                            }
                            nd++;
                            if (nd >= maxdet) {
                                *resultcode = 2;  /* error */
                                return;
                            }
                            value[*ss * (caught[i]-1) + s] = k+1;
                            work[(nd-1)*2] = xyp.x;
                            work[(nd-1)*2+1] = xyp.y;
                            sortkey[nd-1] = (double) (s * *N + caught[i]);
                        }
                        if (count>0) break;   /* no need to look further */
                    }
                }                                             /* end loop over transects */
            }                                                 /* end loop over animals */
        }

        /* -------------------------------------------------------------------------------- */
        /* polygon detectors  */
        else if (*detect == 6) {
            for (i=0; i<*N; i++) {
                /* this implementation assumes NO VARIATION AMONG DETECTORS */

                getpar (i, s, 0, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
		    bswitch (*btype, *N, i, 0, caughtbefore), 
                    gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
                count = rcount(*binomN, g0, Tski);
                w = 10 * sigma;
                par[0] = 1;
                par[1] = sigma;
                par[2] = z;
                for (j=0; j<count; j++) {
                    gxy (&np, fn, par, &w, xy);                 /* simulate location */
                    xy[0] = xy[0] + animals[i];
                    xy[1] = xy[1] + animals[*N + i];
                    for (k=0; k<nk; k++) {                      /* each polygon */
			Tski = Tsk[s * nk + k];
			if (fabs(Tski) > 1e-10) {
                            n1 = cumk[k];
                            n2 = cumk[k+1]-1;
                            inside(xy, &n1, &n2, &sumk, traps, gotcha);  /* assume closed */
                            if (*gotcha > 0) {
                                if (caught[i]==0) {             /* first capture of this animal */
                                    nc++;
                                    caught[i] = nc;
                                    for (t=0; t<*ss; t++)
                                        for (l=0; l<nk; l++)
                                            value[*ss * ((nc-1) * nk + l) + t] = 0;
                                }
                                nd++;
                                if (nd > maxdet) {
                                    *resultcode = 2;
                                    return;  /* error */
                                }
                                value[*ss * ((caught[i]-1) * nk + k) + s]++;
                                work[(nd-1)*2] = xy[0];
                                work[(nd-1)*2+1] = xy[1];
                                sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
                            }
                        }
                    }
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* transect detectors  */
        else if (*detect == 7) {
	    ex = (double *) R_alloc(10 + 2 * maxvertices, sizeof(double));
            for (i=0; i<*N; i++) {                            /* each animal */
                animal.x = animals[i];
                animal.y = animals[i + *N];
                for (k=0; k<nk; k++) {                        /* each transect */
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
 			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
	                par[0] = g0;
                        par[1] = sigma;
                        par[2] = z;
                        n1 = cumk[k];
                        n2 = cumk[k+1]-1;
                        H = hintegral1(*fn, par);
                        lambdak = par[0] * integral1D (*fn, i, 0, par, 1, traps, animals,
						       n1, n2, sumk, *N, ex) / H;
                        count = rcount(*binomN, lambdak, Tski);  /* numb detections on transect */
                        maxg = 0;
                        if (count>0) {                       /* find maximum - approximate */
                            for (l=0; l<=100; l++) {
                                lx = (cumd[n2]-cumd[n1]) * l/100;
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            for (l=n1; l<=n2; l++) {
                                xyp = line[l];
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            maxg= 1.2 * maxg;                 /* safety margin */
                            if (maxg<=0)
                                Rprintf("maxg error in simsecr\n"); /* not found */

                        }
                        for (j=0; j<count; j++) {
                            *gotcha = 0;
                            l = 0;
                            while (*gotcha == 0) {
                                lx = Random() * (cumd[n2]-cumd[n1]);     /* simulate location */
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (Random() < (grx/maxg))   /* rejection sampling */
                                    *gotcha = 1;
                                l++;
                                if (l % 10000 == 0)
                                    R_CheckUserInterrupt();
                                if (l>1e8) *gotcha = 1;        /* give up and accept anything!!!! */
                            }
                            if (caught[i]==0) {               /* first capture of this animal */
                                nc++;
                                caught[i] = nc;
                                for (t=0; t<*ss; t++)
                                    for (l=0; l<nk; l++)
                                        value[*ss * ((nc-1) * nk + l) + t] = 0;
                            }
                            nd++;
                            if (nd >= maxdet) {
                                *resultcode = 2;  /* error */
                                return;
                            }
                            value[*ss * ((caught[i]-1) * nk + k) + s]++;
                            work[(nd-1)*2] = xyp.x;
                            work[(nd-1)*2+1] = xyp.y;
                            sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
                        }
                    }
                }                                             /* end loop over transects */
            }                                                 /* end loop over animals */
        }

        /* ------------------------ */
        /* signal strength detector */
        else if (*detect == 5) {
	    cut = miscparm[0];
	    if ((*fn == 12) || (*fn == 13)) {
		muN = miscparm[1];
		sdN = miscparm[2];
	    }
            for (i=0; i<*N; i++) {
                for (k=0; k<nk; k++) {
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        /* sounds not recaptured */
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
				0, gsb0, gsb0val, gsb0, gsb0val, &beta0, &beta1, &sdS);
                        /*
                        if ((*fn == 10) || (*fn == 12))
			    muS  = mufn (i, k, beta0, beta1, animals, traps, *N, nk, 0);
                        else
                            muS  = mufn (i, k, beta0, beta1, animals, traps, *N, nk, 1);
                        */
			if ((*fn == 10) || (*fn == 12))
			    muS  = mufnL (k, i, beta0, beta1, dist2, nk, 0);
			else
			    muS  = mufnL (k, i, beta0, beta1, dist2, nk, 1);

			signalvalue = norm_rand() * sdS + muS;
                        if ((*fn == 10) || (*fn == 11)) {
			    if (signalvalue > cut) {
				if (caught[i]==0) {        /* first capture of this animal */
				    nc++;
				    caught[i] = nc;
				    for (j=0; j<*ss; j++)
					for (l=0; l<nk; l++)
					    value[*ss * ((nc-1) * *kk + l) + j] = 0;
				}
				nd++;
				value[*ss * ((caught[i]-1) * *kk + k) + s] = 1;
				work[nd-1] = signalvalue;
				sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
			    }
			}
			else {
			    noisevalue = norm_rand() * sdN + muN;
			    if ((signalvalue - noisevalue) > cut) {
				if (caught[i]==0) {        /* first capture of this animal */
				    nc++;
				    caught[i] = nc;
				    for (j=0; j<*ss; j++)
					for (l=0; l<nk; l++)
					    value[*ss * ((nc-1) * *kk + l) + j] = 0;
				}
				nd++;
				value[*ss * ((caught[i]-1) * *kk + k) + s] = 1;
				work[nd-1] = signalvalue;
				noise[nd-1] = noisevalue;
				sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
			    }
			}
		    }
                }
            }
        }

	if ((*btype > 0) && (s < (*ss-1))) {
            /* update record of 'previous-capture' status */
            if (*btype == 1) {
                for (i=0; i<*N; i++) {
                    if (*Markov) 
                        caughtbefore[i] = 0;
                    for (k=0; k<nk; k++)
                        caughtbefore[i] = imax2 (value[i3(s, k, i, *ss, nk)], caughtbefore[i]);
                }
            }
            else if (*btype == 2) {
                for (i=0; i<*N; i++) {
                    for (k=0; k<nk; k++) {
                        ik = k * (*N-1) + i;
                        if (*Markov) 
                            caughtbefore[ik] = value[i3(s, k, i, *ss, nk)];
                        else 
                            caughtbefore[ik] = imax2 (value[i3(s, k, i, *ss, nk)], 
			        caughtbefore[ik]);
		    }
		}
            }
	    else {
                for (k=0;k<nk;k++) {
                    if (*Markov) 
                        caughtbefore[k] = 0;
                    for (i=0; i<*N; i++) 
                        caughtbefore[k] = imax2 (value[i3(s, k, i, *ss, nk)], caughtbefore[k]);
                }
	    }
	}

    }   /* loop over s */

    if ((*detect==3) || (*detect==4) || (*detect==5) || (*detect==6) || (*detect==7)) {
        for (i=0; i<nd; i++) sortorder[i] = i;
        if (nd>0) rsort_with_index (sortkey, sortorder, nd);
        if (*detect==5) {
            for (i=0; i<nd; i++) signal[i] = work[sortorder[i]];
	    if ((*fn == 12) || (*fn == 13)) {
		for (i=0; i<nd; i++) signal[i+nd] = noise[sortorder[i]];
	    }
	}
        else {
            for (i=0; i<nd; i++) {
                detectedXY[i]    = work[sortorder[i]*2];
                detectedXY[i+nd] = work[sortorder[i]*2+1];
            }
        }
    }
    *n = nc;
    PutRNGstate();
    *resultcode = 0;
}