Exemple #1
0
static int gMousePick()
{
	int index = -1;
	float minDist = DINGUS_BIG_FLOAT;

	// go through all meshes
	int i;
	int n = gEntities.size();
	for( i = 0; i < n; ++i ) {
		const SVector3& p = gEntities[i]->mWorldMat.getOrigin();
		const CAABox& aabb = gEntities[i]->getAABB();
		float radius = SVector3(aabb.getMax() - aabb.getMin()).length() * 0.4f;

		if( gMouseRay.project( p ) < 0.0f )
			continue;
		if( gMouseRay.distance( p ) > radius )
			continue;
		float dist2 = SVector3(p-gMouseRay.pos).lengthSq();
		if( dist2 < minDist ) {
			index = i;
			minDist = dist2;
		}
	}
	return index;
}
Exemple #2
0
// returns the cross field as a pair of othogonal vectors (NOT in parametric coordinates, but real 3D coordinates)
Pair<SVector3, SVector3> frameFieldBackgroundMesh2D::compute_crossfield_directions(double u, double v,
        double angle_current)
{
    // get the unit normal at that point
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return Pair<SVector3,SVector3>(SVector3(), SVector3());
    }

    Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v));
    SVector3 s1 = der.first();
    SVector3 s2 = der.second();
    SVector3 n = crossprod(s1,s2);
    n.normalize();

    SVector3 basis_u = s1;
    basis_u.normalize();
    SVector3 basis_v = crossprod(n,basis_u);

    // normalize vector t1 that is tangent to gf at uv
    SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ;
    t1.normalize();

    // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame
    SVector3 t2 = crossprod(n,t1);
    t2.normalize();

    return Pair<SVector3,SVector3>(SVector3(t1[0],t1[1],t1[2]),
                                   SVector3(t2[0],t2[1],t2[2]));
}
Exemple #3
0
Metric Filler::get_metric(double x,double y,double z,GEntity* ge){
  Metric m;
  SMetric3 temp;
  SVector3 v1,v2,v3;
  Field* field;
  FieldManager* manager;
	
  v1 = SVector3(1.0,0.0,0.0);
  v2 = SVector3(0.0,1.0,0.0);
  v3 = SVector3(0.0,0.0,1.0);
	
  manager = ge->model()->getFields();
  if(manager->getBackgroundField()>0){
    field = manager->get(manager->getBackgroundField());
    if(field){
      (*field)(x,y,z,temp,ge);
    }
  }
	
  m.set_m11(v1.x());
  m.set_m21(v1.y());
  m.set_m31(v1.z());
	
  m.set_m12(v2.x());
  m.set_m22(v2.y());
  m.set_m32(v2.z());
	
  m.set_m13(v3.x());
  m.set_m23(v3.y());
  m.set_m33(v3.z());
	
  return m;
}
SOrientedBoundingBox::SOrientedBoundingBox()
{
  center = SVector3();
  size = SVector3();
  axisX = SVector3();
  axisY = SVector3();
  axisZ = SVector3();
  fillp();
}
Exemple #5
0
Player::Player(SVector3* pos, SVector3* vel, CMesh* mod, float size) : GameObject(pos, vel, mod) {
	 
  health = 100;
  cooldown = 0;
  firing = false;
  this->size = size;

  Translation.X = pos->X;
  Translation.Y = pos->Y;
  Translation.Z = pos->Z;

  Scale.X = 1; 
  Scale.Y = 1;
  Scale.Z = 1;

  Rotation.X = 90;
  Rotation.Y = 0;
  Rotation.Z = 0;

  // First create a shader loader and check if our hardware supports shaders
	CShaderLoader ShaderLoader;
	if (! ShaderLoader.isValid())
	{
		std::cerr << "Shaders are not supported by your graphics hardware, or the shader loader was otherwise unable to load." << std::endl;
		waitForUser3();
	}

	// Now attempt to load the shaders
	shade = ShaderLoader.loadShader("Shaders/GameVert2.glsl", "Shaders/Lab3_frag.glsl");
	if (! shade)
	{
		std::cerr << "Unable to open or compile necessary shader." << std::endl;
		waitForUser3();
	}
	shade->loadAttribute("aPosition");
	shade->loadAttribute("aColor");
  shade->loadAttribute("aNormal");
	
	// Attempt to load mesh
   mod = CMeshLoader::loadASCIIMesh("Models/spaceship.obj");
	//mod = CMeshLoader::loadASCIIMesh("Models/cessna_color500.m");
	if (! mod)
	{
		std::cerr << "Unable to load necessary mesh." << std::endl;
		waitForUser3();
	}
	// Make out mesh fit within camera view
	mod->resizeMesh(SVector3(1));
	// And center it at the origin
	mod->centerMeshByExtents(SVector3(0));

	// Now load our mesh into a VBO, retrieving the number of triangles and the handles to each VBO
	CMeshLoader::createVertexBufferObject(* mod, TriangleCount, 
		PositionBufferHandle, ColorBufferHandle, NormalBufferHandle);
}
Exemple #6
0
SVector3 gmshFace::normal(const SPoint2 &param) const
{
  if(s->Typ != MSH_SURF_PLAN){
    Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1);
    Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2);
    Vertex n = vu % vv;
    n.norme();
    return SVector3(n.Pos.X, n.Pos.Y, n.Pos.Z);
  }
  else{
    // We cannot use InterpolateSurface() for plane surfaces since it
    // relies on the mean plane, which does not respect the
    // orientation

    // FIXME: move this test at the end of the MeanPlane computation
    // routine--and store the correct normal, damn it!

    double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c};
    norme(n);
    GPoint pt = point(param.x(), param.y());
    double v[3] = {pt.x(), pt.y(), pt.z()};
    int NP = 10, tries = 0;
    while(1){
      tries++;
      double angle = 0.;
      for(int i = 0; i < List_Nbr(s->Generatrices); i++) {
        Curve *c;
        List_Read(s->Generatrices, i, &c);
        int N = (c->Typ == MSH_SEGM_LINE) ? 1 : NP;
        for(int j = 0; j < N; j++) {
          double u1 = (double)j / (double)N;
          double u2 = (double)(j + 1) / (double)N;
          Vertex p1 = InterpolateCurve(c, u1, 0);
          Vertex p2 = InterpolateCurve(c, u2, 0);
          double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z};
          double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z};
          angle += angle_plan(v, v1, v2, n);
        }
      }
      if(fabs(angle) < 0.5){ // we're outside
        NP *= 2;
        Msg::Debug("Could not compute normal of surface %d - retrying with %d points",
                   tag(), NP);
        if(tries > 10){
          Msg::Warning("Could not orient normal of surface %d", tag());
          return SVector3(n[0], n[1], n[2]);
        }
      }
      else if(angle > 0)
        return SVector3(n[0], n[1], n[2]);
      else
        return SVector3(-n[0], -n[1], -n[2]);
    }
  }
}
bool CMeshLoader::loadVertexBufferObjectFromMesh(std::string const & fileName, int & TriangleCount, GLuint & PositionBufferHandle, GLuint & ColorBufferHandle, GLuint & NormalBufferHandle)
{
	CMesh * Mesh = loadASCIIMesh(fileName);
	if (! Mesh)
		return false;
   
	Mesh->resizeMesh(SVector3(1));
	Mesh->centerMeshByExtents(SVector3(0));
   Mesh->computeNormals();
   
	createVertexBufferObject(* Mesh, TriangleCount, PositionBufferHandle, ColorBufferHandle, NormalBufferHandle);
	
	return true;
}
Exemple #8
0
Pair<SVector3, SVector3> gmshFace::firstDer(const SPoint2 &param) const
{
  if(s->Typ == MSH_SURF_PLAN && !s->geometry){
    double x, y, z, VX[3], VY[3];
    getMeanPlaneData(VX, VY, x, y, z);
    return Pair<SVector3, SVector3>(SVector3(VX[0], VX[1], VX[2]),
                                    SVector3(VY[0], VY[1], VY[2]));
  }
  else{
    Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1);
    Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2);
    return Pair<SVector3, SVector3>(SVector3(vu.Pos.X, vu.Pos.Y, vu.Pos.Z),
                                    SVector3(vv.Pos.X, vv.Pos.Y, vv.Pos.Z));
  }
}
void CWall3D::fracturePiecesInYRange( float t, float y1, float y2, TIntVector& pcs )
{
	if( !mPiecesInited )
		initPieces();

	// fetch the pieces
	pcs.resize( 0 );

	// TODO: optimize, right now linear search!
	float pieceRestoreTime = t + 1.0e6f;

	int n = mWall2D.getPieceCount();
	for( int i = 0; i < n; ++i ) {
		const CWallPiece2D& p = mWall2D.getPiece( i );
		SVector2 c = p.getAABB().getCenter();
		float y = c.y;
		if( mMatrix.getAxisY().y < 0.5f ) {
			SVector3 wc;
			D3DXVec3TransformCoord( &wc, &SVector3(c.x,c.y,0), &mMatrix );
			y = wc.y;
		}
		if( y >= y1 && y <= y2 ) {
			mPieceRestoreTimes[i] = pieceRestoreTime;
			if( mFracturedPieces[i] )
				continue;
			pcs.push_back( i );
			fractureOutPiece( i );
		}
	}
}
Exemple #10
0
SVector3 MFace::normal() const
{
  double n[3];
  normal3points(_v[0]->x(), _v[0]->y(), _v[0]->z(),
                _v[1]->x(), _v[1]->y(), _v[1]->z(),
                _v[2]->x(), _v[2]->y(), _v[2]->z(), n);
  return SVector3(n[0], n[1], n[2]);
}
Exemple #11
0
SVector3 OCCEdge::firstDer(double par) const
{
  BRepAdaptor_Curve brepc(c);
  BRepLProp_CLProps prop(brepc, 1, 1e-5);
  prop.SetParameter(par);
  gp_Vec d1 = prop.D1();
  return SVector3(d1.X(), d1.Y(), d1.Z());
}
Exemple #12
0
SVector3 GEdgeCompound::firstDer(double par) const
{
  double tLoc;
  int iEdge;
  if(!getLocalParameter(par, iEdge, tLoc))
    return SVector3();
  return _compound[iEdge]->firstDer(tLoc);
}
Exemple #13
0
int MZoneBoundary<DIM>::exteriorBoundaryVertices
(const int normalSource, ZoneBoVec &zoneBoVec)
{

  if(globalBoVertMap.size() == 0) return 1;

  zoneBoVec.clear();
  zoneBoVec.reserve(3*globalBoVertMap.size()/2);

  BCPatchIndex patch;                   // Provides a BC patch index for each
                                        // entity
  bool warnNormFromElem = true;         // A warning that normals were
                                        // determined from elements.  This
                                        // warning is only give once (after
                                        // which the flag is set to false)

  const typename GlobalBoVertexMap::const_iterator vMapEnd =
    globalBoVertMap.end();
  for(typename GlobalBoVertexMap::const_iterator vMapIt =
        globalBoVertMap.begin(); vMapIt != vMapEnd; ++vMapIt) {
    const int nZone = vMapIt->second.zoneData.size();
    for(int iZone = 0; iZone != nZone; ++iZone) {
      const typename GlobalVertexData<FaceT>::ZoneData &zoneData =
        vMapIt->second.zoneData[iZone]; // Ref. to data stored for this zone

//--Try to find an outwards normal for this vertex

      if(normalSource) {
        updateBoVec<DIM, FaceT>(normalSource, vMapIt->first, zoneData.zoneIndex,
                                zoneData.vertexIndex, vMapIt->second.faces,
                                zoneBoVec, patch, warnNormFromElem);
      }
      else {
        // Keys to 'globalBoVertMap' will not change so const_cast is okay.
        zoneBoVec.push_back(VertexBoundary(zoneData.zoneIndex, 0, SVector3(0.),
                                           const_cast<MVertex*>(vMapIt->first),
                                           zoneData.vertexIndex));
      }
    }
  }

  // If normals were written from the geometry, zoneBoVec currently stores
  // entities in bcPatchIndex.  Update with the actual patch index.  Why? -
  // because two entities may have been merged if the interface between them is
  // continuous.
  if(normalSource == NormalSourceGeometry) {
    patch.generatePatchIndices();
    const int nBoVert = zoneBoVec.size();
    for(int iBoVert = 0; iBoVert != nBoVert; ++iBoVert) {
      zoneBoVec[iBoVert].bcPatchIndex =
        patch.getIndex(zoneBoVec[iBoVert].bcPatchIndex);
    }
  }

  return 0;

}
SMetric3 buildMetricTangentToCurve(SVector3 &t, double l_t, double l_n)
{
  if (l_t == 0.0) return SMetric3(1.e-22);
  SVector3 a;
  if (fabs(t(0)) <= fabs(t(1)) && fabs(t(0)) <= fabs(t(2))){
    a = SVector3(1,0,0);
  }
  else if (fabs(t(1)) <= fabs(t(0)) && fabs(t(1)) <= fabs(t(2))){
    a = SVector3(0,1,0);
  }
  else{
    a = SVector3(0,0,1);
  }
  SVector3 b = crossprod (t,a);
  SVector3 c = crossprod (b,t);
  b.normalize();
  c.normalize();
  t.normalize();
  SMetric3 Metric (1./(l_t*l_t),1./(l_n*l_n),1./(l_n*l_n),t,b,c);
  //  printf("bmttc %g %g %g %g %g\n",l_t,l_n,Metric(0,0),Metric(0,1),Metric(1,1));
  return Metric;
}
void CMinimapRenderer::render()
{
	// early out if no entities to render
	if( mEntities.empty() )
		return;

	// stuff entities into vertex buffer
	int n = mEntities.size();
	const int MAX_ENTITIES = 1000; // cap the max. entities
	if( n > MAX_ENTITIES )
		n = MAX_ENTITIES;
	TVBChunk::TSharedPtr chunk = CDynamicVBManager::getInstance().allocateChunk( n*4, sizeof(TVertex) );
	TVertex* vb = (TVertex*)chunk->getData();
	for( int i = 0; i < n; ++i ) {
		const SEntity& e = mEntities[i];
		vb[0].p = e.pos + SVector3(-e.size,0,-e.size);	vb[0].diffuse = e.color; vb[0].tu = 0; vb[0].tv = 0;
		vb[1].p = e.pos + SVector3( e.size,0,-e.size);	vb[1].diffuse = e.color; vb[1].tu = 1; vb[1].tv = 0;
		vb[2].p = e.pos + SVector3( e.size,0, e.size);	vb[2].diffuse = e.color; vb[2].tu = 1; vb[2].tv = 1;
		vb[3].p = e.pos + SVector3(-e.size,0, e.size);	vb[3].diffuse = e.color; vb[3].tu = 0; vb[3].tv = 1;
		vb += 4;
	}
	chunk->unlock();

	// set onto renderable buffer and attach it
	mRenderable->resetVBs();
	mRenderable->setVertexDecl( mVDecl );
	mRenderable->setIB( *mIB );
	mRenderable->setVB( chunk->getBuffer(), 0 );
	mRenderable->setStride( chunk->getStride(), 0 );

	mRenderable->setBaseVertex( chunk->getOffset() );
	mRenderable->setMinVertex( 0 );
	mRenderable->setNumVertices( chunk->getSize() );
	mRenderable->setStartIndex( 0 );
	mRenderable->setPrimCount( chunk->getSize()/2 );
	mRenderable->setPrimType( D3DPT_TRIANGLELIST );

	G_RENDERCTX->attach( *mRenderable );
}
Exemple #16
0
static void computeGradSFAtNodes (MElement *e, std::vector<std::vector<SVector3> > &gsf)
{
  const nodalBasis &elbasis = *e->getFunctionSpace();
  double s[256][3];
  for (int j=0;j<e->getNumVertices();j++){
    std::vector<SVector3> g(e->getNumVertices());
    double u_mesh = elbasis.points(j,0);
    double v_mesh = elbasis.points(j,1);
    e->getGradShapeFunctions ( u_mesh , v_mesh , 0,  s);
    for (int k=0;k<e->getNumVertices();k++)
      g[k] = SVector3(s[k][0],s[k][1],s[k][2]);
    gsf.push_back(g);
  }
}
void elasticitySolver::addNeumannBC (int dim, int entityId, const std::vector<double> value) {
  if(value.size()!=3) return;
  neumannBC neu;
  neu.g = new groupOfElements (dim, entityId);
  neu._f= new simpleFunction<SVector3>(SVector3(value[0], value[1], value[2]));
  neu._tag=entityId;
  switch (dim) {
    case 0 : neu.onWhat=BoundaryCondition::ON_VERTEX; break;
    case 1 : neu.onWhat=BoundaryCondition::ON_EDGE; break;
    case 2 : neu.onWhat=BoundaryCondition::ON_FACE; break;
    default : return;
  }
  allNeumann.push_back(neu);
}
Exemple #18
0
void Filler::create_spawns(GEntity* ge,MElementOctree* octree,Node* node,std::vector<Node*>& spawns){
  double x,y,z;
  double x1,y1,z1;
  double x2,y2,z2;
  double x3,y3,z3;
  double x4,y4,z4;
  double x5,y5,z5;
  double x6,y6,z6;
  double h;
  double h1,h2,h3,h4,h5,h6;
  Metric m;
  SPoint3 point;

  point = node->get_point();
  x = point.x();
  y = point.y();
  z = point.z();
  h = node->get_size();
  m = node->get_metric();

  h1 = improvement(ge,octree,point,h,SVector3(m.get_m11(),m.get_m21(),m.get_m31()));
  x1 = x + h1*m.get_m11();
  y1 = y + h1*m.get_m21();
  z1 = z + h1*m.get_m31();

  h2 = improvement(ge,octree,point,h,SVector3(-m.get_m11(),-m.get_m21(),-m.get_m31()));
  x2 = x - h2*m.get_m11();
  y2 = y - h2*m.get_m21();
  z2 = z - h2*m.get_m31();

  h3 = improvement(ge,octree,point,h,SVector3(m.get_m12(),m.get_m22(),m.get_m32()));
  x3 = x + h3*m.get_m12();
  y3 = y + h3*m.get_m22();
  z3 = z + h3*m.get_m32();

  h4 = improvement(ge,octree,point,h,SVector3(-m.get_m12(),-m.get_m22(),-m.get_m32()));
  x4 = x - h4*m.get_m12();
  y4 = y - h4*m.get_m22();
  z4 = z - h4*m.get_m32();

  h5 = improvement(ge,octree,point,h,SVector3(m.get_m13(),m.get_m23(),m.get_m33()));
  x5 = x + h5*m.get_m13();
  y5 = y + h5*m.get_m23();
  z5 = z + h5*m.get_m33();

  h6 = improvement(ge,octree,point,h,SVector3(-m.get_m13(),-m.get_m23(),-m.get_m33()));
  x6 = x - h6*m.get_m13();
  y6 = y - h6*m.get_m23();
  z6 = z - h6*m.get_m33();

  *spawns[0] = Node(SPoint3(x1,y1,z1));
  *spawns[1] = Node(SPoint3(x2,y2,z2));
  *spawns[2] = Node(SPoint3(x3,y3,z3));
  *spawns[3] = Node(SPoint3(x4,y4,z4));
  *spawns[4] = Node(SPoint3(x5,y5,z5));
  *spawns[5] = Node(SPoint3(x6,y6,z6));
}
SOrientedBoundingBox::SOrientedBoundingBox(SVector3 &center_, double sizeX,
                                           double sizeY, double sizeZ,
                                           const SVector3 &axisX_,
                                           const SVector3 &axisY_,
                                           const SVector3 &axisZ_)
{
  center = center_;
  size = SVector3(sizeX, sizeY, sizeZ);
  axisX = axisX_;
  axisX.normalize();
  axisY = axisY_;
  axisY.normalize();
  axisZ = axisZ_;
  axisZ.normalize();
  fillp();
}
Exemple #20
0
int edge_normal
(const MVertex *const vertex, const int zoneIndex, const GEdge *const gEdge,
 const CCon::FaceVector<MZoneBoundary<2>::GlobalVertexData<MEdge>::FaceDataB>
 &faces, SVector3 &boNormal, const int onlyFace = -1)
{

  double par=0.0;
  // Note: const_cast used to match MVertex.cpp interface
  if(!reparamMeshVertexOnEdge(const_cast<MVertex*>(vertex), gEdge, par)) return 1;

  const SVector3 tangent(gEdge->firstDer(par));
                                        // Tangent to the boundary face
  SPoint3 interior(0., 0., 0.);         // An interior point
  SVector3 meshPlaneNormal(0.);         // This normal is perpendicular to the
                                        // plane of the mesh

  // The interior point and mesh plane normal are computed from all elements in
  // the zone.
  int cFace = 0;
  int iFace = 0;
  int nFace = faces.size();
  if ( onlyFace >= 0 ) {
    iFace = onlyFace;
    nFace = onlyFace + 1;
  }
  for(; iFace != nFace; ++iFace) {
    if(faces[iFace].zoneIndex == zoneIndex) {
      ++cFace;
      interior += faces[iFace].parentElement->barycenter();
      // Make sure all the planes go in the same direction
      //**Required?
      SVector3 mpnt = faces[iFace].parentElement->getFace(0).normal();
      if(dot(mpnt, meshPlaneNormal) < 0.) mpnt.negate();
      meshPlaneNormal += mpnt;
    }
  }
  interior /= cFace;
  // Normal to the boundary edge (but unknown direction)
  boNormal = crossprod(tangent, meshPlaneNormal);
  boNormal.normalize();
  // Direction vector from vertex to interior (inwards).  The normal should
  // point in the same direction.
  if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.)
    boNormal.negate();
  return 0;

}
CMesh * const CMeshLoader::loadASCIIMesh(std::string const & fileName)
{
	std::ifstream File;
	File.open(fileName.c_str());
   
	if (! File.is_open())
	{
		std::cerr << "Unable to open mesh file: " << fileName << std::endl;
		return 0;
	}
   
	CMesh * Mesh = new CMesh();
   
	while (File)
	{
		std::string ReadString;
		std::getline(File, ReadString);
      
		std::stringstream Stream(ReadString);
      
		std::string Label;
		Stream >> Label;
      
		if (Label.find("#") != std::string::npos)
		{
			// Comment, skip
			continue;
		}
      
		if ("Vertex" == Label)
		{
			int Index;
			Stream >> Index; // We don't care, throw it away
         
			SVector3 Position;
			Stream >> Position.X;
			Stream >> Position.Y;
			Stream >> Position.Z;
         
			SVertex Vertex;
			Vertex.Position = Position;
			Vertex.Normal = SVector3(0);
         
			Mesh->Vertices.push_back(Vertex);
		}
		else if ("Face" == Label)
void ComputeInterestingSceneParts( const SVector3& lightDir, const SMatrix4x4& cameraViewProj )
{
	bool hit = false;

	SVector3 sweepDir = lightDir;

	// camera frustum
	Frustum sceneFrustum( cameraViewProj );

	gSceneReceivers.clear();
	gSceneCasters.clear();
	gCasterBounds.setNull();
	gReceiverBounds.setNull();

	size_t n = gScene.size();
	for( size_t i = 0; i < n; ++i )
	{
		SceneEntity& obj = *gScene[i];
		CAABox aabb = obj.getAABB();
		aabb.transform( obj.mWorldMat );
		if( aabb.frustumCull( cameraViewProj ) )
		{
			SVector3 spherePos = aabb.getCenter();
			float sphereRadius = SVector3(aabb.getMax()-aabb.getMin()).length() / 2;
			if( sceneFrustum.TestSweptSphere( spherePos, sphereRadius, sweepDir ) )
			{
				hit = true;
				gSceneCasters.push_back( ObjectInfo(aabb,obj) ); // originally in view space
				gCasterBounds.extend( aabb );
			}
		}
		else
		{
			hit = true;
			gSceneCasters.push_back( ObjectInfo(aabb,obj) ); // originally in view space
			gSceneReceivers.push_back( ObjectInfo(aabb,obj) ); // originally in view space
			gCasterBounds.extend( aabb );
			gReceiverBounds.extend( aabb );
		}
	}
}
Exemple #23
0
void gmshFace::secondDer(const SPoint2 &param,
                         SVector3 *dudu, SVector3 *dvdv, SVector3 *dudv) const
{
  if(s->Typ == MSH_SURF_PLAN && !s->geometry){
    *dudu = SVector3(0., 0., 0.);
    *dvdv = SVector3(0., 0., 0.);
    *dudv = SVector3(0., 0., 0.);
  }
  else{
    Vertex vuu = InterpolateSurface(s, param[0], param[1], 2, 1);
    Vertex vvv = InterpolateSurface(s, param[0], param[1], 2, 2);
    Vertex vuv = InterpolateSurface(s, param[0], param[1], 2, 3);
    *dudu = SVector3(vuu.Pos.X,vuu.Pos.Y,vuu.Pos.Z);
    *dvdv = SVector3(vvv.Pos.X,vvv.Pos.Y,vvv.Pos.Z);
    *dudv = SVector3(vuv.Pos.X,vuv.Pos.Y,vuv.Pos.Z);
  }
}
Exemple #24
0
int main(int argc,char *argv[])
{
  if(argc < 6){
    printf("Usage: %s file lx ly lz rmax [levels=1] [refcs=1]\n", argv[0]);
    printf("where\n");
    printf("  'file' contains a CAD model\n");
    printf("  'lx', 'ly' and 'lz' are the sizes of the elements along the"
           " x-, y- and z-axis at the coarsest level\n");
    printf("  'rmax' is the radius of the largest sphere that can be inscribed"
           " in the structure\n");
    printf("  'levels' sets the number of levels in the grid\n");
    printf("  'refcs' selects if curved surfaces should be refined\n");
    return -1;
  }

  GmshInitialize();
  GmshSetOption("General", "Terminal", 1.);
  GmshMergeFile(argv[1]);
  double lx = atof(argv[2]), ly = atof(argv[3]), lz = atof(argv[4]);
  double rmax = atof(argv[5]);
  int levels = (argc > 6) ? atof(argv[6]) : 1;
  int refineCurvedSurfaces = (argc > 7) ? atof(argv[7]) : 1;

  // minimum distance between points in the cloud at the coarsest
  // level
  double sampling = std::min(rmax, std::min(lx, std::min(ly, lz)));

  // radius of the "tube" created around parts to refine at the
  // coarsest level
  double rtube = std::max(lx, std::max(ly, lz)) * 2.;

  GModel *gm = GModel::current();

  std::vector<SPoint3> points;
  Msg::Info("Filling coarse point cloud on surfaces");
  for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++)
    (*fit)->fillPointCloud(sampling, &points);
  Msg::Info("  %d points in the surface cloud", (int)points.size());

  std::vector<SPoint3> refinePoints;
  if(levels > 1){
    double s = sampling / pow(2., levels - 1);
    Msg::Info("Filling refined point cloud on curves and curved surfaces");
    for (GModel::eiter eit = gm->firstEdge(); eit != gm->lastEdge(); eit++)
      fillPointCloud(*eit, s, refinePoints);

    // FIXME: refine this by computing e.g. "mean" curvature
    if(refineCurvedSurfaces){
      for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++)
        if((*fit)->geomType() != GEntity::Plane)
          (*fit)->fillPointCloud(2 * s, &refinePoints);
    }
    Msg::Info("  %d points in the refined cloud", (int)refinePoints.size());
  }

  SBoundingBox3d bb;
  for(unsigned int i = 0; i < points.size(); i++) bb += points[i];
  for(unsigned int i = 0; i < refinePoints.size(); i++) bb += refinePoints[i];
  bb.scale(1.21, 1.21, 1.21);
  SVector3 range = bb.max() - bb.min();
  int NX = range.x() / lx;
  int NY = range.y() / ly;
  int NZ = range.z() / lz;
  if(NX < 2) NX = 2;
  if(NY < 2) NY = 2;
  if(NZ < 2) NZ = 2;

  Msg::Info("  bounding box min: %g %g %g -- max: %g %g %g",
            bb.min().x(), bb.min().y(), bb.min().z(),
            bb.max().x(), bb.max().y(), bb.max().z());
  Msg::Info("  Nx=%d Ny=%d Nz=%d", NX, NY, NZ);

  cartesianBox<double> box(bb.min().x(), bb.min().y(), bb.min().z(),
                           SVector3(range.x(), 0, 0),
                           SVector3(0, range.y(), 0),
                           SVector3(0, 0, range.z()),
                           NX, NY, NZ, levels);

  Msg::Info("Inserting active cells in the cartesian grid");
  Msg::Info("  level %d", box.getLevel());
  for (unsigned int i = 0; i < points.size(); i++)
    insertActiveCells(points[i].x(), points[i].y(), points[i].z(), rmax, box);

  cartesianBox<double> *parent = &box, *child;
  while((child = parent->getChildBox())){
    Msg::Info("  level %d", child->getLevel());
    for(unsigned int i = 0; i < refinePoints.size(); i++)
      insertActiveCells(refinePoints[i].x(), refinePoints[i].y(), refinePoints[i].z(),
                        rtube / pow(2., (levels - child->getLevel())), *child);
    parent = child;
  }

  // remove child cells that do not entirely fill parent cell or for
  // which there is no parent neighbor; then remove parent cells that
  // have children
  Msg::Info("Removing cells to match X-FEM mesh topology constraints");
  removeBadChildCells(&box);
  removeParentCellsWithChildren(&box);

  // we generate duplicate nodes at this point so we can easily access
  // cell values at each level; we will clean up by renumbering after
  // filtering
  Msg::Info("Initializing nodal values in the cartesian grid");
  box.createNodalValues();

  Msg::Info("Computing levelset on the cartesian grid");
  computeLevelset(gm, box);

  Msg::Info("Removing cells outside the structure");
  removeOutsideCells(&box);

  Msg::Info("Renumbering mesh vertices across levels");
  box.renumberNodes();

  bool decomposeInSimplex = false;
  box.writeMSH("yeah.msh", decomposeInSimplex);

  Msg::Info("Done!");
  GmshFinalize();
}
Exemple #25
0
Enemy::Enemy (float random)
{
	srand(random);

	Translation.X = rand() % 9 + 0.5;
	Translation.Y = 0.5;
	Translation.Z = rand() % 9 + 0.5;

	Scale.X = 1; 
	Scale.Y = 1;
	Scale.Z = 1;

	Rotation.Z = 0;
	Rotation.X = 0;
	Rotation.Y = rand() % 360;
	alive = 1;


	size = 0.38;

	next = 0;

	// First create a shader loader and check if our hardware supports shaders
	CShaderLoader ShaderLoader;
	if (! ShaderLoader.isValid())
	{
		std::cerr << "Shaders are not supported by your graphics hardware, or the shader loader was otherwise unable to load." << std::endl;
		waitForUser();
	}

	// Now attempt to load the shaders
	Shader = ShaderLoader.loadShader("Shaders/Lab3_vert.glsl", "Shaders/Lab3_frag.glsl");
	if (! Shader)
	{
		std::cerr << "Unable to open or compile necessary shader." << std::endl;
		waitForUser();
	}
	Shader->loadAttribute("aPosition");
	Shader->loadAttribute("aColor");
        Shader->loadAttribute("aNormal");

	// Now attempt to load the shaders
	Shader2 = ShaderLoader.loadShader("Shaders/Lab3_vert2.glsl", "Shaders/Lab3_frag.glsl");
	if (! Shader2)
	{
		std::cerr << "Unable to open or compile necessary shader." << std::endl;
		waitForUser();
	}
	Shader2->loadAttribute("aPosition");
	Shader2->loadAttribute("aColor");
        Shader2->loadAttribute("aNormal");
	

	// Attempt to load mesh
	CMesh * Mesh = CMeshLoader::loadASCIIMesh("Models/gargoyle500.m");
	if (! Mesh)
	{
		std::cerr << "Unable to load necessary mesh." << std::endl;
		waitForUser();
	}
	// Make out mesh fit within camera view
	Mesh->resizeMesh(SVector3(1));
	// And center it at the origin
	Mesh->centerMeshByExtents(SVector3(0));

	// Now load our mesh into a VBO, retrieving the number of triangles and the handles to each VBO
	CMeshLoader::createVertexBufferObject(* Mesh, TriangleCount, PositionBufferHandle, ColorBufferHandle, NormalBufferHandle);

}
void elasticitySolver::readInputFile(const std::string &fn)
{
  FILE *f = Fopen(fn.c_str(), "r");
  char what[256];
  while(!feof(f)){
    if(fscanf(f, "%s", what) != 1){
      fclose(f);
      return;
    }
    if(what[0]=='#'){
      /*
      char *line=NULL;
      size_t l = 0;
      int r = getline(&line,&l,f);
      free(line);
      */
    }
    else if (!strcmp(what, "ElasticDomain")){
      elasticField field;
      int physical;
      if(fscanf(f, "%d %lf %lf", &physical, &field._E, &field._nu) != 3){
        fclose(f);
        return;
      }
      field._tag = _tag;
      field.g = new groupOfElements (_dim, physical);
      elasticFields.push_back(field);
    }
    else if (!strcmp(what, "LagrangeMultipliers")){
      LagrangeMultiplierField field;
      int physical;
      double d1, d2, d3, val;
      if(fscanf(f, "%d %lf %lf %lf %lf %lf %d", &physical, &field._tau,
                &d1, &d2, &d3, &val, &field._tag) != 7){
        fclose(f);
        return;
      }
      field._tag = _tag;
      field._d = SVector3(d1, d2, d3);
      field._f = simpleFunction<double>(val);
      field.g = new groupOfElements (_dim - 1, physical);
      LagrangeMultiplierFields.push_back(field);
    }
    else if (!strcmp(what, "Void")){
      elasticField field;
      int physical;
      if(fscanf(f, "%d", &physical) != 1){
        fclose(f);
        return;
      }
      field._E = field._nu = 0;
      field.g = new groupOfElements (_dim, physical);
      field._tag = 0;
      elasticFields.push_back(field);
    }
    else if (!strcmp(what, "NodeDisplacement")){
      double val;
      int node, comp;
      if(fscanf(f, "%d %d %lf", &node, &comp, &val) != 3){
        fclose(f);
        return;
      }
      dirichletBC diri;
      diri.g = new groupOfElements (0, node);
      diri._f= new simpleFunction<double>(val);
      diri._comp=comp;
      diri._tag=node;
      diri.onWhat=BoundaryCondition::ON_VERTEX;
      allDirichlet.push_back(diri);
    }
    else if (!strcmp(what, "EdgeDisplacement")){
      double val;
      int edge, comp;
      if(fscanf(f, "%d %d %lf", &edge, &comp, &val) != 3){
        fclose(f);
        return;
      }
      dirichletBC diri;
      diri.g = new groupOfElements (1, edge);
      diri._f= new simpleFunction<double>(val);
      diri._comp=comp;
      diri._tag=edge;
      diri.onWhat=BoundaryCondition::ON_EDGE;
      allDirichlet.push_back(diri);
    }
    else if (!strcmp(what, "FaceDisplacement")){
      double val;
      int face, comp;
      if(fscanf(f, "%d %d %lf", &face, &comp, &val) != 3){
        fclose(f);
        return;
      }
      dirichletBC diri;
      diri.g = new groupOfElements (2, face);
      diri._f= new simpleFunction<double>(val);
      diri._comp=comp;
      diri._tag=face;
      diri.onWhat=BoundaryCondition::ON_FACE;
      allDirichlet.push_back(diri);
    }
    else if (!strcmp(what, "NodeForce")){
      double val1, val2, val3;
      int node;
      if(fscanf(f, "%d %lf %lf %lf", &node, &val1, &val2, &val3) != 4){
        fclose(f);
        return;
      }
      neumannBC neu;
      neu.g = new groupOfElements (0, node);
      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
      neu._tag=node;
      neu.onWhat=BoundaryCondition::ON_VERTEX;
      allNeumann.push_back(neu);
    }
    else if (!strcmp(what, "EdgeForce")){
      double val1, val2, val3;
      int edge;
      if(fscanf(f, "%d %lf %lf %lf", &edge, &val1, &val2, &val3) != 4){
        fclose(f);
        return;
      }
      neumannBC neu;
      neu.g = new groupOfElements (1, edge);
      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
      neu._tag=edge;
      neu.onWhat=BoundaryCondition::ON_EDGE;
      allNeumann.push_back(neu);
    }
    else if (!strcmp(what, "FaceForce")){
      double val1, val2, val3;
      int face;
      if(fscanf(f, "%d %lf %lf %lf", &face, &val1, &val2, &val3) != 4){
        fclose(f);
        return;
      }
      neumannBC neu;
      neu.g = new groupOfElements (2, face);
      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
      neu._tag=face;
      neu.onWhat=BoundaryCondition::ON_FACE;
      allNeumann.push_back(neu);
    }
    else if (!strcmp(what, "VolumeForce")){
      double val1, val2, val3;
      int volume;
      if(fscanf(f, "%d %lf %lf %lf", &volume, &val1, &val2, &val3) != 4){
        fclose(f);
        return;
      }
      neumannBC neu;
      neu.g = new groupOfElements (3, volume);
      neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3));
      neu._tag=volume;
      neu.onWhat=BoundaryCondition::ON_VOLUME;
      allNeumann.push_back(neu);
    }
    else if (!strcmp(what, "MeshFile")){
      char name[245];
      if(fscanf(f, "%s", name) != 1){
        fclose(f);
        return;
      }
      setMesh(name);
    }
    else if (!strcmp(what, "CutMeshPlane")){
      double a, b, c, d;
      if(fscanf(f, "%lf %lf %lf %lf", &a, &b, &c, &d) != 4){
        fclose(f);
        return;
      }
      int tag=1;
      gLevelsetPlane ls(a,b,c,d,tag);
      pModel = pModel->buildCutGModel(&ls);
    }
    else if (!strcmp(what, "CutMeshSphere")){
      double x, y, z, r;
      if(fscanf(f, "%lf %lf %lf %lf", &x, &y, &z, &r) != 4){
        fclose(f);
        return;
      }
      int tag=1;
      gLevelsetSphere ls(x,y,z,r,tag);
      pModel = pModel->buildCutGModel(&ls);
    }
    else {
      Msg::Error("Invalid input : '%s'", what);
    }
  }
  fclose(f);
}
Exemple #27
0
void updateBoVec<3, MFace>(
  const int normalSource, const MVertex *const vertex, const int zoneIndex,
  const int vertIndex,
  const CCon::FaceVector<MZoneBoundary<3>::GlobalVertexData<MFace>::FaceDataB>
    &faces,
  ZoneBoVec &zoneBoVec, BCPatchIndex &patch, bool &warnNormFromElem)
{
  GEntity *ent;
  if(normalSource == NormalSourceElement) goto getNormalFromElements;
  ent = vertex->onWhat();
  if(ent == 0) {
    goto getNormalFromElements;
    // No entity: try to find a normal from the faces
  }
  else {
    switch(ent->dim()) {
    case 0:
    case 1:

      /*--------------------------------------------------------------------*
       * In this case, there are possibly multiple GFaces from this zone
       * connected to the vertex.  One patch for each GFace will be written.
       *--------------------------------------------------------------------*/

      {
        //--Get a list of face entities connected to 'ent'

        std::list<GFace *> gFaceList;
        switch(ent->dim()) {
        case 0: {
          std::vector<GEdge *> gEdgeList = ent->edges();
          std::list<GFace *> gFaceList;
          for(std::vector<GEdge *>::const_iterator gEIt = gEdgeList.begin();
              gEIt != gEdgeList.end(); ++gEIt) {
            std::vector<GFace *> alist = (*gEIt)->faces();
            gFaceList.insert(gFaceList.end(), alist.begin(), alist.end());
          }
          // Remove duplicates
          gFaceList.sort();
          gFaceList.unique();
        } break;
        case 1: {
          std::vector<GFace *> fac = ent->faces();
          gFaceList.insert(gFaceList.end(), fac.begin(), fac.end());
        } break;
        }

        //--Get a list of face entities connected to the 'vertex' that are also
        // in the
        //--zone

        std::list<const GFace *> useGFace;
        std::vector<GEdge *> gEdgeList;
        const int nFace = faces.size();
        for(int iFace = 0; iFace != nFace; ++iFace) {
          if(zoneIndex == faces[iFace].zoneIndex) {
            bool matchedFace = false;
            MFace mFace =
              faces[iFace].parentElement->getFace(faces[iFace].parentFace);
            const int nVOnF = mFace.getNumVertices();
            int vertexOnF = 0; // The index of 'vertex' in the face
            for(int iVOnF = 0; iVOnF != nVOnF; ++iVOnF) {
              const MVertex *const vertex2 = mFace.getVertex(iVOnF);
              if(vertex == vertex2)
                vertexOnF = iVOnF;
              else {
                const GEntity *const ent2 = vertex2->onWhat();
                if(ent2->dim() == 2) {
                  matchedFace = true;
                  useGFace.push_back(static_cast<const GFace *>(ent2));
                  break;
                }
              }
            }
            // Triangle MElements are a total P.I.T.A.:
            // - If the original 'ent' is a vertex, one MVertex can be on the
            //   GVertex, and the other two on GEdges, and then the MElement is
            //   still on the GFace.
            // - If the original 'ent' is an edge, one MVertex can be on the
            //   original GEdge, another on a GVertex, and the final on another
            //   GEdge, and then the MElement is still on the GFace.  There is
            //   also the unlikely case where the two other MVertex are both on
            //   edges ... and the MElement is still on the GFace.
            if(!matchedFace && (3 == nVOnF)) {
              const MVertex *vertex2 = 0;
              const MVertex *vertex3 = 0;
              switch(vertexOnF) {
              case 0:
                vertex2 = mFace.getVertex(1);
                vertex3 = mFace.getVertex(2);
                break;
              case 1:
                vertex2 = mFace.getVertex(0);
                vertex3 = mFace.getVertex(2);
                break;
              case 2:
                vertex2 = mFace.getVertex(0);
                vertex3 = mFace.getVertex(1);
                break;
              }
              if(vertex2 && vertex3) {
                const GEntity *const ent2 = vertex2->onWhat();
                const GEntity *const ent3 = vertex3->onWhat();
                if(ent2 && ent3) {
                  if(ent2->dim() == 1 && ent3->dim() == 1) {
                    // Which GFace is bounded by edges ent2 and ent3?
                    for(std::list<GFace *>::const_iterator gFIt =
                          gFaceList.begin();
                        gFIt != gFaceList.end(); ++gFIt) {
                      gEdgeList = (*gFIt)->edges();
                      if((std::find(gEdgeList.begin(), gEdgeList.end(), ent2) !=
                          gEdgeList.end()) &&
                         (std::find(gEdgeList.begin(), gEdgeList.end(), ent3) !=
                          gEdgeList.end())) {
                        // Edges ent2 and ent3 bound this face
                        useGFace.push_back(*gFIt);
                        break;
                      }
                    }
                  }
                  else if(ent->dim() == 1 && (ent2->dim() + ent3->dim() == 1)) {
                    const GEntity *entCmp;
                    if(ent2->dim() == 1)
                      entCmp = ent2;
                    else
                      entCmp = ent3;
                    // Which GFace is bounded by entCmp
                    for(std::list<GFace *>::const_iterator gFIt =
                          gFaceList.begin();
                        gFIt != gFaceList.end(); ++gFIt) {
                      gEdgeList = (*gFIt)->edges();
                      if(std::find(gEdgeList.begin(), gEdgeList.end(),
                                   entCmp) != gEdgeList.end()) {
                        // Edge entCmp and the original edge bound this face
                        useGFace.push_back(*gFIt);
                        break;
                      }
                    }
                  }
                }
              }
            } // Stupid triangles
          } // End if face in zone
        } // End loop over faces
        // Duplicates are a possibility, remove
        useGFace.sort();
        useGFace.unique();

        //--'useGFace' now contains the face entities that connect to vertex.  A
        // BC
        //--patch will be written for each of them.

        for(std::list<const GFace *>::const_iterator gFIt = useGFace.begin();
            gFIt != useGFace.end(); ++gFIt) {
          SPoint2 par;
          if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), *gFIt,
                                      par))
            goto getNormalFromElements; // :P  After all that!

          SVector3 boNormal = (*gFIt)->normal(par);
          SPoint3 interior(0., 0., 0.);
          int cFace = 0;
          const int nFace = faces.size();
          for(int iFace = 0; iFace != nFace; ++iFace) {
            if(faces[iFace].zoneIndex == zoneIndex) {
              ++cFace;
              interior += faces[iFace].parentElement->barycenter();
            }
          }
          interior /= cFace;
          if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.)
            boNormal.negate();

          zoneBoVec.push_back(
            VertexBoundary(zoneIndex, (*gFIt)->tag(), boNormal,
                           const_cast<MVertex *>(vertex), vertIndex));
          patch.add((*gFIt)->tag());
        }
      }
      break;
    case 2:

      /*--------------------------------------------------------------------*
       * The vertex exists on a face and belongs to only 1 BC patch.
       *--------------------------------------------------------------------*/

      {
        const GFace *const gFace = static_cast<const GFace *>(ent);
        SPoint2 par;
        if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), gFace, par))
          goto getNormalFromElements;

        SVector3 boNormal = static_cast<const GFace *>(ent)->normal(par);
        SPoint3 interior(0., 0., 0.);
        int cFace = 0;
        const int nFace = faces.size();
        for(int iFace = 0; iFace != nFace; ++iFace) {
          if(faces[iFace].zoneIndex == zoneIndex) {
            ++cFace;
            interior += faces[iFace].parentElement->barycenter();
          }
        }
        interior /= cFace;
        if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.)
          boNormal.negate();

        zoneBoVec.push_back(VertexBoundary(zoneIndex, gFace->tag(), boNormal,
                                           const_cast<MVertex *>(vertex),
                                           vertIndex));
        patch.add(gFace->tag());
      }
      break;
    default: goto getNormalFromElements;
    }
  }
  return;

