Exemple #1
0
void OrderDownwindForDofDist(SmartPtr<DoFDistribution> dd, ConstSmartPtr<TDomain> domain,
		SmartPtr<UserData<MathVector<TDomain::dim>, TDomain::dim> > spVelocity,
		number time, int si, number threshold)
{
	static const int dim = TDomain::dim;
	const size_t num_ind = dd->num_indices();
	typedef typename std::pair<MathVector<dim>, size_t> pos_type;
	typedef typename std::vector<std::vector<size_t> > adjacency_type;

	//	get positions of indices
	typename std::vector<pos_type> vPositions;
	ExtractPositions(domain, dd, vPositions);

	// get adjacency vector of vectors
	adjacency_type vvConnections;
	dd->get_connections(vvConnections);

	// Check vector sizes match
	if (vvConnections.size() != num_ind)
		UG_THROW("OrderDownstreamForDofDist: "
				"Adjacency list of dimension " << num_ind << " expected, got "<< vvConnections.size());

	if (vPositions.size() != num_ind)
		UG_THROW("OrderDownstreamForDofDist: "
				"Position list of dimension " << num_ind << " expected, got "<< vPositions.size());

	// init helper structures
	std::vector<size_t> vNewIndex(num_ind, 0);
	std::vector<size_t> vAncestorsCount(num_ind, 0);
	std::vector<bool> vVisited(num_ind, false);

	// remove connections that are not in stream direction
	adjacency_type::iterator VertexIter;
	std::vector<size_t>::iterator AdjIter;
	std::vector<size_t> vAdjacency;

	// count how many vertex were kept / removed per adjacency vector
	size_t initialcount, kept, removed = 0;

	MathVector<TDomain::dim> vVel1, vPos1, vPos2, vDir1_2;
	size_t i;
	for (VertexIter = vvConnections.begin(), i=0; VertexIter != vvConnections.end(); VertexIter++, i++)
	{
		UG_DLOG(LIB_DISC_ORDER, 2, "Filtering vertex " << i << " adjacency vector." <<std::endl);
		initialcount = VertexIter->size();
		kept = 0;
		removed = 0;
		// get position and velocity of first trait
		vPos1 = vPositions.at(i).first;
		(*spVelocity)(vVel1, vPos1, time, si);
		if (VecLengthSq(vVel1) == 0 )
		{
			// if the velocity is zero at this trait it does not interfere with others
			// NOTE: otherwise this trait would be downwind-connected to all of it's neighbors
			// NOTE: VertexIter-> will access inner vector functions (*VertexIter) is the inner vector.
			removed = VertexIter->size();
			VertexIter->clear();
		}
		else {
			AdjIter = VertexIter->begin();
			while (AdjIter != VertexIter->end())
			{
				// get position of second trait
				vPos2 = vPositions.at(*AdjIter).first;

				// get difference vector as direction vector
				VecSubtract(vDir1_2, vPos2, vPos1);

				// compute angle between velocity and direction vector
				number anglex1_2 = VecAngle(vDir1_2, vVel1);

				// if angle is smaller then threshold continue else remove connection
				if (anglex1_2 <= threshold && i != *AdjIter)
				{
					vAncestorsCount.at(*AdjIter) += 1;
					++AdjIter;
					kept++;
				} else {
					AdjIter = VertexIter->erase(AdjIter);
					removed++;
				}
			}
		}
		UG_DLOG(LIB_DISC_ORDER, 2, "Kept: " << kept << ", removed: " << removed << " of " << initialcount
				<< " entries in adjacency matrix." << std::endl << std::endl);
	}
	// calculate downwindorder
	// Find vertexes without any ancestors and start NumeriereKnoten on them.
	size_t v,N;
	for (v=0, N=0; v < vvConnections.size(); v++)
	{
		if (vAncestorsCount[v] == 0 && !vVisited[v])
		{
			NumeriereKnoten(vvConnections, vVisited, vAncestorsCount, vNewIndex, N, v);
		}
	}

	// sanity check
	if (N < vvConnections.size()){
		size_t fails = 0;
		for (v=0; v < vvConnections.size(); v++) {
			if (!vVisited[v]) {
				UG_DLOG(LIB_DISC_ORDER, 2, v << "was not visited, has unresolved ancestors: " << vAncestorsCount[v] << std::endl);
				fails ++;
			}
		}
		UG_THROW("OrderDownwindForDist failed, " << fails << " traits unvisited." << std::endl);
	}

	//	reorder traits
	dd->permute_indices(vNewIndex);
}
Exemple #2
0
/*************
 * DESCRIPTION: -
 * INPUT:       pointer to chunk
 * OUTPUT:      -
 *************/
