<commit_before>
#include <yafraycore/meshtypes.h>

__BEGIN_YAFRAY

void triangle_t::getSurface(surfacePoint_t &sp, const point3d_t &hit, intersectData_t &data) const
{
	sp.Ng = vector3d_t(normal).normalize();
	data.calcB0();

	int tri_index = this - &(mesh->triangles.front());
	float u = data.b0, v = data.b1, w = data.b2;
	
	if(mesh->is_smooth || mesh->normals_exported)
	{
		vector3d_t va( (na > 0) ? mesh->normals[na] : normal ), vb( (nb > 0) ? mesh->normals[nb] : normal ), vc( (nc > 0) ? mesh->normals[nc] : normal );
		sp.N = u*va + v*vb + w*vc;
		sp.N.normalize();
	}
	else sp.N = sp.Ng;
	
	if(mesh->has_orco)
	{
		sp.orcoP = u*mesh->points[pa+1] + v*mesh->points[pb+1] + w*mesh->points[pc+1];
		sp.orcoNg = ((mesh->points[pb+1]-mesh->points[pa+1])^(mesh->points[pc+1]-mesh->points[pa+1])).normalize();
		sp.hasOrco = true;
	}
	else
	{
		sp.orcoP = hit;
		sp.hasOrco = false;
		sp.orcoNg = sp.Ng;
	}
	
	if(mesh->has_uv)
	{
		std::vector<int>::const_iterator uvi = mesh->uv_offsets.begin() + 3*tri_index;
		int uvi1 = *uvi, uvi2 = *(uvi+1), uvi3 = *(uvi+2);
		std::vector<uv_t>::const_iterator it = mesh->uv_values.begin();
		//eh...u, v and w are actually the barycentric coords, not some UVs...quite annoying, i know...
		sp.U = u * it[uvi1].u + v * it[uvi2].u + w * it[uvi3].u;
		sp.V = u * it[uvi1].v + v * it[uvi2].v + w * it[uvi3].v;
		
		// calculate dPdU and dPdV
		float du1 = it[uvi1].u - it[uvi3].u;
		float du2 = it[uvi2].u - it[uvi3].u;
		float dv1 = it[uvi1].v - it[uvi3].v;
		float dv2 = it[uvi2].v - it[uvi3].v;
		float invdet, det = du1 * dv2 - dv1 * du2;
		
		if(std::fabs(det) > 1e-30f)
		{
			invdet = 1.f/det;
			vector3d_t dp1 = mesh->points[pa] - mesh->points[pc];
			vector3d_t dp2 = mesh->points[pb] - mesh->points[pc];
			sp.dPdU = (dv2 * dp1 - dv1 * dp2) * invdet;
			sp.dPdV = (du1 * dp2 - du2 * dp1) * invdet;
		}
		else
		{
			vector3d_t dp1 = mesh->points[pb] - mesh->points[pa];
			vector3d_t dp2 = mesh->points[pc] - mesh->points[pa];
			createCS((dp2 ^ dp1).normalize(), sp.dPdU, sp.dPdV);
		}
	}
	else
	{
		// implicit mapping, p1 = 0/0, p2 = 1/0, p3 = 0/1 => U = u, V = v; (arbitrary choice)
		vector3d_t dp1 = mesh->points[pa] - mesh->points[pc];
		vector3d_t dp2 = mesh->points[pb] - mesh->points[pc];
		sp.U = v + w;
		sp.V = w;
		sp.dPdU = dp2 - dp1;
		sp.dPdV = -dp2;
	}

	sp.dPdU.normalize();
	sp.dPdV.normalize();<commit_msg>- Core: Fix for a waste of cpu cycles (cherry picking from commit df<PASSWORD>cf<PASSWORD>da<PASSWORD>)<commit_after>
#include <yafraycore/meshtypes.h>

__BEGIN_YAFRAY

void triangle_t::getSurface(surfacePoint_t &sp, const point3d_t &hit, intersectData_t &data) const
{
	sp.Ng = vector3d_t(normal);
	data.calcB0();

	int tri_index = this - &(mesh->triangles.front());
	float u = data.b0, v = data.b1, w = data.b2;
	
	if(mesh->is_smooth || mesh->normals_exported)
	{
		vector3d_t va( (na > 0) ? mesh->normals[na] : normal ), vb( (nb > 0) ? mesh->normals[nb] : normal ), vc( (nc > 0) ? mesh->normals[nc] : normal );
		sp.N = u*va + v*vb + w*vc;
		sp.N.normalize();
	}
	else sp.N = sp.Ng;
	
	if(mesh->has_orco)
	{
		sp.orcoP = u*mesh->points[pa+1] + v*mesh->points[pb+1] + w*mesh->points[pc+1];
		sp.orcoNg = ((mesh->points[pb+1]-mesh->points[pa+1])^(mesh->points[pc+1]-mesh->points[pa+1])).normalize();
		sp.hasOrco = true;
	}
	else
	{
		sp.orcoP = hit;
		sp.hasOrco = false;
		sp.orcoNg = sp.Ng;
	}
	
	if(mesh->has_uv)
	{
		std::vector<int>::const_iterator uvi = mesh->uv_offsets.begin() + 3*tri_index;
		int uvi1 = *uvi, uvi2 = *(uvi+1), uvi3 = *(uvi+2);
		std::vector<uv_t>::const_iterator it = mesh->uv_values.begin();
		//eh...u, v and w are actually the barycentric coords, not some UVs...quite annoying, i know...
		sp.U = u * it[uvi1].u + v * it[uvi2].u + w * it[uvi3].u;
		sp.V = u * it[uvi1].v + v * it[uvi2].v + w * it[uvi3].v;
		
		// calculate dPdU and dPdV
		float du1 = it[uvi1].u - it[uvi3].u;
		float du2 = it[uvi2].u - it[uvi3].u;
		float dv1 = it[uvi1].v - it[uvi3].v;
		float dv2 = it[uvi2].v - it[uvi3].v;
		float invdet, det = du1 * dv2 - dv1 * du2;
		
		if(det != 0.f)
		{
			invdet = 1.f / det;
			vector3d_t dp1 = mesh->points[pa] - mesh->points[pc];
			vector3d_t dp2 = mesh->points[pb] - mesh->points[pc];
			sp.dPdU = (dv2 * dp1 - dv1 * dp2) * invdet;
			sp.dPdV = (du1 * dp2 - du2 * dp1) * invdet;
		}
		else
		{
			vector3d_t dp1 = mesh->points[pb] - mesh->points[pa];
			vector3d_t dp2 = mesh->points[pc] - mesh->points[pa];
			createCS((dp2 ^ dp1).normalize(), sp.dPdU, sp.dPdV);
		}
	}
	else
	{
		// implicit mapping, p1 = 0/0, p2 = 1/0, p3 = 0/1 => U = u, V = v; (arbitrary choice)
		vector3d_t dp1 = mesh->points[pa] - mesh->points[pc];
		vector3d_t dp2 = mesh->points[pb] - mesh->points[pc];
		sp.U = v + w;
		sp.V = w;
		sp.dPdU = dp2 - dp1;
		sp.dPdV = -dp2;
	}

	sp.dPdU.normalize();
	sp.dPdV.normalize();
{'fraction_non_alphanumeric': 0.20510691301640024, 'fraction_numerical': 0.03404608677600166, 'mean_word_length': 3.117948717948718, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7430794', 'n_tokens_mistral': 2427, 'n_tokens_neox': 2262, 'n_words': 437}