getNormalFromElements:;

  /*--------------------------------------------------------------------*
   * Geometry information cannot be used - generate normals from the
   * elements
   *--------------------------------------------------------------------*/

  {
    if(warnNormFromElem && normalSource == 1) {
      Msg::Warning("Some or all boundary normals were determined from mesh "
                   "elements instead of from the geometry");
      warnNormFromElem = false;
    }
    // Sum the normals from each element connected to the vertex and in the
    // zone.  Each normal has to be converted independently into an inwards-
    // pointing normal.
    //**Weight each normal by the area of the boundary element?
    SVector3 boNormal(0.);
    const int nFace = faces.size();
    for(int iFace = 0; iFace != nFace; ++iFace) {
      if(faces[iFace].zoneIndex == zoneIndex) {
        // Normal to the boundary (unknown direction)
        SVector3 bnt =
          faces[iFace].parentElement->getFace(faces[iFace].parentFace).normal();
        // Inwards normal
        const SVector3 inwards(vertex->point(),
                               faces[iFace].parentElement->barycenter());
        if(dot(bnt, inwards) < 0.) bnt.negate();
        boNormal += bnt;
      }
    }
    boNormal.normalize();
    zoneBoVec.push_back(VertexBoundary(
      zoneIndex, 0, boNormal, const_cast<MVertex *>(vertex), vertIndex));
    patch.add(0);
  }
}
Exemple #28
0
SVector3 gmshSurface::normal(const SPoint2 &param) const
{
  Msg::Error("Normal computation not implemented for this type of surface");
  return SVector3();
}
Exemple #29
0
int GModel::readSTL(const std::string &name, double tolerance)
{
  FILE *fp = Fopen(name.c_str(), "rb");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  // store triplets of points for each solid found in the file
  std::vector<std::vector<SPoint3> > points;
  SBoundingBox3d bbox;

  // "solid", or binary data header
  char buffer[256];
  if(!fgets(buffer, sizeof(buffer), fp)){ fclose(fp); return 0; }

  bool binary = strncmp(buffer, "solid", 5) && strncmp(buffer, "SOLID", 5);

  // ASCII STL
  if(!binary){
    points.resize(1);
    while(!feof(fp)) {
      // "facet normal x y z" or "endsolid"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      if(!strncmp(buffer, "endsolid", 8) ||
         !strncmp(buffer, "ENDSOLID", 8)){
        // "solid"
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        if(!strncmp(buffer, "solid", 5) ||
           !strncmp(buffer, "SOLID", 5)){
          points.resize(points.size() + 1);
          // "facet normal x y z"
          if(!fgets(buffer, sizeof(buffer), fp)) break;
        }
      }
      // "outer loop"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      // "vertex x y z"
      for(int i = 0; i < 3; i++){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        char s1[256];
        double x, y, z;
        if(sscanf(buffer, "%s %lf %lf %lf", s1, &x, &y, &z) != 4) break;
        SPoint3 p(x, y, z);
        points.back().push_back(p);
        bbox += p;
      }
      // "endloop"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      // "endfacet"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
    }
   }

  // check if we could parse something
  bool empty = true;
  for(unsigned int i = 0; i < points.size(); i++){
    if(points[i].size()){
      empty = false;
      break;
    }
  }
  if(empty) points.clear();

  // binary STL (we also try to read in binary mode if the header told
  // us the format was ASCII but we could not read any vertices)
  if(binary || empty){
    if(binary)
      Msg::Info("Mesh is in binary format");
    else
      Msg::Info("Wrong ASCII header or empty file: trying binary read");
    rewind(fp);
    while(!feof(fp)) {
      char header[80];
      if(!fread(header, sizeof(char), 80, fp)) break;
      unsigned int nfacets = 0;
      size_t ret = fread(&nfacets, sizeof(unsigned int), 1, fp);
      bool swap = false;
      if(nfacets > 100000000){
        Msg::Info("Swapping bytes from binary file");
        swap = true;
        SwapBytes((char*)&nfacets, sizeof(unsigned int), 1);
      }
      if(ret && nfacets){
        points.resize(points.size() + 1);
        char *data = new char[nfacets * 50 * sizeof(char)];
        ret = fread(data, sizeof(char), nfacets * 50, fp);
        if(ret == nfacets * 50){
          for(unsigned int i = 0; i < nfacets; i++) {
            float *xyz = (float *)&data[i * 50 * sizeof(char)];
            if(swap) SwapBytes((char*)xyz, sizeof(float), 12);
            for(int j = 0; j < 3; j++){
              SPoint3 p(xyz[3 + 3 * j], xyz[3 + 3 * j + 1], xyz[3 + 3 * j + 2]);
              points.back().push_back(p);
              bbox += p;
            }
          }
        }
        delete [] data;
      }
    }
  }

  std::vector<GFace*> faces;
  for(unsigned int i = 0; i < points.size(); i++){
    if(points[i].empty()){
      Msg::Error("No facets found in STL file for solid %d", i);
      fclose(fp);
      return 0;
    }
    if(points[i].size() % 3){
      Msg::Error("Wrong number of points (%d) in STL file for solid %d",
                 points[i].size(), i);
      fclose(fp);
      return 0;
    }
    Msg::Info("%d facets in solid %d", points[i].size() / 3, i);
    // create face
    GFace *face = new discreteFace(this, getMaxElementaryNumber(2) + 1);
    faces.push_back(face);
    add(face);
  }

  // create triangles using unique vertices
  double eps = norm(SVector3(bbox.max(), bbox.min())) * tolerance;
  std::vector<MVertex*> vertices;
  for(unsigned int i = 0; i < points.size(); i++)
    for(unsigned int j = 0; j < points[i].size(); j++)
      vertices.push_back(new MVertex(points[i][j].x(), points[i][j].y(),
                                     points[i][j].z()));
  MVertexPositionSet pos(vertices);

  std::set<MFace,Less_Face> unique;
  int nbDuplic = 0;
  for(unsigned int i = 0; i < points.size(); i ++){
    for(unsigned int j = 0; j < points[i].size(); j += 3){
      MVertex *v[3];
      for(int k = 0; k < 3; k++){
        double x = points[i][j + k].x();
        double y = points[i][j + k].y();
        double z = points[i][j + k].z();
        v[k] = pos.find(x, y, z, eps);
      }
      MFace mf (v[0], v[1], v[2]);
      if (unique.find(mf) == unique.end()){
	faces[i]->triangles.push_back(new MTriangle(v[0], v[1], v[2]));
	unique.insert(mf);
      }
      else{
	nbDuplic++;
      }
    }
  }
  if (nbDuplic)
    Msg::Warning("%d duplicate triangles in STL file", nbDuplic);

  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertices); // will delete unused vertices

  fclose(fp);
  return 1;
}
Exemple #30
0
PView *GMSH_DistancePlugin::execute(PView *v)
{
  int id_pt   = (int) DistanceOptions_Number[0].def;
  int id_line = (int) DistanceOptions_Number[1].def;
  int id_face = (int) DistanceOptions_Number[2].def;
  double type = (double) DistanceOptions_Number[3].def;
  int ortho   = (int) DistanceOptions_Number[6].def;

  PView *view = new PView();
  _data = getDataList(view);
#if defined(HAVE_SOLVER)
#if defined(HAVE_TAUCS)
  linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
#else
  linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>;
  lsys->setNoisy(1);
  lsys->setGmres(1);
  lsys->setPrec(5.e-8);
#endif
  dofManager<double> * dofView = new dofManager<double>(lsys);
#endif

  std::vector<GEntity*> _entities;
  GModel::current()->getEntities(_entities);
  if (!_entities.size() || !_entities[_entities.size()-1]->getMeshElement(0)) {
    Msg::Error("This plugin needs a mesh !");
    return view;
  }

  GEntity* ge = _entities[_entities.size()-1];
  int integrationPointTetra[2] = {0,0};

  int numnodes = 0;
  for (unsigned int i = 0; i < _entities.size()-1; i++)
    numnodes += _entities[i]->mesh_vertices.size();
  int totNodes = numnodes + _entities[_entities.size()-1]->mesh_vertices.size();
  int order = ge->getMeshElement(0)->getPolynomialOrder();
  int totNumNodes = totNodes + ge->getNumMeshElements()*integrationPointTetra[order-1];

  std::vector<SPoint3> pts;
  std::vector<double> distances;
  std::vector<MVertex* > pt2Vertex;
  pts.clear();
  distances.clear();
  pt2Vertex.clear();
  pts.reserve(totNumNodes);
  distances.reserve(totNumNodes);
  pt2Vertex.reserve(totNumNodes);

  std::map<MVertex*,double> _distanceE_map;
  std::map<MVertex*,int> _isInYarn_map;
  std::vector<int> index;
  std::vector<double> distancesE;
  std::vector<double> distances2;
  std::vector<double> distancesE2;
  std::vector<int> isInYarn;
  std::vector<int> isInYarn2;
  std::vector<SPoint3> closePts;
  std::vector<SPoint3> closePts2;

  for (int i=0; i<totNumNodes; i++) {
    distances.push_back(1.e22);
  }

  int k = 0;
  for (unsigned int i=0; i<_entities.size(); i++){
    GEntity* ge = _entities[i];
    _maxDim = std::max(_maxDim, ge->dim());
    for (unsigned int j=0; j<ge->mesh_vertices.size(); j++) {
      MVertex *v = ge->mesh_vertices[j];
      pts.push_back(SPoint3(v->x(), v->y(), v->z()));
      _distance_map.insert(std::make_pair(v, 0.0));
/* TO DO (by AM)
      SPoint3 p_empty();
      _closePts_map.insert(std::make_pair(v, p_empty));
*/
      pt2Vertex[k] = v;
      k++;
    }
  }

  // Compute geometrical distance to mesh boundaries
  //------------------------------------------------------
  if (type < 0.0 ) {

    bool existEntity = false;

    for (unsigned int i=0; i<_entities.size(); i++) {
      GEntity* g2 = _entities[i];
      int gDim = g2->dim();
      std::vector<int> phys = g2->getPhysicalEntities();
      bool computeForEntity = false;
      for(unsigned int k = 0; k<phys.size(); k++) {
        int tagp = phys[k];
        if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1)
          computeForEntity = true;
        else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) ||
                 (tagp == id_face && gDim == 2))
          computeForEntity = true;
      }
      if (computeForEntity) {
        existEntity = true;
        for (unsigned int k = 0; k < g2->getNumMeshElements(); k++) {
          std::vector<double> iDistances;
          std::vector<SPoint3> iClosePts;
          std::vector<double> iDistancesE;
          std::vector<int> iIsInYarn;
          MElement *e = g2->getMeshElement(k);
          MVertex *v1 = e->getVertex(0);
          MVertex *v2 = e->getVertex(1);
          SPoint3 p1(v1->x(), v1->y(), v1->z());
          SPoint3 p2(v2->x(), v2->y(), v2->z());
          if ((e->getNumVertices() == 2 && order == 1) ||
              (e->getNumVertices() == 3 && order == 2)) {
            signedDistancesPointsLine(iDistances, iClosePts, pts, p1, p2);
          }
          else if ((e->getNumVertices() == 3 && order == 1) ||
                   (e->getNumVertices() == 6 && order == 2)) {
            MVertex *v3 = e->getVertex(2);
            SPoint3 p3 (v3->x(),v3->y(),v3->z());
            signedDistancesPointsTriangle(iDistances, iClosePts, pts, p1, p2, p3);
          }
          for (unsigned int kk=0; kk<pts.size(); kk++) {
            if (std::abs(iDistances[kk]) < distances[kk]) {
              distances[kk] = std::abs(iDistances[kk]);
              MVertex *v = pt2Vertex[kk];
              _distance_map[v] = distances[kk];
              /* TO DO (by AM)
              _closePts_map[v] = iClosePts[kk];
              */
            }
          }
        }
      }
    }
    if (!existEntity){
      if (id_pt != 0)   Msg::Error("The Physical Point does not exist !");
      if (id_line != 0) Msg::Error("The Physical Line does not exist !");
      if (id_face != 0) Msg::Error("The Physical Surface does not exist !");
      return view;
    }

    printView(_entities, _distance_map);

    /* TO DO (by AM)
    printView(_entities, _closePts_map);
    */
  }

  // Compute PDE for distance function
  //-----------------------------------
  else if (type > 0.0) {

#if defined(HAVE_SOLVER)

    bool existEntity = false;
    SBoundingBox3d bbox;
    for(unsigned int i = 0; i < _entities.size(); i++){
      GEntity* ge = _entities[i];
      int gDim = ge->dim();
      bool fixForEntity = false;
      std::vector<int> phys = ge->getPhysicalEntities();
      for(unsigned int k = 0; k < phys.size(); k++) {
        int tagp = phys[k];
        if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1)
          fixForEntity = true;
        else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) ||
                 (tagp == id_face && gDim == 2) )
          fixForEntity = true;
      }
      if (fixForEntity) {
        existEntity = true;
        for (unsigned int i = 0; i < ge->getNumMeshElements(); ++i) {
          MElement *t = ge->getMeshElement(i);
          for (int k=0; k<t->getNumVertices(); k++) {
            MVertex *v = t->getVertex(k);
            dofView->fixVertex(v, 0, 1, 0.);
            bbox += SPoint3(v->x(), v->y(), v->z());
          }
        }
      }
    }

    if (!existEntity){
      if (id_pt != 0)   Msg::Error("The Physical Point does not exist !");
      if (id_line != 0) Msg::Error("The Physical Line does not exist !");
      if (id_face != 0) Msg::Error("The Physical Surface does not exist !");
      return view;
    }

    std::vector<MElement *> allElems;
    for(unsigned int ii = 0; ii < _entities.size(); ii++){
      if(_entities[ii]->dim() == _maxDim) {
        GEntity *ge = _entities[ii];
        for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i) {
          MElement *t = ge->getMeshElement(i);
          allElems.push_back(t);
          for (int k = 0; k < t->getNumVertices(); k++)
            dofView->numberVertex(t->getVertex(k), 0, 1);
        }
      }
    }

    double L = norm(SVector3(bbox.max(), bbox.min()));
    double mu = type*L;

    simpleFunction<double> DIFF(mu*mu), ONE(1.0);
    distanceTerm distance(GModel::current(), 1, &DIFF, &ONE);

    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      SElement se((*it));
      distance.addToMatrix(*dofView, &se);
    }
    groupOfElements gr(allElems);
    distance.addToRightHandSide(*dofView, gr);

    Msg::Info("Distance Computation: Assembly done");
    lsys->systemSolve();
    Msg::Info("Distance Computation: System solved");

    for (std::map<MVertex*,double >::iterator itv = _distance_map.begin();
         itv != _distance_map.end() ; ++itv) {
      MVertex *v = itv->first;
      double value;
      dofView->getDofValue(v, 0, 1, value);
      value = std::min(0.9999, value);
      double dist = -mu * log(1. - value);
      itv->second = dist;
    }

    printView(_entities, _distance_map);

