Esempio n. 1
0
void btGImpactCollisionAlgorithm::shape_vs_shape_collision(
					  const btCollisionObjectWrapper * body0Wrap,
					  const btCollisionObjectWrapper* body1Wrap,
					  const btCollisionShape * shape0,
					  const btCollisionShape * shape1)
{


	{
		btCollisionObjectWrapper ob0(body0Wrap,shape0,body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform());
		btCollisionObjectWrapper ob1(body1Wrap,shape1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform());

		btCollisionAlgorithm* algor = newAlgorithm(&ob0,&ob1);
		// post :	checkManifold is called

		m_resultOut->setShapeIdentifiersA(m_part0,m_triface0);
		m_resultOut->setShapeIdentifiersB(m_part1,m_triface1);

		algor->processCollision(&ob0,&ob1,*m_dispatchInfo,m_resultOut);

		algor->~btCollisionAlgorithm();
		m_dispatcher->freeCollisionAlgorithm(algor);
	}

}
float collisionTester::collisionTest(btCollisionObject * objectA, btCollisionObject * objectB, btCollisionAlgorithm * algo){
    
    float dist = 99999;
    
    btCollisionObjectWrapper ob0(0,objectA->getCollisionShape(),objectA, objectA->getWorldTransform());
    btCollisionObjectWrapper ob1(0,objectB->getCollisionShape(),objectB, objectB->getWorldTransform());
//    
//	btCollisionAlgorithm* algo = collisionWorld->getDispatcher()->findAlgorithm(&ob0, &ob1);
    
	btManifoldResult contactPointResult(&ob0,&ob1);
	algo->processCollision(&ob0,&ob1,collisionWorld->getDispatchInfo(),&contactPointResult);
	
	btManifoldArray manifoldArray;
	algo->getAllContactManifolds(manifoldArray);
    
	int numManifolds = manifoldArray.size();
	for(int i=0;i<numManifolds;i++)
	{
		btPersistentManifold* contactManifold = manifoldArray[i];
		const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
        //	btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
        
	
		int numContacts = contactManifold->getNumContacts();
		bool swap = obA == objectA;
        
        //printf("numManifolds=%i, numContact = %i \n", numManifolds, numContacts);
        
		for (int j=0;j<numContacts;j++)
		{
			btManifoldPoint& pt = contactManifold->getContactPoint(j);
            
//          glDisable(GL_DEPTH_TEST);
//			glBegin(GL_LINES);
//			glColor3f(0, 0, 1);
			btVector3 ptA = swap ?pt.getPositionWorldOnA():pt.getPositionWorldOnB();
			btVector3 ptB = swap ? pt.getPositionWorldOnB():pt.getPositionWorldOnA();
//			glVertex3d(ptA.x(),ptA.y(),ptA.z());
//			glVertex3d(ptB.x(),ptB.y(),ptB.z());
            
            //contactPts.push_back(ptA);
            //contactPts.push_back(ptB);
            
//			glEnd();

            float distTmp = pt.getDistance();
            if(distTmp<dist)
                dist=distTmp;
                        
		}
        
		//you can un-comment out this line, and then all points are removed
		contactManifold->clearManifold();	
	}
    
    return dist;
}
Esempio n. 3
0
void main()
{
 clrscr();
 derived ob1(1);
 derived *ob2;
 ob2=new derived(2);
  {
   derived ob3(3);
  }
 delete(ob2);
 getch();
}
/************************************************  Program 3 Continued....  **************************************************/
void prog3()
{
	loc ob1(10, 20), ob2(5, 30), ob3(90, 90);
	ob1.show();
	ob2.show();
	++ob1;
	ob1.show(); // displays 11 21
	ob2 = ++ob1;
	ob1.show(); // displays 12 22
	ob2.show(); // displays 12 22
	ob1 = ob2 = ob3; // multiple assignment
	ob1.show(); // displays 90 90
	ob2.show(); // displays 90 90
}
void btGImpactCollisionAlgorithm::convex_vs_convex_collision(
	const btCollisionObjectWrapper* body0Wrap,
	const btCollisionObjectWrapper* body1Wrap,
	const btCollisionShape* shape0,
	const btCollisionShape* shape1)
{
	m_resultOut->setShapeIdentifiersA(m_part0, m_triface0);
	m_resultOut->setShapeIdentifiersB(m_part1, m_triface1);

	btCollisionObjectWrapper ob0(body0Wrap, shape0, body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform(), m_part0, m_triface0);
	btCollisionObjectWrapper ob1(body1Wrap, shape1, body1Wrap->getCollisionObject(), body1Wrap->getWorldTransform(), m_part1, m_triface1);
	checkConvexAlgorithm(&ob0, &ob1);
	m_convex_algorithm->processCollision(&ob0, &ob1, *m_dispatchInfo, m_resultOut);
}
void btHfFluidBuoyantShapeCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
	const btHfFluidBuoyantConvexShape* tmpShape0 = (const btHfFluidBuoyantConvexShape*)body0Wrap->getCollisionShape();
	const btHfFluidBuoyantConvexShape* tmpShape1 = (const btHfFluidBuoyantConvexShape*)body1Wrap->getCollisionShape();
	const btConvexShape* convexShape0 = tmpShape0->getConvexShape();
	const btConvexShape* convexShape1 = tmpShape1->getConvexShape();

	//body0->setCollisionShape (convexShape0);
	//body1->setCollisionShape (convexShape1);

	btCollisionObjectWrapper ob0(body0Wrap,convexShape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform());
	btCollisionObjectWrapper ob1(body1Wrap,convexShape1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform());
	m_convexConvexAlgorithm.processCollision (&ob0, &ob1, dispatchInfo,resultOut);

	
}
void prog2()
{
	int abcd;
	loc ob1(10, 20), ob2(5, 30);
	ob1.show(); // displays 10 20
	ob2.show(); // displays 5 30
	//ob1 = 
	// abcd =	ob1 + ;

	//ob1 = 
	abcd =	ob1.operator+();

	ob1++;
	++ob1;

	ob1.show(); // displays 15 50
}
Esempio n. 8
0
void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap,
				  const btCollisionObjectWrapper* body1Wrap,
				  const btGImpactShapeInterface * shape0,
				  const btCompoundShape * shape1,bool swapped)
{
	btTransform orgtrans1 = body1Wrap->getWorldTransform();

	int i = shape1->getNumChildShapes();
	while(i--)
	{

		const btCollisionShape * colshape1 = shape1->getChildShape(i);
		btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i);

		btCollisionObjectWrapper ob1(body1Wrap,colshape1,body1Wrap->getCollisionObject(),childtrans1);
		//collide child shape
		gimpact_vs_shape(body0Wrap, &ob1,
					  shape0,colshape1,swapped);
	}
}
void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap,
														   const btCollisionObjectWrapper* body1Wrap,
														   const btGImpactShapeInterface* shape0,
														   const btCompoundShape* shape1, bool swapped)
{
	btTransform orgtrans1 = body1Wrap->getWorldTransform();

	int i = shape1->getNumChildShapes();
	while (i--)
	{
		const btCollisionShape* colshape1 = shape1->getChildShape(i);
		btTransform childtrans1 = orgtrans1 * shape1->getChildTransform(i);

		btCollisionObjectWrapper ob1(body1Wrap, colshape1, body1Wrap->getCollisionObject(), childtrans1, -1, i);

		const btCollisionObjectWrapper* tmp = 0;
		if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob1.getCollisionObject())
		{
			tmp = m_resultOut->getBody0Wrap();
			m_resultOut->setBody0Wrap(&ob1);
		}
		else
		{
			tmp = m_resultOut->getBody1Wrap();
			m_resultOut->setBody1Wrap(&ob1);
		}
		//collide child shape
		gimpact_vs_shape(body0Wrap, &ob1,
						 shape0, colshape1, swapped);

		if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob1.getCollisionObject())
		{
			m_resultOut->setBody0Wrap(tmp);
		}
		else
		{
			m_resultOut->setBody1Wrap(tmp);
		}
	}
}
Esempio n. 10
0
void main()
{
 float no1,no2;
 char op,choice;
 do
  {
   clrscr();
   cout<<"\n\n\t\tEnter the first number : ";
   cin>>no1;
   cout<<"\t\tEnter the second number : ";
   cin>>no2;
   cout<<"\t\tEnter the operator (+,-,*,/) : ";
   cin>>op;
   calculator ob1(no1,no2,op);
   if(ob1.operation()==-9999)
    cout<<"\n\n\t\tDivisor can't be zero.\n\t\tDivision can't be performed.";
   else
    cout<<"\n\n\t\tAnswer = "<<ob1.operation();
   cout<<"\n\n\n\t\tWant to continue (y/n) : ";
   cin>>choice;
  }while(choice=='y'||choice=='Y');
 getch();
}
void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
						const btCollisionObjectWrapper* body0Wrap,
					   	const btCollisionObjectWrapper * body1Wrap,
					  	const btGImpactShapeInterface * shape0,
					  	const btGImpactShapeInterface * shape1)
{

	if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
	{
		const btGImpactMeshShape * meshshape0 = static_cast<const btGImpactMeshShape *>(shape0);
		m_part0 = meshshape0->getMeshPartCount();

		while(m_part0--)
		{
			gimpact_vs_gimpact(body0Wrap, body1Wrap, meshshape0->getMeshPart(m_part0), shape1);
		}

		return;
	}

	if(shape1->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
	{
		const btGImpactMeshShape * meshshape1 = static_cast<const btGImpactMeshShape *>(shape1);
		m_part1 = meshshape1->getMeshPartCount();

		while(m_part1--)
		{

			gimpact_vs_gimpact(body0Wrap, body1Wrap, shape0, meshshape1->getMeshPart(m_part1));

		}

		return;
	}


	btTransform orgtrans0 = body0Wrap->getWorldTransform();
	btTransform orgtrans1 = body1Wrap->getWorldTransform();

	btPairSet pairset;

	gimpact_vs_gimpact_find_pairs(orgtrans0, orgtrans1, shape0, shape1, pairset);

	if(pairset.size()== 0) return;

	if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
		shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART)
	{
		const btGImpactMeshShapePart * shapepart0 = static_cast<const btGImpactMeshShapePart * >(shape0);
		const btGImpactMeshShapePart * shapepart1 = static_cast<const btGImpactMeshShapePart * >(shape1);
		//specialized function
		#ifdef BULLET_TRIANGLE_COLLISION
		collide_gjk_triangles(body0Wrap, body1Wrap, shapepart0, shapepart1, &pairset[0].m_index1, pairset.size());
		#else
		collide_sat_triangles(body0Wrap, body1Wrap, shapepart0, shapepart1, &pairset[0].m_index1, pairset.size());
		#endif

		return;
	}

	//general function

	shape0->lockChildShapes();
	shape1->lockChildShapes();

	GIM_ShapeRetriever retriever0(shape0);
	GIM_ShapeRetriever retriever1(shape1);

	bool child_has_transform0 = shape0->childrenHasTransform();
	bool child_has_transform1 = shape1->childrenHasTransform();

	int i = pairset.size();
	while(i--)
	{
		GIM_PAIR * pair = &pairset[i];
		m_triface0 = pair->m_index1;
		m_triface1 = pair->m_index2;
		const btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0);
		const btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1);

		btTransform tr0 = body0Wrap->getWorldTransform();
		btTransform tr1 = body1Wrap->getWorldTransform();

		if(child_has_transform0)
		{
			tr0 = orgtrans0*shape0->getChildTransform(m_triface0);
		}

		if(child_has_transform1)
		{
			tr1 = orgtrans1*shape1->getChildTransform(m_triface1);
		}

		btCollisionObjectWrapper ob0(body0Wrap, colshape0, body0Wrap->getCollisionObject(), tr0, m_part0, m_triface0);
		btCollisionObjectWrapper ob1(body1Wrap, colshape1, body1Wrap->getCollisionObject(), tr1, m_part1, m_triface1);

		//collide two convex shapes
		convex_vs_convex_collision(&ob0, &ob1, colshape0, colshape1);
	}

	shape0->unlockChildShapes();
	shape1->unlockChildShapes();
}
void	SpuGatheringCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo, btDispatcher* dispatcher) 
{

	if (dispatchInfo.m_enableSPU)
	{
		m_maxNumOutstandingTasks = m_threadInterface->getNumTasks();

		{
			BT_PROFILE("processAllOverlappingPairs");

			if (!m_spuCollisionTaskProcess)
				m_spuCollisionTaskProcess = new SpuCollisionTaskProcess(m_threadInterface,m_maxNumOutstandingTasks);
		
			m_spuCollisionTaskProcess->setNumTasks(m_maxNumOutstandingTasks);
	//		printf("m_maxNumOutstandingTasks =%d\n",m_maxNumOutstandingTasks);

			m_spuCollisionTaskProcess->initialize2(dispatchInfo.m_useEpa);
			
		
			///modified version of btCollisionDispatcher::dispatchAllCollisionPairs:
			{
				btSpuCollisionPairCallback	collisionCallback(dispatchInfo,this);

				pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
			}
		}

		//send one big batch
		int numTotalPairs = pairCache->getNumOverlappingPairs();
		if (numTotalPairs)
		{
			btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr();
			int i;
			{
				int pairRange =	SPU_BATCHSIZE_BROADPHASE_PAIRS;
				if (numTotalPairs < (m_spuCollisionTaskProcess->getNumTasks()*SPU_BATCHSIZE_BROADPHASE_PAIRS))
				{
					pairRange = (numTotalPairs/m_spuCollisionTaskProcess->getNumTasks())+1;
				}
	
				BT_PROFILE("addWorkToTask");
				for (i=0;i<numTotalPairs;)
				{
					//Performance Hint: tweak this number during benchmarking
					
					int endIndex = (i+pairRange) < numTotalPairs ? i+pairRange : numTotalPairs;
					m_spuCollisionTaskProcess->addWorkToTask(pairPtr,i,endIndex);
					i = endIndex;
				}
			}
			{
				BT_PROFILE("PPU fallback");
				//handle PPU fallback pairs
				for (i=0;i<numTotalPairs;i++)
				{
					btBroadphasePair& collisionPair = pairPtr[i];
					if (collisionPair.m_internalTmpValue == 3)
					{
						if (collisionPair.m_algorithm)
						{
							btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
							btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
	
							if (dispatcher->needsCollision(colObj0,colObj1))
							{
							//discrete collision detection query
								btCollisionObjectWrapper ob0(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform());
								btCollisionObjectWrapper ob1(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform());

								btManifoldResult contactPointResult(&ob0,&ob1);
								
								if (dispatchInfo.m_dispatchFunc == 		btDispatcherInfo::DISPATCH_DISCRETE)
								{
									
									collisionPair.m_algorithm->processCollision(&ob0,&ob1,dispatchInfo,&contactPointResult);
								} else
								{
									//continuous collision detection query, time of impact (toi)
									btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
									if (dispatchInfo.m_timeOfImpact > toi)
										dispatchInfo.m_timeOfImpact = toi;
	
								}
							}
						}
					}
				}
			}
		}
		{
			BT_PROFILE("flush2");
			//make sure all SPU work is done
			m_spuCollisionTaskProcess->flush2();
		}

	} else
	{
		///PPU fallback
		///!Need to make sure to clear all 'algorithms' when switching between SPU and PPU
		btCollisionDispatcher::dispatchAllCollisionPairs(pairCache,dispatchInfo,dispatcher);
	}
}
	virtual bool	processOverlap(btBroadphasePair& collisionPair)
	{


		//PPU version
		//(*m_dispatcher->getNearCallback())(collisionPair,*m_dispatcher,m_dispatchInfo);

		//only support discrete collision detection for now, we could fallback on PPU/unoptimized version for TOI/CCD
		btAssert(m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE);

		//by default, Bullet will use this near callback
		{
			///userInfo is used to determine if the SPU has to handle this case or not (skip PPU tasks)
			if (!collisionPair.m_internalTmpValue)
			{
				collisionPair.m_internalTmpValue = 1;
			}
			if (!collisionPair.m_algorithm)
			{
				btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
				btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;

				btCollisionAlgorithmConstructionInfo ci;
				ci.m_dispatcher1 = m_dispatcher;
				ci.m_manifold = 0;

				if (m_dispatcher->needsCollision(colObj0,colObj1))
				{
					int	proxyType0 = colObj0->getCollisionShape()->getShapeType();
					int	proxyType1 = colObj1->getCollisionShape()->getShapeType();
					bool supportsSpuDispatch = m_dispatcher->supportsDispatchPairOnSpu(proxyType0,proxyType1) 
						&& ((colObj0->getCollisionFlags() & btCollisionObject::CF_DISABLE_SPU_COLLISION_PROCESSING) == 0)
						&& ((colObj1->getCollisionFlags() & btCollisionObject::CF_DISABLE_SPU_COLLISION_PROCESSING) == 0);

					if (proxyType0 == COMPOUND_SHAPE_PROXYTYPE)
					{
						btCompoundShape* compound = (btCompoundShape*)colObj0->getCollisionShape();
						if (compound->getNumChildShapes()>MAX_SPU_COMPOUND_SUBSHAPES)
						{
							//printf("PPU fallback, compound->getNumChildShapes(%d)>%d\n",compound->getNumChildShapes(),MAX_SPU_COMPOUND_SUBSHAPES);
							supportsSpuDispatch = false;
						}
					}

					if (proxyType1 == COMPOUND_SHAPE_PROXYTYPE)
					{
						btCompoundShape* compound = (btCompoundShape*)colObj1->getCollisionShape();
						if (compound->getNumChildShapes()>MAX_SPU_COMPOUND_SUBSHAPES)
						{
							//printf("PPU fallback, compound->getNumChildShapes(%d)>%d\n",compound->getNumChildShapes(),MAX_SPU_COMPOUND_SUBSHAPES);
							supportsSpuDispatch = false;
						}
					}

					if (supportsSpuDispatch)
					{

						int so = sizeof(SpuContactManifoldCollisionAlgorithm);
#ifdef ALLOCATE_SEPARATELY
						void* mem = btAlignedAlloc(so,16);//m_dispatcher->allocateCollisionAlgorithm(so);
#else
						void* mem = m_dispatcher->allocateCollisionAlgorithm(so);
#endif
						collisionPair.m_algorithm = new(mem) SpuContactManifoldCollisionAlgorithm(ci,colObj0,colObj1);
						collisionPair.m_internalTmpValue =  2;
					} else
					{
						btCollisionObjectWrapper ob0(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform());
						btCollisionObjectWrapper ob1(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform());

						collisionPair.m_algorithm = m_dispatcher->findAlgorithm(&ob0,&ob1);
						collisionPair.m_internalTmpValue = 3;
					}
				} 
			}
		}
		return false;
	}