static void ParseNamedObject(HANDLER_DATA *data, CHUNK *mainchunk)
{
	CHUNK     chunk;
	TRIANGLE *triangle;
	TRILIST  *ph1,*ph2;
	float     angle;
	UWORD     p1, p2, p3;
	UWORD     *edges;
	int       i, h;

	ReadASCIIZ(data, data->ObjName);
	do
	{
		BeginChunk(data, &chunk);
		switch (chunk.id)
		{
			case ID_TRIANGLE:
				ParseTriObject(data, &chunk);
				break;
		}
		EndChunk(data, &chunk);
	}
	while (INCHUNK);

	if (data->TriList && (data->link->type == LINK_RENDERER))
	{
		// go through all vertices and calculate normals (only for renderer)
		for (i = 0; i < data->pointcount; i++)
		{
			data->VertNorms[i].x = data->VertNorms[i].y = data->VertNorms[i].z = 0.f;
			ph1 = data->TriList[i];
			while (ph1)
			{
				for (ph2 = ph1->next; ph2 != NULL; ph2 = ph2->next)
				{
					if (!ph1->flag || !ph2->flag)
					{
						// test angle between two triangles
						angle = VecAngle(data->TriNorms[ph1->tri], data->TriNorms[ph2->tri]);
//                if (angle < 2*PI && angle > /*cos_*/smooth_angle)
						if (angle >0 && angle < /*cos_*/data->smooth_angle)
						{
							if (!ph1->flag)
							{
								VecAdd(&data->VertNorms[i], &data->TriNorms[ph1->tri], &data->VertNorms[i]);
								ph1->flag = TRUE;
								data->TriSmooth[ph1->tri] = TRUE;
							}
							if (!ph2->flag)
							{
								VecAdd(&data->VertNorms[i], &data->TriNorms[ph2->tri], &data->VertNorms[i]);
								ph2->flag = TRUE;
								data->TriSmooth[ph2->tri] = TRUE;
							}
						}
					}
				}
				ph2 = ph1;
				ph1 = ph1->next;
				delete ph2;
			}
			VecNormalize(&data->VertNorms[i]);
		}
	}

	if (data->face)
	{
		data->link->ObjectBegin(data->rc);

		data->defaultsurface = data->link->SurfaceAdd(data->rc);
		if (!data->defaultsurface)
		{
			data->err = ERR_MEM;
			return;
		}

		data->link->SurfaceName(data->rc, data->defaultsurface, "default");
		data->link->SurfaceDiffuse(data->rc, data->defaultsurface, 0.9f, 0.9f, 0.9f);
		data->link->SurfaceAmbient(data->rc, data->defaultsurface, 0.1f, 0.1f, 0.1f);
		data->link->SurfaceRefPhong(data->rc, data->defaultsurface, 49.f);

		triangle = data->link->TriangleAdd(data->rc, data->facecount,data->defaultsurface,data->mainactor);
		if (!triangle)
		{
			data->err = ERR_MEM;
			return;
		}
		if (data->link->type == LINK_SCENARIO)
		{  // modeler needs points,edges and faces seperate
			if (data->link->TriangleAddPoints(data->rc, data->pointcount,data->points) == -1)
			{
				data->err = ERR_MEM;
				return;
			}
			edges = new UWORD[data->facecount*6];
			if (!edges)
			{
				data->err = ERR_MEM;
				return;
			}
			for (i = 0; i < data->facecount; i++)
			{
				h = i*6;
				edges[h++] = data->face[i].p1;
				edges[h++] = data->face[i].p2;
				edges[h++] = data->face[i].p2;
				edges[h++] = data->face[i].p3;
				edges[h++] = data->face[i].p3;
				edges[h++] = data->face[i].p1;
			}
			if (data->link->TriangleAddEdges(data->rc, data->facecount*3,edges) == -1)
			{
				delete edges;
				data->err = ERR_MEM;
				return;
			}
			delete edges;
		}
		for (i = 0; i < data->facecount; i++)
		{
			p1 = data->face[i].p1;
			p2 = data->face[i].p3;
			p3 = data->face[i].p2;

			if(data->replacesurface)
				data->link->TriangleSurface(data->rc, triangle, data->replacesurface);
			else
			{
				if(!data->material[i])
					data->link->TriangleSurface(data->rc, triangle, data->defaultsurface);
				else
					data->link->TriangleSurface(data->rc, triangle, data->material[i]);
			}

			if (data->link->type == LINK_SCENARIO)
			{  // modeler needs edges
				data->link->TriangleSetEdges(data->rc, triangle,i*3,i*3+1,i*3+2);
			}
			else
			{
				// raystorm renderer needs triangles and normals
				data->link->TrianglePoints(data->rc, triangle,&data->points[p1],&data->points[p2],&data->points[p3]);

				if (!VecZero(data->TriNorms[i]))
				{
					// generate smooth triangle when smooth flag is set
					if (data->TriSmooth[i])
					{
						data->link->TriangleVNorm(data->rc, triangle,
							VecZero(data->VertNorms[p1]) ? &data->TriNorms[i] : &data->VertNorms[p1],
							VecZero(data->VertNorms[p2]) ? &data->TriNorms[i] : &data->VertNorms[p2],
							VecZero(data->VertNorms[p3]) ? &data->TriNorms[i] : &data->VertNorms[p3]);
					}
				}
				if(data->mapping)
				{
					data->link->TriangleUV(data->rc, triangle,
						&data->mapping[p1], &data->mapping[p2], &data->mapping[p3]);
				}
			}

			// next triangle
			triangle = data->link->TriangleGetNext(data->rc, triangle);
		}
		data->link->ObjectEnd(data->rc);
	}

	CleanupMesh(data);
}