Example #1
0
void Centerline::run()
{
  double t1 = Cpu();
  if (update_needed){
    std::ifstream input;
    //std::string pattern = FixRelativePath(fileName, "./");
    //Msg::StatusBar(true, "Reading TEST '%s'...", pattern.c_str());
    //input.open(pattern.c_str());
    input.open(fileName.c_str());
    if(StatFile(fileName))
      Msg::Fatal("Centerline file '%s' does not exist ", fileName.c_str());
    importFile(fileName);
    buildKdTree();
    update_needed = false;
  }

  if (is_cut) cutMesh();
  else{
    GFace *gf = current->getFaceByTag(1);
    gf->addPhysicalEntity(1);
    current->setPhysicalName("wall", 2, 1);//tag 1
    current->createTopologyFromMesh();
    NV = current->getMaxElementaryNumber(0);
    NE = current->getMaxElementaryNumber(1);
    NF = current->getMaxElementaryNumber(2);
    NR = current->getMaxElementaryNumber(3);
  }

  //identify the boundary edges by looping over all discreteFaces
  std::vector<GEdge*> boundEdges;
  double dist_inlet = 1.e6;
  GEdge *gin = NULL;
  for (int i= 0; i< NF; i++){
    GFace *gf = current->getFaceByTag(i+1);
    std::list<GEdge*> l_edges = gf->edges();
    for(std::list<GEdge*>::iterator it = l_edges.begin(); it != l_edges.end(); it++){
      std::vector<GEdge*>::iterator ite = std::find(boundEdges.begin(),
                                                    boundEdges.end(), *it);
      if (ite != boundEdges.end()) boundEdges.erase(ite);
      else boundEdges.push_back(*it);
      GVertex *gv = (*it)->getBeginVertex();
      SPoint3 pt(gv->x(), gv->y(), gv->z());
      double dist = pt.distance(ptin);
      if(dist < dist_inlet){
	dist_inlet = dist;
	gin = *it;
      }
    }
  }

  if (is_closed)   createClosedVolume(gin, boundEdges);
  if (is_extruded) extrudeBoundaryLayerWall(gin, boundEdges);

  double t2 = Cpu();
  Msg::Info("Centerline operators computed in %g (s) ",t2-t1);
}
std::list<MeshData> voronoiShatter(MeshData &meshData, std::list<KDPoint> points, bool useDelaunay, double bCriteria, double sCriteria)
{
	CGAL::Timer timer;
	timer.start();

	std::list<MeshData> resultMeshdata;

	Delaunay T(points.begin(), points.end());
	std::cout << "T.number_of_vertices:" <<  T.number_of_vertices() << std::endl;
	std::cout << "T.number_of_edges:" <<  T.number_of_finite_edges() << std::endl;
	std::cout << "T.is_valid:" <<  T.is_valid() << std::endl;

	int countNumberVertices = 0; //Just to count
	Delaunay::Finite_vertices_iterator vit;
	for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit)
	{
		DVertex_handle vh = vit;

		std::list<Triangle> cutMeshTriangles = meshData.first;
		std::list<TriangleInfo> cutInfo = meshData.second;

		std::list<DEdge> segs;
		T.finite_incident_edges(vh, std::back_inserter(segs));
		std::cout << " (" << countNumberVertices++ << ")  num edges: " << segs.size() << std::endl;

		std::list<DEdge>::iterator segsIter;
		for(segsIter=segs.begin(); segsIter!= segs.end(); ++segsIter)
		{
			DEdge edg = *segsIter;
			DSegment_3 segment = T.segment(edg);
			KDVector vect = segment.to_vector();
			KDPoint p1 = segment.source();
			KDPoint p2 = segment.target();

			//KDPoint mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0);
			//Plane planeCutter_voronoi(PointCGAL(mp.x(), mp.y(), mp.z()), Vector(-vect.x(), -vect.y(), -vect.z()));
			//TODO: potrebbe esserci un errore a causa dei punti non esatti p1 e p2
			PointCGAL mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0);
			Plane planeCutter_voronoi(mp, Vector(-vect.x(), -vect.y(), -vect.z()));

			MeshData cutData = cutMesh(cutMeshTriangles, planeCutter_voronoi, cutInfo, useDelaunay, bCriteria, sCriteria);
			cutMeshTriangles = cutData.first;
			cutInfo = cutData.second;

			//std::cout << "    temp mesh size: " << cutMeshTriangles.size() << std::endl;

			//TODO: change TriangleInfo adding:
			// int meshId, meshIdAdjacent
			// and populate these new two variable for the triangles into the cut plane;
			// each mesh piece will have a different id;
			// these two new variable could be used into the RejointMeshes algorithm instead of reportAdjacentIntersectionCallback:
			// knowing this ids it is very easy remove the the triangles in shared cut surfaces

		}

		if (cutMeshTriangles.size() > 0)
		{
			resultMeshdata.push_back(MeshData(cutMeshTriangles, cutInfo));
		}
		else
		{
			std::cout << "    Warning: Final Voronoi mesh size empty!!" << std::endl;
		}
	}

	timer.stop();
	std::cout << "Total voronoiShatter construction took " << timer.time() << " seconds, total cells:" << resultMeshdata.size() << std::endl;

	return resultMeshdata;
}
		void operator()( DVertex_handle vh ) const {
			//std::cout << "TBBVoronoiCell::operator()" << std::endl;

			mutexforDelaunayVoronoiTbb.lock();

			//The direct assign of cutMeshTriangles = meshData->first causes a crash on multiple calls of voronoiShatter,
			// due to the copy of the Triangle. In order to work correctly, the Triangle are recreated
			//std::list<Triangle> cutMeshTriangles = meshData->first;
			std::list<TriangleInfo> cutInfo = meshData->second;
			std::list<Triangle> cutMeshTriangles;
			//std::list<TriangleInfo> cutInfo;
			std::list<Triangle>::iterator triangleIter;
			for(triangleIter=meshData->first.begin(); triangleIter!= meshData->first.end(); ++triangleIter)
			{
				Triangle t = *triangleIter;
				cutMeshTriangles.push_back(Triangle(t.vertex(0),t.vertex(1),t.vertex(2))); //See the comment above
			}
			//std::list<TriangleInfo>::iterator triangleInfoIter;
			//for(triangleInfoIter=meshData->second.begin(); triangleInfoIter!= meshData->second.end(); ++triangleInfoIter)
			//{
			//	TriangleInfo ti = *triangleInfoIter;
			//	cutInfo.push_back(ti);
			//}

			std::list<DEdge> segs;
			T->finite_incident_edges(vh, std::back_inserter(segs));
			mutexforDelaunayVoronoiTbb.unlock();
			std::cout << "  num edges: " << segs.size() << std::endl;

			std::list<DEdge>::iterator segsIter;
			for(segsIter=segs.begin(); segsIter!= segs.end(); ++segsIter)
			{
				DEdge edg = *segsIter;
				mutexforDelaunayVoronoiTbb.lock();
				DSegment_3 segment = T->segment(edg);
				mutexforDelaunayVoronoiTbb.unlock();
				KDVector vect = segment.to_vector();
				KDPoint p1 = segment.source();
				KDPoint p2 = segment.target();

				//KDPoint mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0);
				//Plane planeCutter_voronoi(PointCGAL(mp.x(), mp.y(), mp.z()), Vector(-vect.x(), -vect.y(), -vect.z()));
				//TODO: potrebbe esserci un errore a causa dei punti non esatti p1 e p2
				PointCGAL mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0);
				Plane planeCutter_voronoi(mp, Vector(-vect.x(), -vect.y(), -vect.z()));

				MeshData cutData = cutMesh(cutMeshTriangles, planeCutter_voronoi, cutInfo, useDelaunay, bCriteria, sCriteria);
				cutMeshTriangles = cutData.first;
				cutInfo = cutData.second;

				//std::cout << "    temp mesh size: " << cutMeshTriangles.size() << std::endl;
			}

			mutexforDelaunayVoronoiTbb.lock();
			if (cutMeshTriangles.size() > 0)
			{
				//concurrentResultMeshdata->push_back(MeshData(cutMeshTriangles, cutInfo));
				resultMeshdata->push_back(MeshData(cutMeshTriangles, cutInfo));
			}
			else
			{
				std::cout << "    Warning: Final Voronoi mesh size empty!!" << std::endl;
			}
			mutexforDelaunayVoronoiTbb.unlock();

		}