static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
	BVHCallbackUserData *data = (struct BVHCallbackUserData *)userdata;
	const MLoopTri *lt = &data->sys->heat.mlooptri[index];
	const MLoop *mloop = data->sys->heat.mloop;
	float (*verts)[3] = data->sys->heat.verts;
	const float *vtri_co[3];
	float dist_test;

	vtri_co[0] = verts[mloop[lt->tri[0]].v];
	vtri_co[1] = verts[mloop[lt->tri[1]].v];
	vtri_co[2] = verts[mloop[lt->tri[2]].v];

#ifdef USE_KDOPBVH_WATERTIGHT
	if (isect_ray_tri_watertight_v3(data->start, ray->isect_precalc, UNPACK3(vtri_co), &dist_test, NULL))
#else
	UNUSED_VARS(ray);
	if (isect_ray_tri_v3(data->start, data->vec, UNPACK3(vtri_co), &dist_test, NULL))
#endif
	{
		if (dist_test < hit->dist) {
			float n[3];
			normal_tri_v3(n, UNPACK3(vtri_co));
			if (dot_v3v3(n, data->vec) < -1e-5f) {
				hit->index = index;
				hit->dist = dist_test;
			}
		}
	}
}
예제 #2
0
파일: bvhutils.c 프로젝트: kujira70/Blender
/* copy of function above */
static void mesh_looptri_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata;
	const MVert *vert = data->vert;
	const MLoopTri *lt = &data->looptri[index];
	const float *vtri_co[3] = {
	    vert[data->loop[lt->tri[0]].v].co,
	    vert[data->loop[lt->tri[1]].v].co,
	    vert[data->loop[lt->tri[2]].v].co,
	};
	float dist;

	if (data->sphere_radius == 0.0f)
		dist = bvhtree_ray_tri_intersection(ray, hit->dist, UNPACK3(vtri_co));
	else
		dist = bvhtree_sphereray_tri_intersection(ray, data->sphere_radius, hit->dist, UNPACK3(vtri_co));

	if (dist >= 0 && dist < hit->dist) {
		hit->index = index;
		hit->dist = dist;
		madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);

		normal_tri_v3(hit->no, UNPACK3(vtri_co));
	}
}
예제 #3
0
/**
 * Calculate a 3d segment from 2d window coordinates.
 * This ray_start is located at the viewpoint, ray_end is a far point.
 * ray_start and ray_end are clipped by the view near and far limits
 * so points along this line are always in view.
 * In orthographic view all resulting segments will be parallel.
 * \param ar The region (used for the window width and height).
 * \param v3d The 3d viewport (used for near and far clipping range).
 * \param mval The area relative 2d location (such as event->mval, converted into float[2]).
 * \param ray_start The world-space starting point of the segment.
 * \param ray_end The world-space end point of the segment.
 * \return success, FALSE if the segment is totally clipped.
 */
int ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
{
	RegionView3D *rv3d = ar->regiondata;
	ED_view3d_win_to_segment(ar, v3d, mval, ray_start, ray_end);

	/* clipping */
	if (rv3d->rflag & RV3D_CLIPPING) {
		/* if the ray is totally clipped,
		 * restore the original values but return FALSE
		 * caller can choose what to do */
		float tray_start[3] = {UNPACK3(ray_start)};
		float tray_end[3]   = {UNPACK3(ray_end)};
		int a;
		for (a = 0; a < 4; a++) {
			if (clip_line_plane(tray_start, tray_end, rv3d->clip[a]) == FALSE) {
				return FALSE;
			}
		}

		/* copy in clipped values */
		copy_v3_v3(ray_start, tray_start);
		copy_v3_v3(ray_end, tray_end);
	}

	return TRUE;
}
예제 #4
0
static bool bmbvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
{
	struct BMBVHTree_OverlapData *data = userdata;
	const BMBVHTree *bmtree_a = data->tree_pair[0];
	const BMBVHTree *bmtree_b = data->tree_pair[1];

	BMLoop **tri_a = bmtree_a->looptris[index_a];
	BMLoop **tri_b = bmtree_b->looptris[index_b];
	const float *tri_a_co[3] = {tri_a[0]->v->co, tri_a[1]->v->co, tri_a[2]->v->co};
	const float *tri_b_co[3] = {tri_b[0]->v->co, tri_b[1]->v->co, tri_b[2]->v->co};
	float ix_pair[2][3];
	int verts_shared = 0;

	if (bmtree_a->looptris == bmtree_b->looptris) {
		if (UNLIKELY(tri_a[0]->f == tri_b[0]->f)) {
			return false;
		}

		verts_shared = (
		        ELEM(tri_a_co[0], UNPACK3(tri_b_co)) +
		        ELEM(tri_a_co[1], UNPACK3(tri_b_co)) +
		        ELEM(tri_a_co[2], UNPACK3(tri_b_co)));

		/* if 2 points are shared, bail out */
		if (verts_shared >= 2) {
			return false;
		}
	}

	return (isect_tri_tri_epsilon_v3(UNPACK3(tri_a_co), UNPACK3(tri_b_co), ix_pair[0], ix_pair[1], data->epsilon) &&
	        /* if we share a vertex, check the intersection isn't a 'point' */
	        ((verts_shared == 0) || (len_squared_v3v3(ix_pair[0], ix_pair[1]) > data->epsilon)));
}
static void heat_laplacian_create(LaplacianSystem *sys)
{
	const MLoopTri *mlooptri = sys->heat.mlooptri, *lt;
	const MLoop *mloop = sys->heat.mloop;
	int tottri = sys->heat.tottri;
	int totvert = sys->heat.totvert;
	int a;

	/* heat specific definitions */
	sys->heat.mindist = MEM_callocN(sizeof(float) * totvert, "HeatMinDist");
	sys->heat.H = MEM_callocN(sizeof(float) * totvert, "HeatH");
	sys->heat.p = MEM_callocN(sizeof(float) * totvert, "HeatP");

	/* add verts and faces to laplacian */
	for (a = 0; a < totvert; a++)
		laplacian_add_vertex(sys, sys->heat.verts[a], 0);

	for (a = 0, lt = mlooptri; a < tottri; a++, lt++) {
		int vtri[3];
		vtri[0] = mloop[lt->tri[0]].v;
		vtri[1] = mloop[lt->tri[1]].v;
		vtri[2] = mloop[lt->tri[2]].v;
		laplacian_add_triangle(sys, UNPACK3(vtri));
	}

	/* for distance computation in set_H */
	heat_calc_vnormals(sys);

	for (a = 0; a < totvert; a++)
		heat_set_H(sys, a);
}
예제 #6
0
double BLI_quadric_evaluate(const Quadric *q, const float v_fl[3])
{
	const double v[3] = {UNPACK3(v_fl)};
	return ((q->a2 * v[0] * v[0]) + (q->ab * 2 * v[0] * v[1]) + (q->ac * 2 * v[0] * v[2]) + (q->ad * 2 * v[0]) +
	        (q->b2 * v[1] * v[1]) + (q->bc * 2 * v[1] * v[2]) + (q->bd * 2 * v[1]) +
	        (q->c2 * v[2] * v[2]) + (q->cd * 2 * v[2]) +
	        (q->d2));
}
예제 #7
0
파일: blf.c 프로젝트: RiazAhamed/NewBlender
void BLF_state_print(int fontid)
{
	FontBLF *font = blf_get(fontid);
	if (font) {
		printf("fontid %d %p\n", fontid, (void *)font);
		printf("  name:    '%s'\n", font->name);
		printf("  size:     %u\n", font->size);
		printf("  dpi:      %u\n", font->dpi);
		printf("  pos:      %.6f %.6f %.6f\n", UNPACK3(font->pos));
		printf("  aspect:   (%d) %.6f %.6f %.6f\n", (font->flags & BLF_ROTATION) != 0, UNPACK3(font->aspect));
		printf("  angle:    (%d) %.6f\n", (font->flags & BLF_ASPECT) != 0, font->angle);
		printf("  flag:     %d\n", font->flags);
	}
	else {
		printf("fontid %d (NULL)\n", fontid);
	}
	fflush(stdout);
}
/**
 * Only to check for error-cases.
 */