Esempio n. 14
0
//------------------------------------------------------------------------------
int main( int argc, char * argv[] )
{
    base::auxi::Timer total, detailed;
    
    //--------------------------------------------------------------------------
    // User input
    if ( argc != 5 ) {
        std::cout << "Usage:  " << argv[0]
                  << " file.smf radius E1 E2 \n\n";
        return -1;
    }

    // input mesh file
    const std::string smfFile  = boost::lexical_cast<std::string>( argv[1] );
    const std::string baseName = base::io::baseName( smfFile, ".smf" );

    // problem parameter
    const double radius = boost::lexical_cast<double>( argv[2] );
    const double E1     = boost::lexical_cast<double>( argv[3] );
    const double E2     = boost::lexical_cast<double>( argv[4] );

    const double penaltyFactor = 20.0;

    // material stuff
    const double nu = 0.3;
    const double lambda1 = mat::Lame::lambda( E1, nu );
    const double lambda2 = mat::Lame::lambda( E2, nu );
    const double mu1     = mat::Lame::mu( E1, nu );
    const double mu2     = mat::Lame::mu( E2, nu );

    //--------------------------------------------------------------------------
    const unsigned    geomDeg   = 1;
    const unsigned    dim       = SPACEDIM;
    const base::Shape shape     = base::SimplexShape<dim>::value;
    const bool        isSigned  = true;
    
    const unsigned fieldDeg = 1;
    const unsigned doFSize  = dim;

    // use Nitsche
    const bool useNitscheTerms = true;

    //--------------------------------------------------------------------------
    // Domain mesh
    typedef base::Unstructured<shape,geomDeg> Mesh;

    Mesh mesh;
    {
        std::ifstream smf( smfFile.c_str() );
        base::io::smf::readMesh( smf, mesh );
    }

    //--------------------------------------------------------------------------
    // Compute the level set data
    typedef base::cut::LevelSet<dim> LevelSet;
    std::vector<LevelSet> levelSet;
    base::cut::AnalyticSurface<dim>::Type as =
        boost::bind( &interface<dim>, _1, radius, _2 );
    base::cut::analyticLevelSet( mesh, as, isSigned, levelSet );


    //--------------------------------------------------------------------------
    // FE
    typedef base::fe::Basis<shape,fieldDeg>         FEBasis;
    typedef base::cut::ScaledField<FEBasis,doFSize> Field;
    Field fieldIn, fieldOut;

    base::dof::generate<FEBasis>( mesh, fieldIn  );
    base::dof::generate<FEBasis>( mesh, fieldOut );
    

    //--------------------------------------------------------------------------
    // Cut
    typedef base::cut::Cell<shape> Cell;
    std::vector<Cell> cells;
    base::cut::generateCutCells( mesh, levelSet, cells );

    //--------------------------------------------------------------------------
    //  surface meshes
    typedef base::cut::SurfaceMeshBinder<Mesh>::SurfaceMesh SurfaceMesh;
    SurfaceMesh boundaryMesh, interfaceMesh;

    // from boundary
    {
        // identify list of element boundary faces
        base::mesh::MeshBoundary meshBoundary;
        meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

        // generate a mesh from that list (with a filter)
        base::mesh::generateBoundaryMesh( meshBoundary.begin(),
                                          meshBoundary.end(),
                                          mesh, boundaryMesh,
                                          boost::bind( &dirichletBoundary<dim>, _1 ) );
    }

    // from interface
    base::cut::generateSurfaceMesh<Mesh,Cell>( mesh, cells, interfaceMesh );

    //--------------------------------------------------------------------------
    // Quadratures
    const unsigned kernelDegEstimate = 5;
    // for domain
    typedef base::cut::Quadrature<kernelDegEstimate,shape> CutQuadrature;
    CutQuadrature cutQuadratureIn(  cells, true  );
    CutQuadrature cutQuadratureOut( cells, false );
    // for surface
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;

    //--------------------------------------------------------------------------
    // Bind fields

    // for domain fields
    typedef base::asmb::FieldBinder<Mesh,Field,Field> FieldBinder;
    typedef FieldBinder::TupleBinder<1,1>::Type FTB1;
    typedef FieldBinder::TupleBinder<2,2>::Type FTB2;
    FieldBinder fieldBinder(  mesh, fieldIn, fieldOut );

    // for surface fields
    typedef base::asmb::SurfaceFieldBinder<SurfaceMesh,Field,Field> SurfaceFieldBinder;
    typedef SurfaceFieldBinder::TupleBinder<1,1>::Type STB11;
    typedef SurfaceFieldBinder::TupleBinder<2,2>::Type STB22;
    typedef SurfaceFieldBinder::TupleBinder<1,2>::Type STB12;
    typedef SurfaceFieldBinder::TupleBinder<2,1>::Type STB21;
    SurfaceFieldBinder   boundaryFieldBinder(  boundaryMesh, fieldIn, fieldOut );
    SurfaceFieldBinder interfaceFieldBinder(  interfaceMesh, fieldIn, fieldOut );

    // compute supports, scale basis
    const std::size_t numDoFs = std::distance( fieldIn.doFsBegin(), fieldIn.doFsEnd() );
    std::vector<double> supportsIn, supportsOut;
    supportsIn.resize(  numDoFs );
    supportsOut.resize( numDoFs );
    
    base::cut::supportComputation( mesh, fieldIn,  cutQuadratureIn,  supportsIn );
    base::cut::supportComputation( mesh, fieldOut, cutQuadratureOut, supportsOut );

    fieldIn.scaleAndTagBasis(  supportsIn,  1.e-10 );
    fieldOut.scaleAndTagBasis( supportsOut, 1.e-10 );
    //fieldIn.tagBasis( supportsIn, 1.e-10 );
    //fieldOut.tagBasis( supportsOut, 1.e-10 );
    
    // number DoFs, create solver
    const std::size_t activeDoFsIn = 
        base::dof::numberDoFsConsecutively( fieldIn.doFsBegin(), fieldIn.doFsEnd() );
    const std::size_t activeDoFsOut = 
        base::dof::numberDoFsConsecutively( fieldOut.doFsBegin(),
                                            fieldOut.doFsEnd(), activeDoFsIn );

    typedef base::solver::Eigen3 Solver;
    Solver solver( activeDoFsIn + activeDoFsOut );

    message( "Preprocessing time = " + detailed.print() );
    detailed.reset();
    

    //--------------------------------------------------------------------------
    // Stiffness matrix
    typedef mat::hypel::StVenant Material;
    Material material1( lambda1, mu1 );
    Material material2( lambda2, mu2 );

    // matrix kernel
    typedef solid::HyperElastic<Material,FTB1::Tuple> HyperElastic1;
    HyperElastic1 hyperElastic1( material1 );
    typedef solid::HyperElastic<Material,FTB2::Tuple> HyperElastic2;
    HyperElastic2 hyperElastic2( material2 );

    message( "Stiffness" );
    base::asmb::stiffnessMatrixComputation<FTB1>( cutQuadratureIn, solver,
                                                  fieldBinder, hyperElastic1 );
    base::asmb::stiffnessMatrixComputation<FTB2>( cutQuadratureOut, solver,
                                                  fieldBinder, hyperElastic2 );

    // boundary conditions
#if 1
    {
        message("Boundary Penalty");
        base::nitsche::OuterBoundary ob1( E1);
        base::nitsche::OuterBoundary ob2( E2);
        
        base::nitsche::penaltyLHS<STB11>( surfaceQuadrature, solver,
                                          boundaryFieldBinder, ob1, penaltyFactor );
        base::nitsche::penaltyLHS<STB22>( surfaceQuadrature, solver,
                                          boundaryFieldBinder, ob2, penaltyFactor );
        base::nitsche::penaltyRHS<STB11>( surfaceQuadrature, solver, boundaryFieldBinder, 
                                          boost::bind( &dirichlet<dim>, _1), ob1,
                                          penaltyFactor );
        base::nitsche::penaltyRHS<STB22>( surfaceQuadrature, solver, boundaryFieldBinder,
                                          boost::bind( &dirichlet<dim>, _1), ob2,
                                          penaltyFactor );

        if ( useNitscheTerms ) {
        
            message("Boundary Nitsche");
            base::nitsche::energyLHS<STB11>( hyperElastic1, surfaceQuadrature, solver,
                                             boundaryFieldBinder, ob1 );
            base::nitsche::energyLHS<STB22>( hyperElastic2, surfaceQuadrature, solver,
                                             boundaryFieldBinder, ob2 );

            base::nitsche::energyRHS<STB11>( hyperElastic1, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1), ob1 );
            base::nitsche::energyRHS<STB22>( hyperElastic2, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1), ob2 );
        }
        
    }

    // interface conditions
    {
        message("Interface Penalty");
        base::nitsche::ImmersedInterface<Cell> ip(  E1,  E2, cells );

        base::nitsche::penaltyLHS<STB11>( surfaceQuadrature, solver,
                                          interfaceFieldBinder, ip, penaltyFactor );
        base::nitsche::penaltyLHS<STB22>( surfaceQuadrature, solver,
                                          interfaceFieldBinder, ip, penaltyFactor );
        
        base::nitsche::penaltyLHS<STB12>( surfaceQuadrature, solver, interfaceFieldBinder,
                                          ip, -penaltyFactor );
        base::nitsche::penaltyLHS<STB21>( surfaceQuadrature, solver, interfaceFieldBinder,
                                          ip, -penaltyFactor );

        if ( useNitscheTerms ) {
            message("Interface Nitsche");
            
            base::nitsche::energyLHS<STB11>(
                hyperElastic1, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, true, true  ); //  kappa1
        
            base::nitsche::energyLHS<STB21>(
                hyperElastic1, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, true, false ); //  -kappa1
            
            base::nitsche::energyLHS<STB12>(
                hyperElastic2, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, false, true );  //  kappa2
        
            base::nitsche::energyLHS<STB22>(
                hyperElastic2, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, false, false ); // -kappa2
            
        }
    }
