Exemple #1
0
void FixBoarderNormals( surface_points_t *sp )
{
        int     u, v;
        vec3d_t         tmp;
        for ( u = 0; u < sp->upointnum; u++ )
        {
                GetSurfacePoint( sp, u, 0, tmp );
                FixNormal( tmp, tmp );
                SetSurfacePoint( sp, u, 0, tmp );

                GetSurfacePoint( sp, u, sp->vpointnum-1, tmp );
                FixNormal( tmp, tmp );
                SetSurfacePoint( sp, u, sp->vpointnum-1, tmp );
        }

        for ( v = 0; v < sp->vpointnum; v++ )
        {
                GetSurfacePoint( sp, 0, v, tmp );
                FixNormal( tmp, tmp );
                SetSurfacePoint( sp, 0, v, tmp );

                GetSurfacePoint( sp, sp->upointnum-1, v, tmp );
                FixNormal( tmp, tmp );
                SetSurfacePoint( sp, sp->upointnum-1, v, tmp );
        }
}
void Normals::ComputeNormals(const PolygonalModel& objs, std::vector<Normals::PolygonNormalData>& polygonNormals, NormalList& vertexNormals, PolygonAdjacencyGraph& polygonAdjacency, NormalsGeneration src)
{
	polygonNormals.clear();
	vertexNormals.clear();
	if (objs.empty())
	{
		return;
	}
	std::vector<double> polygonAreas;
	const size_t approxNumPolygons = objs.front().polygons.size() * objs.size();
	polygonAreas.reserve(approxNumPolygons);
	polygonNormals.reserve(approxNumPolygons);
	const size_t approxNumVertices = approxNumPolygons * (objs.front().polygons.empty() ? 1 : objs.front().polygons.front().points.size());
	std::unordered_map<Point3D, Vector3D, HashAndComparePoint3D, HashAndComparePoint3D> vertexMap;
	vertexMap.reserve(approxNumVertices);

	std::unordered_map<LineSegment, PolygonAdjacency, HashAndCompareEdge, HashAndCompareEdge> edgeMap;
	edgeMap.reserve(2 * approxNumVertices);

	int polygonIdx = 0;
	for (auto i = objs.begin(); i != objs.end(); ++i)
	{
		for (auto j = i->polygons.begin(); j != i->polygons.end(); ++j)
		{
			const std::pair<double, HomogeneousPoint> areaAndCentroid = j->AreaAndCentroid();
			Vector3D currPolygonNormal = j->Normal();
			if (src == NORMALS_SMART)
			{
				FixNormal(*i, j - i->polygons.begin(), areaAndCentroid, currPolygonNormal);
			}

			PolygonNormalData d(LineSegment(areaAndCentroid.second, HomogeneousPoint(Point3D(areaAndCentroid.second) + currPolygonNormal)));
			polygonNormals.push_back(d);

			polygonAreas.push_back(areaAndCentroid.first);
			for (auto v = j->points.begin(); v != j->points.end(); ++v)
			{
				if ((src != NORMALS_FILE) || j->tmpNormals.empty())
				{
					if (vertexMap.find(Point3D(*v)) == vertexMap.end())
					{
						vertexMap[Point3D(*v)] = currPolygonNormal * areaAndCentroid.first;
					}
					else
					{
						vertexMap[Point3D(*v)] += currPolygonNormal * areaAndCentroid.first;
					}
				}
				else
				{
					vertexMap[Point3D(*v)] = j->tmpNormals[v - j->points.begin()];
				}

				const LineSegment currEdge(*v, (v + 1 != j->points.end()) ? *(v + 1) : j->points.front());
				if (edgeMap.find(currEdge) == edgeMap.end())
				{
					edgeMap[currEdge] = PolygonAdjacency(polygonIdx, (i - objs.begin()), (j - i->polygons.begin()), v - j->points.begin());
				}
				else
				{
					edgeMap[currEdge].polygonIdxs.push_back(polygonIdx);
				}
			}
			++polygonIdx;
		}
	}

	polygonAdjacency.clear();
	polygonAdjacency.reserve(edgeMap.size());
	for (auto e = edgeMap.begin(); e != edgeMap.end(); ++e)
	{
		polygonAdjacency.push_back(e->second);
	}

	vertexNormals.reserve(vertexMap.size());
	for (auto i = vertexMap.begin(); i != vertexMap.end(); ++i)
	{
		const Vector3D direction = i->second.Normalized();
		vertexNormals.push_back(LineSegment(HomogeneousPoint(i->first), HomogeneousPoint(i->first + direction)));
	}

	polygonIdx = 0;
	for (auto i = objs.begin(); i != objs.end(); ++i)
	{
		for (auto j = i->polygons.begin(); j != i->polygons.end(); ++j)
		{
			for (auto v = j->points.begin(); v != j->points.end(); ++v)
			{
				const Vector3D direction = vertexMap[Point3D(*v)].Normalized();
				polygonNormals[polygonIdx].VertexNormals.push_back(LineSegment(*v, HomogeneousPoint(Point3D(*v) + direction)));
			}
			++polygonIdx;
		}
	}
}