static void polyfill_validate_tri(unsigned int (*tris)[3], unsigned int tri_index, EdgeHash *ehash)
{
    const unsigned int *tri = tris[tri_index];
    int j_curr;

    BLI_assert(!ELEM(tri[0], tri[1], tri[2]) &&
               !ELEM(tri[1], tri[0], tri[2]) &&
               !ELEM(tri[2], tri[0], tri[1]));

    for (j_curr = 0; j_curr < 3; j_curr++) {
        struct PolyEdge *e;
        unsigned int e_v1 = tri[(j_curr    )    ];
        unsigned int e_v2 = tri[(j_curr + 1) % 3];
        e = BLI_edgehash_lookup(ehash, e_v1, e_v2);
        if (e) {
            if (e->faces[0] == tri_index) {
                BLI_assert(e->verts[0] == e_v1);
                BLI_assert(e->verts[1] == e_v2);
            }
            else if (e->faces[1] == tri_index) {
                BLI_assert(e->verts[0] == e_v2);
                BLI_assert(e->verts[1] == e_v1);
            }
            else {
                BLI_assert(0);
            }

            BLI_assert(e->faces[0] != e->faces[1]);
            BLI_assert(ELEM(e_v1, UNPACK3(tri)));
            BLI_assert(ELEM(e_v2, UNPACK3(tri)));
            BLI_assert(ELEM(e_v1, UNPACK2(e->verts)));
            BLI_assert(ELEM(e_v2, UNPACK2(e->verts)));
            BLI_assert(e_v1 != tris[e->faces[0]][e->faces_other_v[0]]);
            BLI_assert(e_v1 != tris[e->faces[1]][e->faces_other_v[1]]);
            BLI_assert(e_v2 != tris[e->faces[0]][e->faces_other_v[0]]);
            BLI_assert(e_v2 != tris[e->faces[1]][e->faces_other_v[1]]);

            BLI_assert(ELEM(tri_index, UNPACK2(e->faces)));
        }
    }
}
/**
 * This method computes the Laplacian Matrix and Differential Coordinates for all vertex in the mesh.
 * The Linear system is LV = d
 * Where L is Laplacian Matrix, V as the vertexes in Mesh, d is the differential coordinates
 * The Laplacian Matrix is computes as a
 * Lij = sum(Wij) (if i == j)
 * Lij = Wij (if i != j)
 * Wij is weight between vertex Vi and vertex Vj, we use cotangent weight
 *
 * The Differential Coordinate is computes as a
 * di = Vi * sum(Wij) - sum(Wij * Vj)
 * Where :
 * di is the Differential Coordinate i
 * sum (Wij) is the sum of all weights between vertex Vi and its vertexes neighbors (Vj)
 * sum (Wij * Vj) is the sum of the product between vertex neighbor Vj and weight Wij for all neighborhood.
 *
 * This Laplacian Matrix is described in the paper:
 * Desbrun M. et.al, Implicit fairing of irregular meshes using diffusion and curvature flow, SIGGRAPH '99, pag 317-324,
 * New York, USA
 *
 * The computation of Laplace Beltrami operator on Hybrid Triangle/Quad Meshes is described in the paper:
 * Pinzon A., Romero E., Shape Inflation With an Adapted Laplacian Operator For Hybrid Quad/Triangle Meshes,
 * Conference on Graphics Patterns and Images, SIBGRAPI, 2013
 *
 * The computation of Differential Coordinates is described in the paper:
 * Sorkine, O. Laplacian Surface Editing. Proceedings of the EUROGRAPHICS/ACM SIGGRAPH Symposium on Geometry Processing,
 * 2004. p. 179-188.
 */
