예제 #1
0
//Find the barycenter for each mesh and translate each mesh into the barycenter, returning mesh and barycenter
std::list<TranslatedMeshData> centerMeshesInBarycenter(std::list<MeshData> &listMeshData)
{

	std::list< std::pair<MeshData,PointCGAL> > result;
	std::list<MeshData>::iterator meshDataInter;
	for(meshDataInter = listMeshData.begin(); meshDataInter != listMeshData.end(); ++meshDataInter)
	{
		MeshData meshData = *meshDataInter;
		PointCGAL barycenter = getMeshBarycenter(meshData);
		MeshData meshDataTranslated = translateMesh(meshData, PointCGAL(-barycenter.x(), -barycenter.y(), -barycenter.z()));
		result.push_back(TranslatedMeshData(meshDataTranslated, barycenter));
	}

	return result;
}
예제 #2
0
		TripleDouble PointsMapperArchive::getMappedPoint(PointCGAL p)
		{
			std::map<PointCGAL, TripleDouble>::iterator foundPair = mapPointsDoubleValues.find(p);
			if (foundPair == mapPointsDoubleValues.end())
			{
				double x = CGAL::to_double(p.x());
				double y = CGAL::to_double(p.y());
				double z = CGAL::to_double(p.z());
				TripleDouble tripleDouble;
				tripleDouble.d1 = x;
				tripleDouble.d2 = y;
				tripleDouble.d3 = z;
				mapPointsDoubleValues.insert(std::pair<PointCGAL, TripleDouble>(p, tripleDouble));
				return tripleDouble;
			}
			else
			{
				return foundPair->second;
			}
		}
예제 #3
0
MeshData translateMesh(MeshData &meshData, PointCGAL point)
{
	std::list<Triangle> *meshTriangles = &(meshData.first);
	//std::list<TriangleInfo> cutInfo = meshData.second;

	std::list<Triangle> meshTrianglesTranslated;
	CGAL::Aff_transformation_3<Kernel> translate(CGAL::TRANSLATION, Vector(point.x(), point.y(), point.z()));

	std::list<Triangle>::iterator triangleIter;
	for(triangleIter = meshTriangles->begin(); triangleIter != meshTriangles->end(); ++triangleIter)
	{
		//Method 1
		//Triangle t = *triangleIter;
		//Triangle tTranslated(translate(t.vertex(0)), translate(t.vertex(1)), translate(t.vertex(2)) );
		//meshTrianglesTranslated.push_back(tTranslated);

		//Method 2
		meshTrianglesTranslated.push_back(triangleIter->transform(translate));
	}

	//return MeshData(meshTrianglesTranslated, cutInfo);
	return MeshData(meshTrianglesTranslated, meshData.second);
}
예제 #4
0
cv::Point2d DelaunayTri::GetCircumcenter(const cv::Point2d &a, const cv::Point2d &b, const cv::Point2d &c) {
    PointCGAL p = dt.circumcenter(PointCGAL(a.x, a.y), PointCGAL(b.x, b.y), PointCGAL(c.x, c.y));
    return cv::Point2d(p.x(), p.y());
}
예제 #5
0
//TODO: use CGAL::Cartesian_converter<K1,K2> converter;
//K1::Point_3 p_k1(1,2,3);
//K2::Point_3 p_k2 = converter( p_k1 );
KDPoint converPointExactToInexact(PointCGAL point)
{
	return KDPoint(CGAL::to_double(point.x()), CGAL::to_double(point.y()), CGAL::to_double(point.z()));
}
예제 #6
0
/*
 * Given a site with known fluidness, examine the links to not-yet-visited
 * neighbouring sites. If the neighbours have unknown fluidness, set that.
 *
 * Since we wish to examine each link only once, this will set link properties
 * from neighbour => site as well as site => neighbour
 *
 */