#endif
    
    //--------------------------------------------------------------------------
    // Solve and distribute
    solver.finishAssembly();

    message( "Assembly time = " + detailed.print() );
    detailed.reset();

#ifdef VERBOSE
    {
        solver.systemInfo( std::cout );

        std::ofstream mat( "matrix" );
        solver.debugLHS( mat );

        std::ofstream vec( "vector" );
        solver.debugRHS( vec );
    }
#endif

    
#if 1 // decide to solve and post-process

    
    //solver.choleskySolve();
    const unsigned numCGIter = solver.cgSolve();

    //message( "Solve time = " + detailed.print() );
    const double solveTime = detailed.seconds(); 
    detailed.reset();

    base::dof::setDoFsFromSolver( solver, fieldIn  );
    base::dof::setDoFsFromSolver( solver, fieldOut );


    //--------------------------------------------------------------------------
    // Extract distances, closestPoints and location flags from level set data
    {
    }
    
    //--------------------------------------------------------------------------
    {
        const std::string vtkFile = baseName + ".vtk";
        std::ofstream vtk( vtkFile.c_str() );
        base::io::vtk::LegacyWriter vtkWriter( vtk );

        vtkWriter.writeUnstructuredGrid( mesh );
        {
            std::vector<double> distances;
            std::transform( levelSet.begin(), levelSet.end(),
                            std::back_inserter( distances ),
                            boost::bind( &LevelSet::getSignedDistance, _1 ) );
            vtkWriter.writePointData( distances.begin(), distances.end(), "distances" );
        }
        
        {
            std::vector<bool>   location;
            std::transform( levelSet.begin(), levelSet.end(),
                            std::back_inserter( location ),
                            boost::bind( &LevelSet::isInterior, _1 ) );
            vtkWriter.writePointData( location.begin(), location.end(), "location" );
        }

        vtkWriter.writePointData( supportsIn.begin(),  supportsIn.end(),  "suppIn" );
        vtkWriter.writePointData( supportsOut.begin(), supportsOut.end(), "suppOut" );

        base::io::vtk::writePointData( vtkWriter, mesh, fieldIn,  "fieldIn"  );
        base::io::vtk::writePointData( vtkWriter, mesh, fieldOut, "fieldOut" );
        
        vtk.close();
    }

#ifdef VERBOSE   // decide error verbosity
    
    // integrate
    double volumeIn = 0.;
    base::asmb::simplyIntegrate<FTB1>( cutQuadratureIn, volumeIn, fieldBinder,
                                       base::kernel::Measure<FTB1::Tuple>() );


    double volumeOut = 0.;
    base::asmb::simplyIntegrate<FTB2>( cutQuadratureOut, volumeOut, fieldBinder,
                                      base::kernel::Measure<FTB2::Tuple>() );
    
    std::cout << "Volume of mesh: " << volumeIn << " + " << volumeOut
              << " = " << volumeIn + volumeOut
              << '\n';

    

#else
    // for convergence analysis
    std::cout << solveTime << "  " << numCGIter << "\n";
#endif


#endif // decide to solve and write

    message( "Post-process time = " + detailed.print() );
    message( "---------------------------------------" );
    
    message( "Total time = " + total.print() );
    
    return 0;
}
void prog2()
{
    date ob1(12, 4, 2011), ob2("10/22/2001");
    ob1.show_date();
    ob2.show_date();
}