static void initLaplacianMatrix(LaplacianSystem *sys)
{
	float no[3];
	float w2, w3;
	int i = 3, j, ti;
	int idv[3];

	for (ti = 0; ti < sys->total_tris; ti++) {
		const unsigned int *vidt = sys->tris[ti];
		const float *co[3];

		co[0] = sys->co[vidt[0]];
		co[1] = sys->co[vidt[1]];
		co[2] = sys->co[vidt[2]];

		normal_tri_v3(no, UNPACK3(co));
		add_v3_v3(sys->no[vidt[0]], no);
		add_v3_v3(sys->no[vidt[1]], no);
		add_v3_v3(sys->no[vidt[2]], no);

		for (j = 0; j < 3; j++) {
			const float *v1, *v2, *v3;

			idv[0] = vidt[j];
			idv[1] = vidt[(j + 1) % i];
			idv[2] = vidt[(j + 2) % i];

			v1 = sys->co[idv[0]];
			v2 = sys->co[idv[1]];
			v3 = sys->co[idv[2]];

			w2 = cotangent_tri_weight_v3(v3, v1, v2);
			w3 = cotangent_tri_weight_v3(v2, v3, v1);

			sys->delta[idv[0]][0] += v1[0] * (w2 + w3);
			sys->delta[idv[0]][1] += v1[1] * (w2 + w3);
			sys->delta[idv[0]][2] += v1[2] * (w2 + w3);

			sys->delta[idv[0]][0] -= v2[0] * w2;
			sys->delta[idv[0]][1] -= v2[1] * w2;
			sys->delta[idv[0]][2] -= v2[2] * w2;

			sys->delta[idv[0]][0] -= v3[0] * w3;
			sys->delta[idv[0]][1] -= v3[1] * w3;
			sys->delta[idv[0]][2] -= v3[2] * w3;

			nlMatrixAdd(idv[0], idv[1], -w2);
			nlMatrixAdd(idv[0], idv[2], -w3);
			nlMatrixAdd(idv[0], idv[0], w2 + w3);
		}
	}
}
예제 #10
0
파일: bvhutils.c 프로젝트: kujira70/Blender
/* copy of function above */
static void mesh_looptri_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
{
	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata;
	const MVert *vert = data->vert;
	const MLoopTri *lt = &data->looptri[index];
	const float *vtri_co[3] = {
	    vert[data->loop[lt->tri[0]].v].co,
	    vert[data->loop[lt->tri[1]].v].co,
	    vert[data->loop[lt->tri[2]].v].co,
	};
	float nearest_tmp[3], dist_sq;

	closest_on_tri_to_point_v3(nearest_tmp, co, UNPACK3(vtri_co));
	dist_sq = len_squared_v3v3(co, nearest_tmp);

	if (dist_sq < nearest->dist_sq) {
		nearest->index = index;
		nearest->dist_sq = dist_sq;
		copy_v3_v3(nearest->co, nearest_tmp);
		normal_tri_v3(nearest->no, UNPACK3(vtri_co));
	}
}
예제 #11
0
static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
	struct MeshRayCallbackData *data = userdata;
	MeshDeformBind *mdb = data->mdb;
	const MLoop *mloop = mdb->cagedm_cache.mloop;
	const MLoopTri *looptri = mdb->cagedm_cache.looptri, *lt;
	const float (*poly_nors)[3] = mdb->cagedm_cache.poly_nors;
	MeshDeformIsect *isec = data->isec;
	float no[3], co[3], end[3], uvw[3], dist;
	float *face[3];
	
	lt = &looptri[index];
	
	face[0] = mdb->cagecos[mloop[lt->tri[0]].v];
	face[1] = mdb->cagecos[mloop[lt->tri[1]].v];
	face[2] = mdb->cagecos[mloop[lt->tri[2]].v];
	
	add_v3_v3v3(end, isec->start, isec->vec);
	
	if (!meshdeform_tri_intersect(ray->origin, end, UNPACK3(face), co, uvw))
		return;

	if (poly_nors) {
		copy_v3_v3(no, poly_nors[lt->poly]);
	}
	else {
		normal_tri_v3(no, UNPACK3(face));
	}

	dist = len_v3v3(ray->origin, co) / isec->vec_length;
	if (dist < hit->dist) {
		hit->index = index;
		hit->dist = dist;
		copy_v3_v3(hit->co, co);
		
		isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f);
		isec->lambda = dist;
	}
}
예제 #12
0
void BKE_scanfill_obj_dump(ScanFillContext *sf_ctx)
{
	FILE *f = fopen("test.obj", "w");
	unsigned int i = 1;

	ScanFillVert *eve;
	ScanFillEdge *eed;

	for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next, i++) {
		fprintf(f, "v %f %f %f\n", UNPACK3(eve->co));
		eve->keyindex = i;
	}
	for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
		fprintf(f, "f %d %d\n", eed->v1->keyindex, eed->v2->keyindex);
	}
	fclose(f);
}
예제 #13
0
static void bmbvh_find_face_closest_cb(void *userdata, int index, const float co[3], BVHTreeNearest *hit)
{
	struct FaceSearchUserData *bmcb_data = userdata;
	const BMLoop **ltri = bmcb_data->looptris[index];
	const float dist_max_sq = bmcb_data->dist_max_sq;

	const float *tri_cos[3];

	bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage);

	float co_close[3];
	closest_on_tri_to_point_v3(co_close, co, UNPACK3(tri_cos));
	const float dist_sq = len_squared_v3v3(co, co_close);
	if (dist_sq < hit->dist_sq && dist_sq < dist_max_sq) {
		/* XXX, normal ignores cage */
		copy_v3_v3(hit->no, ltri[0]->f->no);
		hit->dist_sq = dist_sq;
		hit->index = index;
	}
}
static void polyedge_rotate(
    unsigned int (*tris)[3],
    struct PolyEdge *e,
    EdgeHash *ehash)
{
    unsigned int e_v1_new = tris[e->faces[0]][e->faces_other_v[0]];
    unsigned int e_v2_new = tris[e->faces[1]][e->faces_other_v[1]];

#ifndef NDEBUG
    polyfill_validate_tri(tris, e->faces[0], ehash);
    polyfill_validate_tri(tris, e->faces[1], ehash);
#endif

    BLI_assert(e_v1_new != e_v2_new);
    BLI_assert(!ELEM(e_v2_new, UNPACK3(tris[e->faces[0]])));
    BLI_assert(!ELEM(e_v1_new, UNPACK3(tris[e->faces[1]])));

    tris[e->faces[0]][(e->faces_other_v[0] + 1) % 3] = e_v2_new;
    tris[e->faces[1]][(e->faces_other_v[1] + 1) % 3] = e_v1_new;

    e->faces_other_v[0] = (e->faces_other_v[0] + 2) % 3;
    e->faces_other_v[1] = (e->faces_other_v[1] + 2) % 3;

    BLI_assert((tris[e->faces[0]][e->faces_other_v[0]] != e_v1_new) &&
               (tris[e->faces[0]][e->faces_other_v[0]] != e_v2_new));
    BLI_assert((tris[e->faces[1]][e->faces_other_v[1]] != e_v1_new) &&
               (tris[e->faces[1]][e->faces_other_v[1]] != e_v2_new));

    BLI_edgehash_remove(ehash, e->verts[0], e->verts[1], NULL);
    BLI_edgehash_insert(ehash, e_v1_new, e_v2_new, e);

    if (e_v1_new < e_v2_new) {
        e->verts[0] = e_v1_new;
        e->verts[1] = e_v2_new;
    }
    else {
        /* maintain winding info */
        e->verts[0] = e_v2_new;
        e->verts[1] = e_v1_new;

        SWAP(unsigned int, e->faces[0], e->faces[1]);
        SWAP(unsigned int, e->faces_other_v[0], e->faces_other_v[1]);
    }

    /* update adjacent data */
    {
        unsigned int e_side = 0;

        for (e_side = 0; e_side < 2; e_side++) {
            /* 't_other' which we need to swap out is always the same edge-order */
            const unsigned int t_other = (((e->faces_other_v[e_side]) + 2)) % 3;
            unsigned int t_index = e->faces[e_side];
            unsigned int t_index_other = e->faces[!e_side];
            unsigned int *tri = tris[t_index];

            struct PolyEdge *e_other;
            unsigned int e_v1 = tri[(t_other    )    ];
            unsigned int e_v2 = tri[(t_other + 1) % 3];

            e_other = BLI_edgehash_lookup(ehash, e_v1, e_v2);
            if (e_other) {
                BLI_assert(t_index != e_other->faces[0] && t_index != e_other->faces[1]);
                if (t_index_other == e_other->faces[0]) {
                    e_other->faces[0] = t_index;
                    e_other->faces_other_v[0] = (t_other + 2) % 3;
                    BLI_assert(!ELEM(tri[e_other->faces_other_v[0]], e_v1, e_v2));
                }
                else if (t_index_other == e_other->faces[1]) {
                    e_other->faces[1] = t_index;
                    e_other->faces_other_v[1] = (t_other + 2) % 3;
                    BLI_assert(!ELEM(tri[e_other->faces_other_v[1]], e_v1, e_v2));
                }
                else {
                    BLI_assert(0);
                }
            }
        }
    }

#ifndef NDEBUG
    polyfill_validate_tri(tris, e->faces[0], ehash);
    polyfill_validate_tri(tris, e->faces[1], ehash);
#endif

    BLI_assert(!ELEM(tris[e->faces[0]][e->faces_other_v[0]], UNPACK2(e->verts)));
    BLI_assert(!ELEM(tris[e->faces[1]][e->faces_other_v[1]], UNPACK2(e->verts)));
}
예제 #15
0
void Controller::ComputeViewMap()
{
	if (!_ListOfModels.size())
		return;

	DeleteViewMap(true);

	// retrieve the 3D viewpoint and transformations information
	//----------------------------------------------------------
	// Save the viewpoint context at the view level in order 
	// to be able to restore it later:

	// Restore the context of view:
	// we need to perform all these operations while the 
	// 3D context is on.
	Vec3f vp(UNPACK3(g_freestyle.viewpoint));

#if 0
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "mv" << endl;
	}