#endif
  }

  _data->setName("distance");
  _data->Time.push_back(0);
  _data->setFileName(_fileName.c_str());
  _data->finalize();

  // compute also orthogonal vector to distance field
  // A Uortho = -C DIST
  //------------------------------------------------
  if (ortho > 0) {
#if defined(HAVE_SOLVER)

#ifdef HAVE_TAUCS
    linearSystemCSRTaucs<double> *lsys2 = new linearSystemCSRTaucs<double>;
#else
    linearSystemCSRGmm<double> *lsys2 = new linearSystemCSRGmm<double>;
    lsys->setNoisy(1);
    lsys->setGmres(1);
    lsys->setPrec(5.e-8);
#endif
    dofManager<double> myAssembler(lsys2);
    simpleFunction<double> ONE(1.0);

    double dMax = 1.0; //EMI TO CHANGE

    std::vector<MElement *> allElems;
    for(unsigned int ii = 0; ii < _entities.size(); ii++){
      if (_entities[ii]->dim() == _maxDim) {
        GEntity *ge = _entities[ii];
        for (unsigned int i=0; i<ge->getNumMeshElements(); ++i) {
          MElement *t = ge->getMeshElement(i);
          double vMean = 0.0;
          for (int k = 0; k < t->getNumVertices(); k++) {
            std::map<MVertex*, double>::iterator it = _distance_map.find(t->getVertex(k));
            vMean += it->second;
          }
          vMean /= t->getNumVertices();
          if (vMean < dMax)
            allElems.push_back(ge->getMeshElement(i));
        }
      }
    }

    int mid = (int)floor(allElems.size() / 2.);
    MElement *e = allElems[mid];
    MVertex *vFIX = e->getVertex(0);
    myAssembler.fixVertex(vFIX, 0, 1, 0.0);

    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      MElement *t = *it;
      for(int k = 0; k < t->getNumVertices(); k++)
        myAssembler.numberVertex(t->getVertex(k), 0, 1);
    }

    orthogonalTerm *ortho;
    ortho  = new orthogonalTerm(GModel::current(), 1, &ONE, &_distance_map);
    // if (type  < 0)
    //   ortho  = new orthogonalTerm(GModel::current(), 1, &ONE, view);
    // else
    //   ortho  = new orthogonalTerm(GModel::current(), 1, &ONE, dofView);

    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      SElement se((*it));
      ortho->addToMatrix(myAssembler, &se);
    }
    groupOfElements gr(allElems);
    ortho->addToRightHandSide(myAssembler, gr);

    Msg::Info("Orthogonal Computation: Assembly done");
    lsys2->systemSolve();
    Msg::Info("Orthogonal Computation: System solved");

    PView *view2 = new PView();
    PViewDataList *data2 = getDataList(view2);
    data2->setName("ortogonal field");

    Msg::Info("Writing  orthogonal.pos");
    FILE * f5 = Fopen("orthogonal.pos","w");
    fprintf(f5,"View \"orthogonal\"{\n");
    for (std::vector<MElement* >::iterator it = allElems.begin();
         it != allElems.end(); it++){
      MElement *e = *it;

    int numNodes = e->getNumVertices();
    if (e->getType() == TYPE_POLYG)
      numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices();
    std::vector<double> x(numNodes), y(numNodes), z(numNodes);
    std::vector<double> *out2 = data2->incrementList(1, e->getType(), numNodes);
    std::vector<MVertex*> nods;
    std::vector<double> orth;

    if(!e->getNumChildren())
      for(int i=0; i<numNodes; i++)
        nods.push_back(e->getVertex(i));
    else
      for(int i = 0; i < e->getNumChildren(); i++)
        for(int j = 0; j < e->getChild(i)->getNumVertices(); j++)
          nods.push_back(e->getChild(i)->getVertex(j));

    for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->x());
    for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->y());
    for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->z());

    if (_maxDim == 2)
      switch (numNodes) {
        case 2: fprintf(f5,"SL("); break;
        case 3: fprintf(f5,"ST("); break;
        case 4: fprintf(f5,"SQ("); break;
        default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break;
      }
    else if (_maxDim == 3)
      switch (numNodes) {
        case 4: fprintf(f5,"SS("); break;
        case 8: fprintf(f5,"SH("); break;
        case 6: fprintf(f5,"SI("); break;
        case 5: fprintf(f5,"SY("); break;
        default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break;
      }

    for (int j=0; j<numNodes; j++) {
      MVertex *v =  nods[j];
      if (j)
        fprintf(f5, ",%g,%g,%g", v->x(), v->y(), v->z());
      else
        fprintf(f5, "%g,%g,%g", v->x(), v->y(), v->z());
      double value;
      myAssembler.getDofValue(v, 0, 1, value);
      orth.push_back(value);
    }
    fprintf(f5,"){");
    for (unsigned int i=0; i<orth.size(); i++) {
      out2->push_back(orth[i]);
      if (i)
        fprintf(f5,",%g", orth[i]);
      else
        fprintf(f5,"%g", orth[i]);
    }
    fprintf(f5,"};\n");

  }
  fprintf(f5,"};\n");
  fclose(f5);

  lsys->clear();
  lsys2->clear();

  data2->Time.push_back(0);
  data2->setFileName("orthogonal.pos");
  data2->finalize();

#endif
  }

  return view;
}