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; } } } }
/* 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)); } }
/** * 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; }
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); }
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)); }
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); } } }
/* 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)); } }
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; } }
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); }
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))); }
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(); }
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; } }
/* 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]); } } }