#endif
	real mv[4][4];
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			mv[i][j] = g_freestyle.mv[i][j];
#if 0
			if (G.debug & G_DEBUG_FREESTYLE) {
				cout << mv[i][j] << " ";
			}
#endif
		}
#if 0
		if (G.debug & G_DEBUG_FREESTYLE) {
			cout << endl;
		}
#endif
	}

#if 0
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\nproj" << endl;
	}
#endif
	real proj[4][4];
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			proj[i][j] = g_freestyle.proj[i][j];
#if 0
			if (G.debug & G_DEBUG_FREESTYLE) {
				cout << proj[i][j] << " ";
			}
#endif
		}
#if 0
		if (G.debug & G_DEBUG_FREESTYLE) {
			cout << endl;
		}
#endif
	}

	int viewport[4];
	for (int i = 0; i < 4; i++)
		viewport[i] = g_freestyle.viewport[i];

#if 0
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\nfocal:" << _pView->GetFocalLength() << endl << endl;
	}
#endif

	// Flag the WXEdge structure for silhouette edge detection:
	//----------------------------------------------------------

	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\n===  Detecting silhouette edges  ===" << endl;
	}
	_Chrono.start();

	edgeDetector.setViewpoint(vp);
	edgeDetector.enableOrthographicProjection(proj[3][3] != 0.0);
	edgeDetector.enableRidgesAndValleysFlag(_ComputeRidges);
	edgeDetector.enableSuggestiveContours(_ComputeSuggestive);
	edgeDetector.enableMaterialBoundaries(_ComputeMaterialBoundaries);
	edgeDetector.enableFaceSmoothness(_EnableFaceSmoothness);
	edgeDetector.setCreaseAngle(_creaseAngle);
	edgeDetector.setSphereRadius(_sphereRadius);
	edgeDetector.setSuggestiveContourKrDerivativeEpsilon(_suggestiveContourKrDerivativeEpsilon);
	edgeDetector.setRenderMonitor(_pRenderMonitor);
	edgeDetector.processShapes(*_winged_edge);

	real duration = _Chrono.stop();
	if (G.debug & G_DEBUG_FREESTYLE) {
		printf("Feature lines    : %lf\n", duration);
	}

	if (_pRenderMonitor->testBreak())
		return;

	// Builds the view map structure from the flagged WSEdge structure:
	//----------------------------------------------------------
	ViewMapBuilder vmBuilder;
	vmBuilder.setEnableQI(_EnableQI);
	vmBuilder.setViewpoint(vp);
	vmBuilder.setTransform(mv, proj, viewport, _pView->GetFocalLength(), _pView->GetAspect(), _pView->GetFovyRadian());
	vmBuilder.setFrustum(_pView->znear(), _pView->zfar());
	vmBuilder.setGrid(&_Grid);
	vmBuilder.setRenderMonitor(_pRenderMonitor);