void PolyDataGenerator::ClassifySite(Site& site) {
        if (!site.IsFluidKnown){
		throw GenerationErrorMessage("The start site is not known cannot continue");
	}
	for (LaterNeighbourIterator neighIt = site.begin(); neighIt != site.end();
		 ++neighIt) {
	  	Site& neigh = *neighIt;
		unsigned int iNeigh = neighIt.GetNeighbourIndex();
		int nHits = Intersect(site,neigh);
		// Four cases: fluid-fluid, solid-solid, fluid-solid and solid-fluid.
		// Will handle the last two together.
		if (site.IsFluid == neigh.IsFluid) {
			if (site.IsFluid) {
				// Fluid-fluid, must set CUT_NONE for both
				site.Links[iNeigh].Type = geometry::CUT_NONE;
				neigh.Links[Neighbours::inverses[iNeigh]].Type =
					geometry::CUT_NONE;
			} else {
				// solid-solid, nothing to do.
			}
		} else {
			// They differ, figure out which is fluid and which is solid.
			Site* fluid;
			Site* solid;

			// Index of the solid site from the fluid site.
			int iSolid;
			// Index of the point in this->hitPoints we're considering as the
			// hit of interest (i.e. the one closest to the fluid site).
			int iHit;

			Vector hitPoint;
			PointCGAL hitPointCGAL;
			SegmentCGAL hitsegmentCGAL;
			int hitCellId;
			double distancetol = 0.01;
			std::vector<int> CloseIoletIDS;
			if (nHits == -1){//unclassified intersection need to be carefull.
				if (site.IsFluid) {
					fluid = &site;
					solid = &neigh;
					iSolid = iNeigh;
					int n=0;
					iHit = n;
					// here we iterate over all intersections until we 
					// find a wall or the rest are futher away than the tol.
					for (std::vector<Object_Primitive_and_distance>::iterator distit 
							 = IntersectionCGAL.begin(); distit != IntersectionCGAL.end(); ++distit){
						if (distit->second > IntersectionCGAL[0].second+distancetol){
							iHit = n;
							break;
						}
						int tempioletId = distit->first.second->id() - 2; 
						//shifting back from unsigned
						if (tempioletId < 0){
							break;//hit a wall no need to continue.
						}//what if we hit both an inlet and outlet. Can that ever happen?
						++n;
					}
					
				} else {
					fluid = &neigh;
					solid = &site;
					iSolid = Neighbours::inverses[iNeigh];
					int n = IntersectionCGAL.size()-1;
					iHit = n;
					for (std::vector<Object_Primitive_and_distance>::reverse_iterator distit 
							 = IntersectionCGAL.rbegin(); distit != IntersectionCGAL.rend(); ++distit){
						if (distit->second < IntersectionCGAL.back().second - distancetol){
							iHit = n;
							break;//ignoring the following intersections, they are to far away.
						}
						int tempioletId = distit->first.second->id() - 2; //shifting back from unsigned
						if (tempioletId < 0){
							break;//hit a wall no need to continue.
						}//what if we hit both an inlet and outlet. Can that ever happen?
						--n;
					}
				}
			}
			else{//normal intersection just take the closest point.
				
				if (site.IsFluid) {
					fluid = &site;
					solid = &neigh;
					iSolid = iNeigh;   
					iHit = 0;
				} else {
					fluid = &neigh;
					solid = &site;
					iSolid = Neighbours::inverses[iNeigh];
					iHit = nHits - 1;
				}
			}
			Object_Primitive_and_distance hitpoint_triangle_dist = IntersectionCGAL[iHit];

			if (CGAL::assign(hitPointCGAL, hitpoint_triangle_dist.first.first)){
			//we do an explicite cast to double here. 
			//The cast to double is only needed if we use an exact_construction kernel. 
			//Otherwise this is already a double but keeping this in makes it 
			//posible to change the kernel for testing.
				hitPoint = Vector(CGAL::to_double(hitPointCGAL.x()),CGAL::to_double(hitPointCGAL.y()),
						  CGAL::to_double(hitPointCGAL.z()));
			}
			else if (CGAL::assign(hitsegmentCGAL, hitpoint_triangle_dist.first.first)){
				hitPointCGAL = CGAL::midpoint(hitsegmentCGAL.vertex(0),hitsegmentCGAL.vertex(1));
				hitPoint = Vector(CGAL::to_double(hitPointCGAL.x()),CGAL::to_double(hitPointCGAL.y()),
						  CGAL::to_double(hitPointCGAL.z()));
			}
			else{
				throw GenerationErrorMessage("This type of intersection should not happen");
			}

			LinkData& link = fluid->Links[iSolid];
			
			// This is set in any solid case
			float distanceInVoxels =
				(hitPoint - fluid->Position).GetMagnitude();
			// The distance is in voxels but must be output as a fraction of
			// the lattice vector. Scale it.
			link.Distance = distanceInVoxels / Neighbours::norms[iSolid];
			
			int ioletId =  hitpoint_triangle_dist.first.second->id() - 2;
			//shifting back from unsigned.
			if (ioletId < 0) {
				// -1 => we hit a wall
				link.Type = geometry::CUT_WALL;
			} else {
				// We hit an inlet or outlet
				Iolet* iolet = this->Iolets[ioletId];
				if (iolet->IsInlet) {
					link.Type = geometry::CUT_INLET;
				} else {
					link.Type = geometry::CUT_OUTLET;
				}
				// Set the Id
				link.IoletId = iolet->Id;
			}
			
			// If this link intersected the wall, store the normal of the cell we hit and the distance to it.
			if (link.Type == geometry::CUT_WALL) {
				VectorCGAL CGALNorm = 
				CGAL::cross_product(hitpoint_triangle_dist.first.second->halfedge()->next()->vertex()->point() 
									- hitpoint_triangle_dist.first.second->halfedge()->vertex()->point(),
				 hitpoint_triangle_dist.first.second->halfedge()->next()->next()->vertex()->point() - 
									hitpoint_triangle_dist.first.second->halfedge()->next()->vertex()->point());
				CGALNorm = CGALNorm/CGAL::sqrt(CGALNorm.squared_length());
				link.WallNormalAtWallCut = Vector(CGALNorm.x(), CGALNorm.y(),CGALNorm.z());
				link.DistanceInVoxels = distanceInVoxels;
			}
		}
	}
	
	// If there's enough information available, an approximation of the wall normal will be computed for this fluid site.
	this->ComputeAveragedNormal(site);
}
예제 #7
0
    void operator()( HDS& hds) {

    	CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, false);
		//B.begin_surface( 3*trianglesList->size(), trianglesList->size(), 0, CGAL::Polyhedron_incremental_builder_3<HDS>::RELATIVE_INDEXING); //ABSOLUTE_INDEXING
		B.begin_surface( 3*trianglesList->size(), trianglesList->size()); //ABSOLUTE_INDEXING

		// Init data structures and add points to B
		int pointIndex = 0;
		int triangleIndex = 0;
		int edgeIndex = 0;
		std::list<Triangle>::iterator triangleIter;
		for(triangleIter = trianglesList->begin(); triangleIter != trianglesList->end(); ++triangleIter)
		{
			Triangle t = *triangleIter;

			if (t.is_degenerate())
			{
				continue;
			}

			TriangleVisitedInfoMS tvi;
			tvi.triangle = &(*triangleIter); //Use the pointer, it should not change into the container, since there aren't new added elements
			tvi.visited = false;

			// loop for vertexes
			for (int i = 0;  i < 3; ++i)
			{
				PointCGAL v = t.vertex(i);

				MapPointId::iterator foundPair = mapPointId.find(v);
				if (foundPair == mapPointId.end())
				{
					// PointCGAL not found
					Polyhedron::Vertex_handle vh = B.add_vertex( PointKK(CGAL::to_double(v.x()), CGAL::to_double(v.y()), CGAL::to_double(v.z())) );

					mapPointId.insert(PairPointId(v, pointIndex));
					vertexPoints.push_back(v);
					tvi.vertexIndexes.push_back(pointIndex);
					pointIndex++;
				}
				else
				{
					tvi.vertexIndexes.push_back(foundPair->second);
				}
			}

			// loop for edges
			for (int i = 0;  i < 3; ++i)
			{
				int firstEdgeIndex = i;
				int secondEdgeIndex = (i<2) ? (i+1) : 0;
				IntUnorderedPair iup;
				iup.first = tvi.vertexIndexes.at(firstEdgeIndex);
				iup.second = tvi.vertexIndexes.at(secondEdgeIndex);

				MapUnorderedPairId::iterator foundPair = mapEdgeId.find(iup);
				if (foundPair == mapEdgeId.end())
				{
					// Edge not found
					EdgeVisitedInfo evi;
					evi.edgeVertexes = iup;
					evi.visited = false;
					evi.triangleVisitedInfoIndexes.push_back(triangleIndex);

					mapEdgeId.insert(PairIntUnorderedPairId(iup, edgeIndex));
					edgesVisited.push_back(evi);

					tvi.edgeVisitedInfoIndexes.push_back(edgeIndex);
					edgeIndex++;
				}
				else
				{
					EdgeVisitedInfo *evi = &(edgesVisited.at(foundPair->second));
					evi->triangleVisitedInfoIndexes.push_back(triangleIndex);
					tvi.edgeVisitedInfoIndexes.push_back(foundPair->second);
				}

			}

			trianglesVisited.push_back(tvi);
			triangleIndex++;
		}


		// build the surface adding the triangles
		std::queue<EdgeVisitedInfo*> fifoEdgesToVisit;
		for (unsigned int edgeIdx = 0; edgeIdx < edgesVisited.size(); edgeIdx++)
		{
			EdgeVisitedInfo *evip = &edgesVisited.at(edgeIdx);
			if (!(evip->visited))
			{
				//std::cout << "START";
				fifoEdgesToVisit.push(evip);
				while(!fifoEdgesToVisit.empty())
				{
					EdgeVisitedInfo *evitv = fifoEdgesToVisit.front();
					fifoEdgesToVisit.pop();
					//if (!(evitv->visited))
					{
						//std::cout << "*";
						evitv->visited = true;
						for (unsigned int triangleVecIdx = 0; triangleVecIdx < evitv->triangleVisitedInfoIndexes.size(); triangleVecIdx++)
						{
							TriangleVisitedInfoMS *tvitv =  &trianglesVisited.at(evitv->triangleVisitedInfoIndexes.at(triangleVecIdx));
							if (!(tvitv->visited))
							{
								// check if the triangle edges have more than 2 connected triangles
								// and add the connected non visited edges to fifoEdgesToVisit
								bool oneEdgeHasMoreThanTwoTriangles = false;
								for (unsigned int edgeVecIdx = 0; edgeVecIdx < tvitv->edgeVisitedInfoIndexes.size(); edgeVecIdx++)
								{
									EdgeVisitedInfo *eviTvitv = &edgesVisited.at(tvitv->edgeVisitedInfoIndexes.at(edgeVecIdx));
									if (!(eviTvitv->visited))
									{
										fifoEdgesToVisit.push(eviTvitv);
									}

									if (eviTvitv->triangleVisitedInfoIndexes.size() > 2)
									{
										oneEdgeHasMoreThanTwoTriangles = true;
									}
								}

								if (oneEdgeHasMoreThanTwoTriangles)
								{
									//std::cout << "2";
									// Add new points and the triangle with these new vertexes
									std::vector<unsigned int> newVertexIndexes;
									for (int vIdx = 0; vIdx < tvitv->vertexIndexes.size(); vIdx++)
									{
										PointCGAL vt = vertexPoints.at(tvitv->vertexIndexes.at(vIdx));
										B.add_vertex( PointKK(CGAL::to_double(vt.x()), CGAL::to_double(vt.y()), CGAL::to_double(vt.z())) );
										vertexPoints.push_back(vt);
										newVertexIndexes.push_back(pointIndex);
										pointIndex++;
									}
									if (B.test_facet(newVertexIndexes.begin(), newVertexIndexes.end()))
									{
										B.add_facet(newVertexIndexes.begin(), newVertexIndexes.end());
									}
									else
									{
										std::cout << "Build_triangle_mesh_coherent_surface: WARNING: can't add a triangle in polyhedron (1)!!!\n";
									}
								}
								else
								{
									//add triangle tvitv to Polyhedron surface
									bool testFacetVerseA = B.test_facet(tvitv->vertexIndexes.begin(), tvitv->vertexIndexes.end());
									if (testFacetVerseA)
									{
										//std::cout << "A";
										B.add_facet(tvitv->vertexIndexes.begin(), tvitv->vertexIndexes.end());
									}
									else
									{

										bool testFacetVerseB = B.test_facet(tvitv->vertexIndexes.rbegin(), tvitv->vertexIndexes.rend());
										if (testFacetVerseB)
										{
											//std::cout << "B";
											B.add_facet(tvitv->vertexIndexes.rbegin(), tvitv->vertexIndexes.rend());
										}
										else
										{
											//std::cout << "C"; // Same block of 2
											// Add new points and the triangle with these new vertexes
											std::vector<unsigned int> newVertexIndexes;
											for (int vIdx = 0; vIdx < tvitv->vertexIndexes.size(); vIdx++)
											{
												PointCGAL vt = vertexPoints.at(tvitv->vertexIndexes.at(vIdx));
												B.add_vertex( PointKK(CGAL::to_double(vt.x()), CGAL::to_double(vt.y()), CGAL::to_double(vt.z())) );
												vertexPoints.push_back(vt);
												newVertexIndexes.push_back(pointIndex);
												pointIndex++;
											}
											if (B.test_facet(newVertexIndexes.begin(), newVertexIndexes.end()))
											{
												B.add_facet(newVertexIndexes.begin(), newVertexIndexes.end());
											}
											else
											{
												std::cout << "Build_triangle_mesh_coherent_surface: WARNING: can't add a triangle in polyhedron (2)!!!\n";
											}
										}
									}
								}

								tvitv->visited = true;
							}
						}
					}
				}
			}
		}


		if ( B.check_unconnected_vertices() )
		{
			//std::cout << "Remove_unconnected_vertices" << std::endl;
			B.remove_unconnected_vertices();
		}

		B.end_surface();
    }