BLF: Utility to Wrap a String into Multiple Lines #118436
|
@ -737,7 +737,7 @@ ccl_device int bsdf_hair_huang_sample(const KernelGlobals kg,
|
|||
if (cos_mi3 > 0.0f) {
|
||||
const Spectrum A_tr = exp(mu_a / cos_theta(wtr) *
|
||||
-(is_circular ?
|
||||
2.0f * fabsf(cos(phi_tr - gamma_mt)) :
|
||||
2.0f * fabsf(cosf(phi_tr - gamma_mt)) :
|
||||
len(to_point(gamma_mt, b) - to_point(gamma_mtr, b))));
|
||||
|
||||
const Spectrum TR = T1 * R2 * scale2 * A_t * A_tr *
|
||||
|
|
|
@ -201,7 +201,7 @@ ccl_device void light_tree_importance(const float3 N_or_D,
|
|||
cos_min_outgoing_angle = 1.0f;
|
||||
}
|
||||
else if ((bcone.theta_o + bcone.theta_e > M_PI_F) ||
|
||||
(cos_theta_minus_theta_u > cos(bcone.theta_o + bcone.theta_e)))
|
||||
(cos_theta_minus_theta_u > cosf(bcone.theta_o + bcone.theta_e)))
|
||||
{
|
||||
/* theta' = theta - theta_o - theta_u < theta_e */
|
||||
kernel_assert(
|
||||
|
@ -231,7 +231,7 @@ ccl_device void light_tree_importance(const float3 N_or_D,
|
|||
float cos_max_outgoing_angle;
|
||||
const float cos_theta_plus_theta_u = cos_theta * cos_theta_u - sin_theta * sin_theta_u;
|
||||
if (bcone.theta_e - bcone.theta_o < 0 || cos_theta < 0 || cos_theta_u < 0 ||
|
||||
cos_theta_plus_theta_u < cos(bcone.theta_e - bcone.theta_o))
|
||||
cos_theta_plus_theta_u < cosf(bcone.theta_e - bcone.theta_o))
|
||||
{
|
||||
min_importance = 0.0f;
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ class AssetCatalogService {
|
|||
*/
|
||||
void update_catalog_path(CatalogID catalog_id, const AssetCatalogPath &new_catalog_path);
|
||||
|
||||
AssetCatalogTree *get_catalog_tree();
|
||||
AssetCatalogTree *get_catalog_tree() const;
|
||||
|
||||
/** Return true only if there are no catalogs known. */
|
||||
bool is_empty() const;
|
||||
|
@ -239,7 +239,7 @@ class AssetCatalogService {
|
|||
* Construct an in-memory catalog definition file (CDF) from the currently known catalogs.
|
||||
* This object can then be processed further before saving to disk. */
|
||||
std::unique_ptr<AssetCatalogDefinitionFile> construct_cdf_in_memory(
|
||||
const CatalogFilePath &file_path);
|
||||
const CatalogFilePath &file_path) const;
|
||||
|
||||
/**
|
||||
* Find a suitable path to write a CDF to.
|
||||
|
@ -250,7 +250,7 @@ class AssetCatalogService {
|
|||
static CatalogFilePath find_suitable_cdf_path_for_writing(
|
||||
const CatalogFilePath &blend_file_path);
|
||||
|
||||
std::unique_ptr<AssetCatalogTree> read_into_tree();
|
||||
std::unique_ptr<AssetCatalogTree> read_into_tree() const;
|
||||
|
||||
/**
|
||||
* For every catalog, ensure that its parent path also has a known catalog.
|
||||
|
@ -263,9 +263,9 @@ class AssetCatalogService {
|
|||
void tag_all_catalogs_as_unsaved_changes();
|
||||
|
||||
/* For access by subclasses, as those will not be marked as friend by #AssetCatalogCollection. */
|
||||
AssetCatalogDefinitionFile *get_catalog_definition_file();
|
||||
OwningAssetCatalogMap &get_catalogs();
|
||||
OwningAssetCatalogMap &get_deleted_catalogs();
|
||||
AssetCatalogDefinitionFile *get_catalog_definition_file() const;
|
||||
OwningAssetCatalogMap &get_catalogs() const;
|
||||
OwningAssetCatalogMap &get_deleted_catalogs() const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,16 +116,16 @@ bool AssetCatalogService::is_empty() const
|
|||
return catalog_collection_->catalogs_.is_empty();
|
||||
}
|
||||
|
||||
OwningAssetCatalogMap &AssetCatalogService::get_catalogs()
|
||||
OwningAssetCatalogMap &AssetCatalogService::get_catalogs() const
|
||||
{
|
||||
return catalog_collection_->catalogs_;
|
||||
}
|
||||
OwningAssetCatalogMap &AssetCatalogService::get_deleted_catalogs()
|
||||
OwningAssetCatalogMap &AssetCatalogService::get_deleted_catalogs() const
|
||||
{
|
||||
return catalog_collection_->deleted_catalogs_;
|
||||
}
|
||||
|
||||
AssetCatalogDefinitionFile *AssetCatalogService::get_catalog_definition_file()
|
||||
AssetCatalogDefinitionFile *AssetCatalogService::get_catalog_definition_file() const
|
||||
{
|
||||
return catalog_collection_->catalog_definition_file_.get();
|
||||
}
|
||||
|
@ -560,7 +560,7 @@ CatalogFilePath AssetCatalogService::find_suitable_cdf_path_for_writing(
|
|||
}
|
||||
|
||||
std::unique_ptr<AssetCatalogDefinitionFile> AssetCatalogService::construct_cdf_in_memory(
|
||||
const CatalogFilePath &file_path)
|
||||
const CatalogFilePath &file_path) const
|
||||
{
|
||||
auto cdf = std::make_unique<AssetCatalogDefinitionFile>();
|
||||
cdf->file_path = file_path;
|
||||
|
@ -572,12 +572,12 @@ std::unique_ptr<AssetCatalogDefinitionFile> AssetCatalogService::construct_cdf_i
|
|||
return cdf;
|
||||
}
|
||||
|
||||
AssetCatalogTree *AssetCatalogService::get_catalog_tree()
|
||||
AssetCatalogTree *AssetCatalogService::get_catalog_tree() const
|
||||
{
|
||||
return catalog_tree_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<AssetCatalogTree> AssetCatalogService::read_into_tree()
|
||||
std::unique_ptr<AssetCatalogTree> AssetCatalogService::read_into_tree() const
|
||||
{
|
||||
auto tree = std::make_unique<AssetCatalogTree>();
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace blender::asset_system {
|
|||
|
||||
AllAssetLibrary::AllAssetLibrary() : AssetLibrary(ASSET_LIBRARY_ALL) {}
|
||||
|
||||
void AllAssetLibrary::rebuild(const bool reload_catalogs)
|
||||
void AllAssetLibrary::rebuild_catalogs_from_nested(const bool reload_nested_catalogs)
|
||||
{
|
||||
/* Start with empty catalog storage. Don't do this directly in #this.catalog_service to avoid
|
||||
* race conditions. Rather build into a new service and replace the current one when done. */
|
||||
|
@ -25,7 +25,7 @@ void AllAssetLibrary::rebuild(const bool reload_catalogs)
|
|||
|
||||
AssetLibrary::foreach_loaded(
|
||||
[&](AssetLibrary &nested) {
|
||||
if (reload_catalogs) {
|
||||
if (reload_nested_catalogs) {
|
||||
nested.catalog_service->reload_catalogs();
|
||||
}
|
||||
new_catalog_service->add_from_existing(*nested.catalog_service);
|
||||
|
@ -37,7 +37,7 @@ void AllAssetLibrary::rebuild(const bool reload_catalogs)
|
|||
|
||||
void AllAssetLibrary::refresh_catalogs()
|
||||
{
|
||||
rebuild(/*reload_catalogs=*/true);
|
||||
rebuild_catalogs_from_nested(/*reload_nested_catalogs=*/true);
|
||||
}
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
|
|
@ -18,7 +18,14 @@ class AllAssetLibrary : public AssetLibrary {
|
|||
|
||||
void refresh_catalogs() override;
|
||||
|
||||
void rebuild(const bool reload_catalogs);
|
||||
/**
|
||||
* Update the available catalogs and catalog tree from the nested asset libraries. Completely
|
||||
* recreates the catalog service (invalidating pointers to the previous one).
|
||||
*
|
||||
* \param reload_nested_catalogs: Re-read catalog definitions of nested libraries from disk and
|
||||
* merge them into the in-memory representations.
|
||||
*/
|
||||
void rebuild_catalogs_from_nested(bool reload_nested_catalogs);
|
||||
};
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
|
|
@ -190,7 +190,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_current_file()
|
|||
void AssetLibraryService::rebuild_all_library()
|
||||
{
|
||||
if (all_library_) {
|
||||
all_library_->rebuild(false);
|
||||
all_library_->rebuild_catalogs_from_nested(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_all(const Main *bmain)
|
|||
all_library_ = std::make_unique<AllAssetLibrary>();
|
||||
|
||||
/* Don't reload catalogs on this initial read, they've just been loaded above. */
|
||||
all_library_->rebuild(/*reload_catalogs=*/false);
|
||||
all_library_->rebuild_catalogs_from_nested(/*reload_nested_catalogs=*/false);
|
||||
|
||||
return all_library_.get();
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class TestableAssetCatalogService : public AssetCatalogService {
|
|||
return AssetCatalogService::get_catalog_definition_file();
|
||||
}
|
||||
|
||||
OwningAssetCatalogMap &get_deleted_catalogs()
|
||||
OwningAssetCatalogMap &get_deleted_catalogs() const
|
||||
{
|
||||
return AssetCatalogService::get_deleted_catalogs();
|
||||
}
|
||||
|
|
|
@ -75,10 +75,10 @@ static float from_16dot16(FT_Fixed value)
|
|||
/** \name Glyph Cache
|
||||
* \{ */
|
||||
|
||||
static GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, const float size)
|
||||
static GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font)
|
||||
{
|
||||
for (std::unique_ptr<GlyphCacheBLF> &gc : font->cache) {
|
||||
if (gc->size == size && (gc->bold == ((font->flags & BLF_BOLD) != 0)) &&
|
||||
if (gc->size == font->size && (gc->bold == ((font->flags & BLF_BOLD) != 0)) &&
|
||||
(gc->italic == ((font->flags & BLF_ITALIC) != 0)) &&
|
||||
(gc->char_weight == font->char_weight) && (gc->char_slant == font->char_slant) &&
|
||||
(gc->char_width == font->char_width) && (gc->char_spacing == font->char_spacing))
|
||||
|
@ -130,7 +130,7 @@ GlyphCacheBLF *blf_glyph_cache_acquire(FontBLF *font)
|
|||
{
|
||||
font->glyph_cache_mutex.lock();
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_find(font, font->size);
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_find(font);
|
||||
|
||||
if (!gc) {
|
||||
gc = blf_glyph_cache_new(font);
|
||||
|
@ -1277,10 +1277,7 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static GlyphBLF *blf_glyph_ensure_ex(FontBLF *font,
|
||||
GlyphCacheBLF *gc,
|
||||
const uint charcode,
|
||||
uint8_t subpixel)
|
||||
GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, const uint charcode, uint8_t subpixel)
|
||||
{
|
||||
GlyphBLF *g = blf_glyph_cache_find_glyph(gc, charcode, subpixel);
|
||||
if (g) {
|
||||
|
@ -1306,11 +1303,6 @@ static GlyphBLF *blf_glyph_ensure_ex(FontBLF *font,
|
|||
return g;
|
||||
}
|
||||
|
||||
GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, const uint charcode)
|
||||
{
|
||||
return blf_glyph_ensure_ex(font, gc, charcode, 0);
|
||||
}
|
||||
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
GlyphBLF *blf_glyph_ensure_subpixel(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, int32_t pen_x)
|
||||
{
|
||||
|
@ -1328,7 +1320,7 @@ GlyphBLF *blf_glyph_ensure_subpixel(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *
|
|||
const uint8_t subpixel = uint8_t(pen_x & ((font->size > 16.0f) ? 32L : 48L));
|
||||
|
||||
if (g->subpixel != subpixel) {
|
||||
g = blf_glyph_ensure_ex(font, gc, g->c, subpixel);
|
||||
g = blf_glyph_ensure(font, gc, g->c, subpixel);
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
|
|
@ -182,7 +182,10 @@ void blf_glyph_cache_clear(struct FontBLF *font);
|
|||
/**
|
||||
* Create (or load from cache) a fully-rendered bitmap glyph.
|
||||
*/
|
||||
struct GlyphBLF *blf_glyph_ensure(struct FontBLF *font, struct GlyphCacheBLF *gc, uint charcode);
|
||||
struct GlyphBLF *blf_glyph_ensure(struct FontBLF *font,
|
||||
struct GlyphCacheBLF *gc,
|
||||
uint charcode,
|
||||
uint8_t subpixel = 0);
|
||||
|
||||
#ifdef BLF_SUBPIXEL_AA
|
||||
struct GlyphBLF *blf_glyph_ensure_subpixel(struct FontBLF *font,
|
||||
|
|
|
@ -25,8 +25,8 @@ struct LightProbeSample {
|
|||
*/
|
||||
LightProbeSample lightprobe_load(vec3 P, vec3 Ng, vec3 V)
|
||||
{
|
||||
/* TODO: Dependency hell */
|
||||
float noise = 0.0;
|
||||
float noise = interlieved_gradient_noise(UTIL_TEXEL, 0.0, 0.0);
|
||||
noise = fract(noise + sampling_rng_1D_get(SAMPLING_LIGHTPROBE));
|
||||
|
||||
LightProbeSample result;
|
||||
result.volume_irradiance = lightprobe_irradiance_sample(P, V, Ng);
|
||||
|
|
|
@ -2637,6 +2637,32 @@ static float widget_radius_from_rcti(const rcti *rect, const uiWidgetColors *wco
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Widget Emboss Helper
|
||||
*
|
||||
* Emboss is an (optional) shadow shown under the bottom edge of buttons. For
|
||||
* vertically-aligned stacks of buttons it should only be shown under the bottom one.
|
||||
* \{ */
|
||||
|
||||
static bool draw_emboss(const uiBut *but)
|
||||
{
|
||||
if (but->drawflag & UI_BUT_ALIGN_DOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (but->type == UI_BTYPE_TAB &&
|
||||
(BLI_rctf_size_y(&but->block->rect) > BLI_rctf_size_x(&but->block->rect)) &&
|
||||
!(but->next == nullptr || but->next->type == UI_BTYPE_SEPR))
|
||||
{
|
||||
/* Vertical tabs, emboss at end and before separators. */
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Widget Types
|
||||
* \{ */
|
||||
|
@ -3403,7 +3429,8 @@ static void ui_draw_separator(const uiWidgetColors *wcol, uiBut *but, const rcti
|
|||
|
||||
#define NUM_BUT_PADDING_FACTOR 0.425f
|
||||
|
||||
static void widget_numbut_draw(uiWidgetColors *wcol,
|
||||
static void widget_numbut_draw(const uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const float zoom,
|
||||
const uiWidgetStateInfo *state,
|
||||
|
@ -3493,12 +3520,12 @@ static void widget_numbut_draw(uiWidgetColors *wcol,
|
|||
|
||||
/* outline */
|
||||
wtb.draw_inner = false;
|
||||
wtb.draw_emboss = roundboxalign & (UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
|
||||
wtb.draw_emboss = draw_emboss(but);
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
}
|
||||
else {
|
||||
/* inner and outline */
|
||||
wtb.draw_emboss = roundboxalign & (UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
|
||||
wtb.draw_emboss = draw_emboss(but);
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
}
|
||||
|
||||
|
@ -3510,13 +3537,14 @@ static void widget_numbut_draw(uiWidgetColors *wcol,
|
|||
}
|
||||
}
|
||||
|
||||
static void widget_numbut(uiWidgetColors *wcol,
|
||||
static void widget_numbut(uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo *state,
|
||||
int roundboxalign,
|
||||
const float zoom)
|
||||
{
|
||||
widget_numbut_draw(wcol, rect, zoom, state, roundboxalign, false);
|
||||
widget_numbut_draw(but, wcol, rect, zoom, state, roundboxalign, false);
|
||||
}
|
||||
|
||||
static void widget_menubut(uiWidgetColors *wcol,
|
||||
|
@ -3567,14 +3595,14 @@ static void widget_menubut_embossn(const uiBut * /*but*/,
|
|||
/**
|
||||
* Draw number buttons still with triangles when field is not embossed
|
||||
*/
|
||||
static void widget_numbut_embossn(const uiBut * /*but*/,
|
||||
static void widget_numbut_embossn(const uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo *state,
|
||||
int roundboxalign,
|
||||
const float zoom)
|
||||
{
|
||||
widget_numbut_draw(wcol, rect, zoom, state, roundboxalign, true);
|
||||
widget_numbut_draw(but, wcol, rect, zoom, state, roundboxalign, true);
|
||||
}
|
||||
|
||||
void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
|
||||
|
@ -4414,8 +4442,7 @@ static void widget_box(uiBut *but,
|
|||
|
||||
const float rad = widget_radius_from_zoom(zoom, wcol);
|
||||
round_box_edges(&wtb, roundboxalign, rect, rad);
|
||||
|
||||
wtb.draw_emboss = roundboxalign & (UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
|
||||
wtb.draw_emboss = draw_emboss(but);
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
|
||||
copy_v3_v3_uchar(wcol->inner, old_col);
|
||||
|
@ -4451,7 +4478,8 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int /*state*/ int
|
|||
}
|
||||
#endif
|
||||
|
||||
static void widget_roundbut_exec(uiWidgetColors *wcol,
|
||||
static void widget_roundbut_exec(uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo *state,
|
||||
int roundboxalign,
|
||||
|
@ -4469,12 +4497,12 @@ static void widget_roundbut_exec(uiWidgetColors *wcol,
|
|||
|
||||
/* half rounded */
|
||||
round_box_edges(&wtb, roundboxalign, rect, rad);
|
||||
|
||||
wtb.draw_emboss = roundboxalign & (UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
|
||||
wtb.draw_emboss = draw_emboss(but);
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
}
|
||||
|
||||
static void widget_tab(uiWidgetColors *wcol,
|
||||
static void widget_tab(uiBut *but,
|
||||
uiWidgetColors *wcol,
|
||||
rcti *rect,
|
||||
const uiWidgetStateInfo *state,
|
||||
int roundboxalign,
|
||||
|
@ -4509,6 +4537,7 @@ static void widget_tab(uiWidgetColors *wcol,
|
|||
#ifdef USE_TAB_SHADED_HIGHLIGHT
|
||||
wtb.draw_outline = 0;
|
||||
#endif
|
||||
wtb.draw_emboss = draw_emboss(but);
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
|
||||
/* We are drawing on top of widget bases. Flush cache. */
|
||||
|
@ -4603,7 +4632,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
|
|||
|
||||
case UI_WTYPE_NUMBER:
|
||||
wt.wcol_theme = &btheme->tui.wcol_num;
|
||||
wt.draw = widget_numbut;
|
||||
wt.custom = widget_numbut;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_SLIDER:
|
||||
|
@ -4614,17 +4643,17 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
|
|||
|
||||
case UI_WTYPE_EXEC:
|
||||
wt.wcol_theme = &btheme->tui.wcol_tool;
|
||||
wt.draw = widget_roundbut_exec;
|
||||
wt.custom = widget_roundbut_exec;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_TOOLBAR_ITEM:
|
||||
wt.wcol_theme = &btheme->tui.wcol_toolbar_item;
|
||||
wt.draw = widget_roundbut_exec;
|
||||
wt.custom = widget_roundbut_exec;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_TAB:
|
||||
wt.wcol_theme = &btheme->tui.wcol_tab;
|
||||
wt.draw = widget_tab;
|
||||
wt.custom = widget_tab;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_TOOLTIP:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,7 +43,7 @@ static void add_huff_table(j_decompress_ptr dinfo,
|
|||
memcpy((*htblptr)->huffval, val, min_zz(sizeof((*htblptr)->huffval), val_size));
|
||||
|
||||
/* Initialize sent_table false so table will be written to JPEG file. */
|
||||
(*htblptr)->sent_table = false;
|
||||
(*htblptr)->sent_table = FALSE;
|
||||
}
|
||||
|
||||
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
|
||||
|
@ -226,7 +226,7 @@ static int Decode_JPEG(uchar *inBuffer, uchar *outBuffer, uint width, uint heigh
|
|||
dinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&dinfo);
|
||||
jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize);
|
||||
jpeg_read_header(&dinfo, true);
|
||||
jpeg_read_header(&dinfo, TRUE);
|
||||
if (dinfo.dc_huff_tbl_ptrs[0] == nullptr) {
|
||||
std_huff_tables(&dinfo);
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ static int Decode_JPEG(uchar *inBuffer, uchar *outBuffer, uint width, uint heigh
|
|||
jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize - numbytes);
|
||||
|
||||
numbytes = 0;
|
||||
jpeg_read_header(&dinfo, true);
|
||||
jpeg_read_header(&dinfo, TRUE);
|
||||
if (dinfo.dc_huff_tbl_ptrs[0] == nullptr) {
|
||||
std_huff_tables(&dinfo);
|
||||
}
|
||||
|
@ -286,21 +286,21 @@ static void Compress_JPEG(
|
|||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_colorspace(&cinfo, JCS_YCbCr);
|
||||
|
||||
jpeg_set_quality(&cinfo, quality, true);
|
||||
jpeg_set_quality(&cinfo, quality, TRUE);
|
||||
|
||||
cinfo.dc_huff_tbl_ptrs[0]->sent_table = true;
|
||||
cinfo.dc_huff_tbl_ptrs[1]->sent_table = true;
|
||||
cinfo.ac_huff_tbl_ptrs[0]->sent_table = true;
|
||||
cinfo.ac_huff_tbl_ptrs[1]->sent_table = true;
|
||||
cinfo.dc_huff_tbl_ptrs[0]->sent_table = TRUE;
|
||||
cinfo.dc_huff_tbl_ptrs[1]->sent_table = TRUE;
|
||||
cinfo.ac_huff_tbl_ptrs[0]->sent_table = TRUE;
|
||||
cinfo.ac_huff_tbl_ptrs[1]->sent_table = TRUE;
|
||||
|
||||
cinfo.comp_info[0].component_id = 0;
|
||||
cinfo.comp_info[0].v_samp_factor = 1;
|
||||
cinfo.comp_info[1].component_id = 1;
|
||||
cinfo.comp_info[2].component_id = 2;
|
||||
|
||||
cinfo.write_JFIF_header = false;
|
||||
cinfo.write_JFIF_header = FALSE;
|
||||
|
||||
jpeg_start_compress(&cinfo, false);
|
||||
jpeg_start_compress(&cinfo, FALSE);
|
||||
|
||||
int i = 0;
|
||||
marker[i++] = 'A';
|
||||
|
@ -469,7 +469,7 @@ static void jpegmemdestmgr_init_destination(j_compress_ptr cinfo)
|
|||
static boolean jpegmemdestmgr_empty_output_buffer(j_compress_ptr cinfo)
|
||||
{
|
||||
(void)cinfo; /* unused */
|
||||
return true;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo)
|
||||
|
@ -514,7 +514,7 @@ static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo)
|
|||
dinfo->src->next_input_byte = buf;
|
||||
dinfo->src->bytes_in_buffer = 2;
|
||||
|
||||
return true;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void jpegmemsrcmgr_skip_input_data(j_decompress_ptr dinfo, long skip_count)
|
||||
|
|
|
@ -904,6 +904,12 @@ const EnumPropertyItem *RNA_node_tree_interface_socket_menu_itemf(bContext * /*C
|
|||
return RNA_node_enum_definition_itemf(*data->enum_items, r_free);
|
||||
}
|
||||
|
||||
static void rna_NodeTreeInterfaceSocket_idname_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
bNodeTreeInterfaceSocket &socket = *static_cast<bNodeTreeInterfaceSocket *>(ptr->data);
|
||||
socket.set_socket_type(value);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_node_interface_item(BlenderRNA *brna)
|
||||
|
@ -1057,6 +1063,8 @@ static void rna_def_node_interface_socket(BlenderRNA *brna)
|
|||
RNA_def_property_string_sdna(prop, nullptr, "socket_type");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER);
|
||||
RNA_def_property_ui_text(prop, "Socket Type Name", "Name of the socket type");
|
||||
RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocket_idname_set");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceItem_update");
|
||||
|
||||
func = RNA_def_function(srna, "draw", nullptr);
|
||||
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
|
||||
|
|
|
@ -6,8 +6,18 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "NOD_rna_define.hh"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
#include "UI_resources.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_remove_attribute_cc {
|
||||
|
||||
enum class PatternMode {
|
||||
Exact,
|
||||
Wildcard,
|
||||
};
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Geometry>("Geometry");
|
||||
|
@ -15,22 +25,44 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
b.add_output<decl::Geometry>("Geometry").propagate_all();
|
||||
}
|
||||
|
||||
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "pattern_mode", UI_ITEM_NONE, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
|
||||
const std::string name = params.extract_input<std::string>("Name");
|
||||
if (name.empty()) {
|
||||
const std::string pattern = params.extract_input<std::string>("Name");
|
||||
if (pattern.empty()) {
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
return;
|
||||
}
|
||||
if (!bke::allow_procedural_attribute_access(name)) {
|
||||
params.error_message_add(NodeWarningType::Info, TIP_(bke::no_procedural_access_message));
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
return;
|
||||
const bNode &node = params.node();
|
||||
PatternMode pattern_mode = PatternMode(node.custom1);
|
||||
if (pattern_mode == PatternMode::Wildcard) {
|
||||
const int wildcard_count = Span(pattern.c_str(), pattern.size()).count('*');
|
||||
if (wildcard_count == 0) {
|
||||
pattern_mode = PatternMode::Exact;
|
||||
}
|
||||
else if (wildcard_count >= 2) {
|
||||
params.error_message_add(NodeWarningType::Info,
|
||||
TIP_("Only one * is supported in the pattern"));
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::atomic<bool> attribute_exists = false;
|
||||
std::atomic<bool> cannot_delete = false;
|
||||
StringRef wildcard_prefix;
|
||||
StringRef wildcard_suffix;
|
||||
if (pattern_mode == PatternMode::Wildcard) {
|
||||
const int wildcard_index = pattern.find('*');
|
||||
wildcard_prefix = StringRef(pattern).substr(0, wildcard_index);
|
||||
wildcard_suffix = StringRef(pattern).substr(wildcard_index + 1);
|
||||
}
|
||||
|
||||
Set<std::string> removed_attributes;
|
||||
Set<std::string> failed_attributes;
|
||||
|
||||
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
|
||||
for (const GeometryComponent::Type type : {GeometryComponent::Type::Mesh,
|
||||
|
@ -38,42 +70,103 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
GeometryComponent::Type::Curve,
|
||||
GeometryComponent::Type::Instance})
|
||||
{
|
||||
if (geometry_set.has(type)) {
|
||||
/* First check if the attribute exists before getting write access,
|
||||
* to avoid potentially expensive unnecessary copies. */
|
||||
const GeometryComponent &read_only_component = *geometry_set.get_component(type);
|
||||
if (read_only_component.attributes()->contains(name)) {
|
||||
attribute_exists = true;
|
||||
if (!geometry_set.has(type)) {
|
||||
continue;
|
||||
}
|
||||
/* First check if the attribute exists before getting write access,
|
||||
* to avoid potentially expensive unnecessary copies. */
|
||||
const GeometryComponent &read_only_component = *geometry_set.get_component(type);
|
||||
Vector<std::string> attributes_to_remove;
|
||||
switch (pattern_mode) {
|
||||
case PatternMode::Exact: {
|
||||
if (read_only_component.attributes()->contains(pattern)) {
|
||||
attributes_to_remove.append(pattern);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
case PatternMode::Wildcard: {
|
||||
read_only_component.attributes()->for_all(
|
||||
[&](const blender::bke::AttributeIDRef &id,
|
||||
const blender::bke::AttributeMetaData /*meta_data*/) {
|
||||
if (id.is_anonymous()) {
|
||||
return true;
|
||||
}
|
||||
const StringRef attribute_name = id.name();
|
||||
if (attribute_name.startswith(wildcard_prefix) &&
|
||||
attribute_name.endswith(wildcard_suffix))
|
||||
{
|
||||
attributes_to_remove.append(attribute_name);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attributes_to_remove.is_empty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
GeometryComponent &component = geometry_set.get_component_for_write(type);
|
||||
for (const StringRef attribute_name : attributes_to_remove) {
|
||||
if (!bke::allow_procedural_attribute_access(attribute_name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GeometryComponent &component = geometry_set.get_component_for_write(type);
|
||||
if (!component.attributes_for_write()->remove(name)) {
|
||||
cannot_delete = true;
|
||||
if (component.attributes_for_write()->remove(attribute_name)) {
|
||||
removed_attributes.add(attribute_name);
|
||||
}
|
||||
else {
|
||||
failed_attributes.add(attribute_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (attribute_exists && !cannot_delete) {
|
||||
params.used_named_attribute(name, NamedAttributeUsage::Remove);
|
||||
for (const StringRef attribute_name : removed_attributes) {
|
||||
params.used_named_attribute(attribute_name, NamedAttributeUsage::Remove);
|
||||
}
|
||||
|
||||
if (!attribute_exists) {
|
||||
const std::string message = fmt::format(TIP_("Attribute does not exist: \"{}\""), name);
|
||||
if (!failed_attributes.is_empty()) {
|
||||
Vector<std::string> quoted_attribute_names;
|
||||
for (const StringRef attribute_name : failed_attributes) {
|
||||
quoted_attribute_names.append(fmt::format("\"{}\"", attribute_name));
|
||||
}
|
||||
const std::string message = fmt::format(TIP_("Cannot remove built-in attributes: {}"),
|
||||
fmt::join(quoted_attribute_names, ", "));
|
||||
params.error_message_add(NodeWarningType::Warning, message);
|
||||
}
|
||||
if (cannot_delete) {
|
||||
const std::string message = fmt::format(TIP_("Cannot delete built-in attribute: \"{}\""),
|
||||
name);
|
||||
else if (removed_attributes.is_empty() && pattern_mode == PatternMode::Exact) {
|
||||
const std::string message = fmt::format(TIP_("Attribute does not exist: \"{}\""), pattern);
|
||||
params.error_message_add(NodeWarningType::Warning, message);
|
||||
}
|
||||
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
}
|
||||
|
||||
static void node_rna(StructRNA *srna)
|
||||
{
|
||||
static const EnumPropertyItem pattern_mode_items[] = {
|
||||
{int(PatternMode::Exact),
|
||||
"EXACT",
|
||||
0,
|
||||
"Exact",
|
||||
"Remove the one attribute with the given name"},
|
||||
{int(PatternMode::Wildcard),
|
||||
"WILDCARD",
|
||||
0,
|
||||
"Wildcard",
|
||||
"Remove all attributes that match the pattern which is allowed to contain a single "
|
||||
"wildcard (*)."},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
RNA_def_node_enum(srna,
|
||||
"pattern_mode",
|
||||
"Pattern Mode",
|
||||
"How the attributes to remove are chosen",
|
||||
pattern_mode_items,
|
||||
NOD_inline_enum_accessors(custom1));
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
@ -81,9 +174,12 @@ static void node_register()
|
|||
geo_node_type_base(
|
||||
&ntype, GEO_NODE_REMOVE_ATTRIBUTE, "Remove Named Attribute", NODE_CLASS_ATTRIBUTE);
|
||||
ntype.declare = node_declare;
|
||||
ntype.draw_buttons = node_layout;
|
||||
bke::node_type_size(&ntype, 170, 100, 700);
|
||||
ntype.geometry_node_execute = node_geo_exec;
|
||||
nodeRegisterType(&ntype);
|
||||
|
||||
node_rna(ntype.rna_ext.srna);
|
||||
}
|
||||
NOD_REGISTER_NODE(node_register)
|
||||
|
||||
|
|
Loading…
Reference in New Issue