#if 0
	// Builds a tesselated form of the silhouette for display purpose:
	//---------------------------------------------------------------
	ViewMapTesselator3D sTesselator3d;
	ViewMapTesselator2D sTesselator2d;
	sTesselator2d.setNature(_edgeTesselationNature);
	sTesselator3d.setNature(_edgeTesselationNature);
#endif

	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "\n===  Building the view map  ===" << endl;
	}
	_Chrono.start();
	// Build View Map
	_ViewMap = vmBuilder.BuildViewMap(*_winged_edge, _VisibilityAlgo, _EPSILON, _Scene3dBBox, _SceneNumFaces);
	_ViewMap->setScene3dBBox(_Scene3dBBox);

	if (G.debug & G_DEBUG_FREESTYLE) {
		printf("ViewMap edge count : %i\n", _ViewMap->viewedges_size());
	}

#if 0
	// Tesselate the 3D edges:
	_SilhouetteNode = sTesselator3d.Tesselate(_ViewMap);
	_SilhouetteNode->addRef();

	// Tesselate 2D edges
	_ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap);
	_ProjectedSilhouette->addRef();
#endif

	duration = _Chrono.stop();
	if (G.debug & G_DEBUG_FREESTYLE) {
		printf("ViewMap building : %lf\n", duration);
	}

#if 0
	_pView->AddSilhouette(_SilhouetteNode);
	_pView->AddSilhouette(_WRoot);
	_pView->Add2DSilhouette(_ProjectedSilhouette);
	_pView->Add2DVisibleSilhouette(_VisibleProjectedSilhouette);
	_pView->AddDebug(_DebugNode);
#endif

	// Draw the steerable density map:
	//--------------------------------
	if (_ComputeSteerableViewMap) {
		ComputeSteerableViewMap();
	}
	// Reset Style modules modification flags
	resetModified(true);

	DeleteWingedEdge();
}
예제 #16
0
static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
                              RulerItem **r_ruler_item, int *r_co_index)
{
	ARegion *ar = ruler_info->ar;
	RulerItem *ruler_item;

	float dist_best = RULER_PICK_DIST_SQ;
	RulerItem *ruler_item_best = NULL;
	int co_index_best = -1;

	for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) {
		float co_ss[3][2];
		float dist;
		int j;

		/* should these be checked? - ok for now not to */
		for (j = 0; j < 3; j++) {
			ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
		}

		if (ruler_item->flag & RULERITEM_USE_ANGLE) {
			dist = min_ff(dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[1]),
			              dist_squared_to_line_segment_v2(mval, co_ss[1], co_ss[2]));
			if (dist < dist_best) {
				dist_best = dist;
				ruler_item_best = ruler_item;

				{
					const float dist_points[3] = {
					    len_squared_v2v2(co_ss[0], mval),
					    len_squared_v2v2(co_ss[1], mval),
					    len_squared_v2v2(co_ss[2], mval),
					};
					if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) {
						co_index_best = min_axis_v3(dist_points);
					}
					else {
						co_index_best = -1;
					}
				}
			}
		}
		else {
			dist = dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[2]);
			if (dist < dist_best) {
				dist_best = dist;
				ruler_item_best = ruler_item;

				{
					const float dist_points[2] = {
					    len_squared_v2v2(co_ss[0], mval),
					    len_squared_v2v2(co_ss[2], mval),
					};
					if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) {
						co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2;
					}
					else {
						co_index_best = -1;
					}
				}
			}
		}
	}

	if (ruler_item_best) {
		*r_ruler_item = ruler_item_best;
		*r_co_index = co_index_best;
		return true;
	}
	else {
		*r_ruler_item = NULL;
		*r_co_index = -1;
		return false;
	}
}
예제 #17
0
/* used by node view too */
void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_default_view, int channels, int x, int y,
                        const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf)
{
	rcti color_rect;
	char str[256];
	int dx = 6;
	const int dy = 0.3f * UI_UNIT_Y;
	/* text colors */
	/* XXX colored text not allowed in Blender UI */
#if 0
	unsigned char red[3] = {255, 50, 50};
	unsigned char green[3] = {0, 255, 0};
	unsigned char blue[3] = {100, 100, 255};
#else
	unsigned char red[3] = {255, 255, 255};
	unsigned char green[3] = {255, 255, 255};
	unsigned char blue[3] = {255, 255, 255};
#endif
	float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
	float col[4], finalcol[4];

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);

	/* noisy, high contrast make impossible to read if lower alpha is used. */
	glColor4ub(0, 0, 0, 190);
	glRecti(0.0, 0.0, BLI_rcti_size_x(&ar->winrct) + 1, UI_UNIT_Y);
	glDisable(GL_BLEND);

	BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi);

	glColor3ub(255, 255, 255);
	BLI_snprintf(str, sizeof(str), "X:%-4d  Y:%-4d |", x, y);
	BLF_position(blf_mono_font, dx, dy, 0);
	BLF_draw_ascii(blf_mono_font, str, sizeof(str));
	dx += BLF_width(blf_mono_font, str, sizeof(str));

	if (zp) {
		glColor3ub(255, 255, 255);
		BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff));
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}
	if (zpf) {
		glColor3ub(255, 255, 255);
		BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}

	if (channels >= 3) {
		glColor3ubv(red);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  R:%-.5f", fp[0]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  R:%-3d", cp[0]);
		else
			BLI_snprintf(str, sizeof(str), "  R:-");
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
		
		glColor3ubv(green);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  G:%-.5f", fp[1]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  G:%-3d", cp[1]);
		else
			BLI_snprintf(str, sizeof(str), "  G:-");
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
		
		glColor3ubv(blue);
		if (fp)
			BLI_snprintf(str, sizeof(str), "  B:%-.5f", fp[2]);
		else if (cp)
			BLI_snprintf(str, sizeof(str), "  B:%-3d", cp[2]);
		else
			BLI_snprintf(str, sizeof(str), "  B:-");
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
		
		if (channels == 4) {
			glColor3ub(255, 255, 255);
			if (fp)
				BLI_snprintf(str, sizeof(str), "  A:%-.4f", fp[3]);
			else if (cp)
				BLI_snprintf(str, sizeof(str), "  A:%-3d", cp[3]);
			else
				BLI_snprintf(str, sizeof(str), "- ");
			BLF_position(blf_mono_font, dx, dy, 0);
			BLF_draw_ascii(blf_mono_font, str, sizeof(str));
			dx += BLF_width(blf_mono_font, str, sizeof(str));
		}

		if (color_manage) {
			float rgba[4];

			copy_v3_v3(rgba, linearcol);
			if (channels == 3)
				rgba[3] = 1.0f;
			else
				rgba[3] = linearcol[3];

			if (use_default_view)
				IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba,  NULL, &scene->display_settings);
			else
				IMB_colormanagement_pixel_to_display_space_v4(rgba, rgba,  &scene->view_settings, &scene->display_settings);

			BLI_snprintf(str, sizeof(str), "  |  CM  R:%-.4f  G:%-.4f  B:%-.4f", rgba[0], rgba[1], rgba[2]);
			BLF_position(blf_mono_font, dx, dy, 0);
			BLF_draw_ascii(blf_mono_font, str, sizeof(str));
			dx += BLF_width(blf_mono_font, str, sizeof(str));
		}
	}
	
	/* color rectangle */
	if (channels == 1) {
		if (fp) {
			col[0] = col[1] = col[2] = fp[0];
		}
		else if (cp) {
			col[0] = col[1] = col[2] = (float)cp[0] / 255.0f;
		}
		else {
			col[0] = col[1] = col[2] = 0.0f;
		}
		col[3] = 1.0f;
	}
	else if (channels == 3) {
		copy_v3_v3(col, linearcol);
		col[3] = 1.0f;
	}
	else if (channels == 4) {
		copy_v4_v4(col, linearcol);
	}
	else {
		BLI_assert(0);
		zero_v4(col);
	}

	if (color_manage) {
		if (use_default_view)
			IMB_colormanagement_pixel_to_display_space_v4(finalcol, col,  NULL, &scene->display_settings);
		else
			IMB_colormanagement_pixel_to_display_space_v4(finalcol, col,  &scene->view_settings, &scene->display_settings);
	}
	else {
		copy_v4_v4(finalcol, col);
	}

	glDisable(GL_BLEND);
	dx += 0.25f * UI_UNIT_X;

	BLI_rcti_init(&color_rect, dx, dx + (1.5f * UI_UNIT_X), 0.15f * UI_UNIT_Y, 0.85f * UI_UNIT_Y);

	if (channels == 4) {
		rcti color_rect_half;
		int color_quater_x, color_quater_y;

		color_rect_half = color_rect;
		color_rect_half.xmax = BLI_rcti_cent_x(&color_rect);
		glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);

		color_rect_half = color_rect;
		color_rect_half.xmin = BLI_rcti_cent_x(&color_rect);

		color_quater_x = BLI_rcti_cent_x(&color_rect_half);
		color_quater_y = BLI_rcti_cent_y(&color_rect_half);

		glColor4ub(UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, UI_ALPHA_CHECKER_DARK, 255);
		glRecti(color_rect_half.xmin, color_rect_half.ymin, color_rect_half.xmax, color_rect_half.ymax);

		glColor4ub(UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, UI_ALPHA_CHECKER_LIGHT, 255);
		glRecti(color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax);
		glRecti(color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y);

		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(UNPACK3(finalcol), fp ? fp[3] : (cp[3] / 255.0f));
		glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
		glDisable(GL_BLEND);
	}
	else {
		glColor3fv(finalcol);
		glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
	}

	/* draw outline */
	glColor3ub(128, 128, 128);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glRecti(color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	dx += 1.75f * UI_UNIT_X;

	glColor3ub(255, 255, 255);
	if (channels == 1) {
		if (fp) {
			rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val);
			rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v);
		}
		else if (cp) {
			rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &hue, &sat, &val);
			rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v);
		}
		
		BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}
	else if (channels >= 3) {
		rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val);
		rgb_to_yuv(finalcol[0], finalcol[1], finalcol[2], &lum, &u, &v);

		BLI_snprintf(str, sizeof(str), "H:%-.4f", hue);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "  S:%-.4f", sat);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "  V:%-.4f", val);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));

		BLI_snprintf(str, sizeof(str), "   L:%-.4f", lum);
		BLF_position(blf_mono_font, dx, dy, 0);
		BLF_draw_ascii(blf_mono_font, str, sizeof(str));
		dx += BLF_width(blf_mono_font, str, sizeof(str));
	}

	(void)dx;
}
static void rotateDifferentialCoordinates(LaplacianSystem *sys)
{
	float alpha, beta, gamma;
	float pj[3], ni[3], di[3];
	float uij[3], dun[3], e2[3], pi[3], fni[3], vn[3][3];
	int i, j, num_fni, k, fi;
	int *fidn;

	for (i = 0; i < sys->total_verts; i++) {
		copy_v3_v3(pi, sys->co[i]);
		copy_v3_v3(ni, sys->no[i]);
		k = sys->unit_verts[i];
		copy_v3_v3(pj, sys->co[k]);
		sub_v3_v3v3(uij, pj, pi);
		mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
		sub_v3_v3(uij, dun);
		normalize_v3(uij);
		cross_v3_v3v3(e2, ni, uij);
		copy_v3_v3(di, sys->delta[i]);
		alpha = dot_v3v3(ni, di);
		beta = dot_v3v3(uij, di);
		gamma = dot_v3v3(e2, di);

		pi[0] = nlGetVariable(0, i);
		pi[1] = nlGetVariable(1, i);
		pi[2] = nlGetVariable(2, i);
		zero_v3(ni);
		num_fni = 0;
		num_fni = sys->ringf_map[i].count;
		for (fi = 0; fi < num_fni; fi++) {
			const unsigned int *vin;
			fidn = sys->ringf_map[i].indices;
			vin = sys->tris[fidn[fi]];
			for (j = 0; j < 3; j++) {
				vn[j][0] = nlGetVariable(0, vin[j]);
				vn[j][1] = nlGetVariable(1, vin[j]);
				vn[j][2] = nlGetVariable(2, vin[j]);
				if (vin[j] == sys->unit_verts[i]) {
					copy_v3_v3(pj, vn[j]);
				}
			}

			normal_tri_v3(fni, UNPACK3(vn));
			add_v3_v3(ni, fni);
		}

		normalize_v3(ni);
		sub_v3_v3v3(uij, pj, pi);
		mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
		sub_v3_v3(uij, dun);
		normalize_v3(uij);
		cross_v3_v3v3(e2, ni, uij);
		fni[0] = alpha * ni[0] + beta * uij[0] + gamma * e2[0];
		fni[1] = alpha * ni[1] + beta * uij[1] + gamma * e2[1];
		fni[2] = alpha * ni[2] + beta * uij[2] + gamma * e2[2];

		if (len_squared_v3(fni) > FLT_EPSILON) {
			nlRightHandSideSet(0, i, fni[0]);
			nlRightHandSideSet(1, i, fni[1]);
			nlRightHandSideSet(2, i, fni[2]);
		}
		else {
			nlRightHandSideSet(0, i, sys->delta[i][0]);
			nlRightHandSideSet(1, i, sys->delta[i][1]);
			nlRightHandSideSet(2, i, sys->delta[i][2]);
		}
	}
}