[Bf-blender-cvs] [cb39058f2f3] master: Fix T94633: Sculpt mode missing check for hidden active object
Commit: cb39058f2f31815279ac72fce08ead7cbc979517 Author: Joseph Eagar Date: Sun Jul 10 23:39:45 2022 -0700 Branches: master https://developer.blender.org/rBcb39058f2f31815279ac72fce08ead7cbc979517 Fix T94633: Sculpt mode missing check for hidden active object Note there is a bug in BKE_object_is_visible_in_viewport, it returns false when the object is in local mode. The transform operator poll should do a similar test. That would allow us to move the test from sculpt_brush_strok_invoke to SCULPT_mode_poll (at the moment we cannot do this due to the brush operator falling through to the translate keymap item in global view3d keymap). === M source/blender/editors/sculpt_paint/sculpt.c === diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 906c4fd35fe..ae65ca8178b 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5499,10 +5499,23 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent struct PaintStroke *stroke; int ignore_background_click; int retval; + Object *ob = CTX_data_active_object(C); + + /* Test that ob is visible; otherwise we won't be able to get evaluated data + * from the depsgraph. We do this here instead of SCULPT_mode_poll + * to avoid falling through to the translate operator in the + * global view3d keymap. + * + * Note: BKE_object_is_visible_in_viewport is not working here (it returns false + * if the object is in local view); instead, test for OB_HIDE_VIEWPORT directly. + */ + + if (ob->visibility_flag & OB_HIDE_VIEWPORT) { +return OPERATOR_CANCELLED; + } sculpt_brush_stroke_init(C, op); - Object *ob = CTX_data_active_object(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [133d398120b] master: PyAPI: add Matrix.is_identity read-only attribute
Commit: 133d398120bfa5c6fe35e93b424cc86543747ccd Author: Campbell Barton Date: Mon Jul 11 12:43:24 2022 +1000 Branches: master https://developer.blender.org/rB133d398120bfa5c6fe35e93b424cc86543747ccd PyAPI: add Matrix.is_identity read-only attribute Add a convenient way of checking if the matrix is an identity matrix. === M source/blender/python/mathutils/mathutils_Matrix.c === diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 8cd7a5c7d87..1e85ece124d 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -290,6 +290,18 @@ static PyObject *matrix__apply_to_copy(PyObject *(*matrix_func)(MatrixObject *), return NULL; } +static bool matrix_is_identity(MatrixObject *self) +{ + for (int row = 0; row < self->row_num; row++) { +for (int col = 0; col < self->col_num; col++) { + if (MATRIX_ITEM(self, row, col) != ((row != col) ? 0.0f : 1.0f)) { +return false; + } +} + } + return true; +} + /** \} */ /* */ @@ -3104,6 +3116,16 @@ static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closur return PyFloat_FromDouble(mat3_to_scale(mat)); } +PyDoc_STRVAR(Matrix_is_identity_doc, + "True if this is an identity matrix (read-only).\n\n:type: bool"); +static PyObject *Matrix_is_identity_get(MatrixObject *self, void *UNUSED(closure)) +{ + if (BaseMath_ReadCallback(self) == -1) { +return NULL; + } + return PyBool_FromLong(matrix_is_identity(self)); +} + PyDoc_STRVAR(Matrix_is_negative_doc, "True if this matrix results in a negative scale, 3x3 and 4x4 only, " "(read-only).\n\n:type: bool"); @@ -3187,6 +3209,7 @@ static PyGetSetDef Matrix_getseters[] = { NULL}, {"row", (getter)Matrix_row_get, (setter)NULL, Matrix_row_doc, NULL}, {"col", (getter)Matrix_col_get, (setter)NULL, Matrix_col_doc, NULL}, +{"is_identity", (getter)Matrix_is_identity_get, (setter)NULL, Matrix_is_identity_doc, NULL}, {"is_negative", (getter)Matrix_is_negative_get, (setter)NULL, Matrix_is_negative_doc, NULL}, {"is_orthogonal", (getter)Matrix_is_orthogonal_get, ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [d51bc8215f5] master: GPencil: Dot-dash modifier rename segment bug fix.
Commit: d51bc8215f515144ae51cc5feec01b3dbc7900c4 Author: YimingWu Date: Mon Jul 11 10:12:49 2022 +0800 Branches: master https://developer.blender.org/rBd51bc8215f515144ae51cc5feec01b3dbc7900c4 GPencil: Dot-dash modifier rename segment bug fix. This patch fixes naming and renaming issue with dot-dash modifier segment list. Before: when double clicking and exiting it would append number at the end regardless of name being changed or not. Now it works like in other areas. Authored by: Aleš Jelovčan (frogstomp) Reviewed By: YimingWu (NicksBest) Differential Revision: https://developer.blender.org/D15359 === M release/scripts/addons M source/blender/makesrna/intern/rna_gpencil_modifier.c M source/tools === diff --git a/release/scripts/addons b/release/scripts/addons index 403b95ef6ff..7ea2e74fc41 16 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 403b95ef6ff38918de966ed2a5843cfa3274a58b +Subproject commit 7ea2e74fc41b2eabdbf639b812082e73823b09d7 diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index dccf7d7a7a9..d3e1aab1ba0 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -774,7 +774,7 @@ static bool dash_segment_name_exists_fn(void *arg, const char *name) { const DashGpencilModifierData *dmd = (const DashGpencilModifierData *)arg; for (int i = 0; i < dmd->segments_len; i++) { -if (STREQ(dmd->segments[i].name, name)) { +if (STREQ(dmd->segments[i].name, name) && dmd->segments[i].name != name) { return true; } } diff --git a/source/tools b/source/tools index 01b4c0e4a17..da8bdd7244c 16 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 01b4c0e4a172819414229445c314be34527bf412 +Subproject commit da8bdd7244c7b6c2eadf4c949ff391d0cc430275 ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [d4a4691c0c3] master: Cleanup: spelling in comments
Commit: d4a4691c0c395967e7e12d2405b561d1fd0b6365 Author: Campbell Barton Date: Mon Jul 11 10:38:04 2022 +1000 Branches: master https://developer.blender.org/rBd4a4691c0c395967e7e12d2405b561d1fd0b6365 Cleanup: spelling in comments === M source/blender/blenkernel/BKE_mesh.h M source/blender/blenloader/intern/versioning_legacy.c M source/blender/draw/engines/eevee/eevee_sampling.c M source/blender/editors/screen/screen_ops.c M source/blender/editors/space_file/file_ops.c M source/blender/io/wavefront_obj/importer/obj_import_objects.hh M source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc === diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 366083fee7f..731c9872aae 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -986,7 +986,7 @@ void BKE_mesh_strip_loose_edges(struct Mesh *me); /** * If the mesh is from a very old blender version, - * convert mface->edcode to edge drawflags + * convert #MFace.edcode to edge #ME_EDGEDRAW. */ void BKE_mesh_calc_edges_legacy(struct Mesh *me, bool use_old); void BKE_mesh_calc_edges_loose(struct Mesh *mesh); diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index a3f17878f68..75cc333e4b5 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -1468,7 +1468,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) for (me = bmain->meshes.first; me; me = me->id.next) { if (!me->medge) { -BKE_mesh_calc_edges_legacy(me, true); /* true = use mface->edcode */ +BKE_mesh_calc_edges_legacy(me, true); /* true = use #MFace.edcode. */ } else { BKE_mesh_strip_loose_faces(me); diff --git a/source/blender/draw/engines/eevee/eevee_sampling.c b/source/blender/draw/engines/eevee/eevee_sampling.c index a1a3e98f34f..34d3cd74b36 100644 --- a/source/blender/draw/engines/eevee/eevee_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_sampling.c @@ -74,7 +74,8 @@ void EEVEE_sample_ellipse(int sample_ofs, BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point); - /* Decorelate AA and shadow samples. (see T68594) */ + /* Decorrelate AA and shadow samples. (see T68594) */ + ht_point[0] = fmod(ht_point[0] * 1151.0, 1.0); ht_point[1] = fmod(ht_point[1] * 1069.0, 1.0); @@ -97,7 +98,7 @@ void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]) BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point); - /* Decorelate AA and shadow samples. (see T68594) */ + /* Decorrelate AA and shadow samples. (see T68594) */ ht_point[0] = fmod(ht_point[0] * 1151.0, 1.0); ht_point[1] = fmod(ht_point[1] * 1069.0, 1.0); ht_point[2] = fmod(ht_point[2] * 1151.0, 1.0); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index c616ca2b5eb..3618b933443 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -4718,7 +4718,7 @@ static int screen_animation_step_invoke(bContext *C, wmOperator *UNUSED(op), con #endif } - /* since we follow drawflags, we can't send notifier but tag regions ourselves */ + /* Since we follow draw-flags, we can't send notifier but tag regions ourselves. */ if (depsgraph != NULL) { ED_update_for_newframe(bmain, depsgraph); } diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 62bdd583bc1..59d9a15fbab 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1793,7 +1793,7 @@ static bool file_execute(bContext *C, SpaceFile *sfile) } ED_file_change_dir(C); } - /* opening file - sends events now, so things get handled on windowqueue level */ + /* Opening file, sends events now, so things get handled on window-queue level. */ else if (sfile->op) { wmOperator *op = sfile->op; char filepath[FILE_MAX]; diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh index 76436315465..9f0079d7c53 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh @@ -26,10 +26,12 @@ struct GlobalVertices { Vector uv_vertices; Vector vertex_normals; - /* Vertex colors might not be present in the file at all, or only + /** + * Vertex colors might not be present in the file at all, or only * provided for some meshes. Store them in chunks as they are * spelled out in the file, e.g. if there are 10 vertices in sequence
[Bf-blender-cvs] [a83502f05f0] master: Cleanup: remove unused GHOST function getAnyModifiedState.
Commit: a83502f05f017fc4ad5bd910aff32fa457ad6702 Author: Campbell Barton Date: Mon Jul 11 10:38:02 2022 +1000 Branches: master https://developer.blender.org/rBa83502f05f017fc4ad5bd910aff32fa457ad6702 Cleanup: remove unused GHOST function getAnyModifiedState. Remove unused GHOST_WindowManager::getAnyModifiedState() === M intern/ghost/intern/GHOST_WindowManager.cpp M intern/ghost/intern/GHOST_WindowManager.h === diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp index 19684a44169..e8785cbdb24 100644 --- a/intern/ghost/intern/GHOST_WindowManager.cpp +++ b/intern/ghost/intern/GHOST_WindowManager.cpp @@ -162,17 +162,3 @@ GHOST_IWindow *GHOST_WindowManager::getWindowAssociatedWithOSWindow(void *osWind } return nullptr; } - -bool GHOST_WindowManager::getAnyModifiedState() -{ - bool isAnyModified = false; - std::vector::iterator iter; - - for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) { -if ((*iter)->getModifiedState()) { - isAnyModified = true; -} - } - - return isAnyModified; -} diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h index 9d20413c433..bf7a0f4ec61 100644 --- a/intern/ghost/intern/GHOST_WindowManager.h +++ b/intern/ghost/intern/GHOST_WindowManager.h @@ -109,12 +109,6 @@ class GHOST_WindowManager { */ GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow); - /** - * Return true if any windows has a modified status - * \return True if any window has unsaved changes - */ - bool getAnyModifiedState(); - protected: /** The list of windows managed */ std::vector m_windows; ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [7f4ee97b9ef] master: Revert "Fix an assert trip in boolean tickled by D11272 example."
Commit: 7f4ee97b9ef93b0c8f9fc89d47ee8535ab665327 Author: Howard Trickey Date: Sun Jul 10 18:50:11 2022 -0400 Branches: master https://developer.blender.org/rB7f4ee97b9ef93b0c8f9fc89d47ee8535ab665327 Revert "Fix an assert trip in boolean tickled by D11272 example." This reverts commit 65432901162c0dff124d55a04875050fd0f1ac22. It broke tests and I don't know why, so reverting this while figuring that out. === M source/blender/blenlib/intern/mesh_boolean.cc === diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index 464b8f4139e..700c126ca4c 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -2966,11 +2966,6 @@ static std::ostream &operator<<(std::ostream &os, const FaceMergeState &fms) * \a tris all have the same original face. * Find the 2d edge/triangle topology for these triangles, but only the ones facing in the * norm direction, and whether each edge is dissolvable or not. - * If we did the initial triangulation properly, and any Delaunay triangulations of interections - * properly, then each triangle edge should have at most one neighbor. - * However, there can be anonalies. For example, if an input face is self-intersecting, we fall - * back on the floating poing polyfill triangulation, which, after which all bets are off. - * Hence, try to be tolerant of such unexpected topology. */ static void init_face_merge_state(FaceMergeState *fms, const Vector &tris, @@ -3058,35 +3053,16 @@ static void init_face_merge_state(FaceMergeState *fms, std::cout << "me.v1 == mf.vert[i] so set edge[" << me_index << "].left_face = " << f << "\n"; } -if (me.left_face != 1) { - /* Unexpected in the normal case: this means more than one triangle shares this - * edge in the same orientation. But be tolerant of this case. By making this - * edge not dissolvable, we'll avoid future problems due to this non-manifold topology. - */ - if (dbg_level > 1) { -std::cout << "me.left_face was already occupied, so triangulation wasn't good\n"; - } - me.dissolvable = false; -} -else { - fms->edge[me_index].left_face = f; -} +BLI_assert(me.left_face == -1); +fms->edge[me_index].left_face = f; } else { if (dbg_level > 1) { std::cout << "me.v1 != mf.vert[i] so set edge[" << me_index << "].right_face = " << f << "\n"; } -if (me.right_face != -1) { - /* Unexpected, analogous to the me.left_face != -1 case above. */ - if (dbg_level > 1) { -std::cout << "me.right_face was already occupied, so triangulation wasn't good\n"; - } - me.dissolvable = false; -} -else { - fms->edge[me_index].right_face = f; -} +BLI_assert(me.right_face == -1); +fms->edge[me_index].right_face = f; } fms->face[f].edge.append(me_index); } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [65432901162] master: Fix an assert trip in boolean tickled by D11272 example.
Commit: 65432901162c0dff124d55a04875050fd0f1ac22 Author: Howard Trickey Date: Sun Jul 10 14:50:17 2022 -0400 Branches: master https://developer.blender.org/rB65432901162c0dff124d55a04875050fd0f1ac22 Fix an assert trip in boolean tickled by D11272 example. The face merging code in exact boolean made an assumption that the tesselated original face was manifold except at the boundaries. This should be true but sometimes (e.g., if the input faces have self-intersection, as happens in the example), it is not. This commit makes face merging tolerant of such a situation. It might leave some stray edges from triangulation, but it should only happen if the input is malformed. Note: the input may be malformed if there were previous booleans in the stack, since snapping the exact result to float coordinates is not guaranteed to leave the mesh without defects. === M source/blender/blenlib/intern/mesh_boolean.cc === diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index 700c126ca4c..464b8f4139e 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -2966,6 +2966,11 @@ static std::ostream &operator<<(std::ostream &os, const FaceMergeState &fms) * \a tris all have the same original face. * Find the 2d edge/triangle topology for these triangles, but only the ones facing in the * norm direction, and whether each edge is dissolvable or not. + * If we did the initial triangulation properly, and any Delaunay triangulations of interections + * properly, then each triangle edge should have at most one neighbor. + * However, there can be anonalies. For example, if an input face is self-intersecting, we fall + * back on the floating poing polyfill triangulation, which, after which all bets are off. + * Hence, try to be tolerant of such unexpected topology. */ static void init_face_merge_state(FaceMergeState *fms, const Vector &tris, @@ -3053,16 +3058,35 @@ static void init_face_merge_state(FaceMergeState *fms, std::cout << "me.v1 == mf.vert[i] so set edge[" << me_index << "].left_face = " << f << "\n"; } -BLI_assert(me.left_face == -1); -fms->edge[me_index].left_face = f; +if (me.left_face != 1) { + /* Unexpected in the normal case: this means more than one triangle shares this + * edge in the same orientation. But be tolerant of this case. By making this + * edge not dissolvable, we'll avoid future problems due to this non-manifold topology. + */ + if (dbg_level > 1) { +std::cout << "me.left_face was already occupied, so triangulation wasn't good\n"; + } + me.dissolvable = false; +} +else { + fms->edge[me_index].left_face = f; +} } else { if (dbg_level > 1) { std::cout << "me.v1 != mf.vert[i] so set edge[" << me_index << "].right_face = " << f << "\n"; } -BLI_assert(me.right_face == -1); -fms->edge[me_index].right_face = f; +if (me.right_face != -1) { + /* Unexpected, analogous to the me.left_face != -1 case above. */ + if (dbg_level > 1) { +std::cout << "me.right_face was already occupied, so triangulation wasn't good\n"; + } + me.dissolvable = false; +} +else { + fms->edge[me_index].right_face = f; +} } fms->face[f].edge.append(me_index); } ___ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
[Bf-blender-cvs] [fad857f4731] master: Fix T99532: New OBJ importer in some cases fails to import faces
Commit: fad857f47319166d3ff97029385b50059731a576 Author: Aras Pranckevicius Date: Sun Jul 10 20:09:29 2022 +0300 Branches: master https://developer.blender.org/rBfad857f47319166d3ff97029385b50059731a576 Fix T99532: New OBJ importer in some cases fails to import faces The importer code was written under incorrect assumption that vertex data (v, vn, vt commands etc.) are grouped by object, i.e. follow the o command, and that each object has its own vertex data commands. This is not the case -- all the vertex data in the whole OBJ file is "global", with no relation to any objects/groups; it's just that the faces belong to the object, and then they pull in any vertices they like. This patch fixes this incorrect assumption in the importer: - Vertex data is now properly global; no need to track some sort of "offsets" per object like it was doing before. - For each object, face definitions track the minimum & maximum vertex indices referenced by the object, and then all that vertex range is created in the final Blender object. Note: it might be (unusual, but possible) that an object does not reference a sequential range of vertices, e.g. just a single face with vertex indices 1, 10, 100 -- the resulting Blender mesh will have all the 100 vertices (some "loose" without belonging to a face). It should be possible to track the used vertices exactly (e.g. with a vector set), but I haven't done that for performance reasons. Reviewed By: Howard Trickey Differential Revision: https://developer.blender.org/D15410 === M source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc M source/blender/io/wavefront_obj/importer/obj_import_mesh.cc M source/blender/io/wavefront_obj/importer/obj_import_objects.hh M source/blender/io/wavefront_obj/tests/obj_importer_tests.cc === diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index 6eb1bbc51f3..a32fd90594d 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -22,32 +22,24 @@ using std::string; /** * Based on the properties of the given Geometry instance, create a new Geometry instance * or return the previous one. - * - * Also update index offsets which should always happen if a new Geometry instance is created. */ static Geometry *create_geometry(Geometry *const prev_geometry, const eGeometryType new_type, StringRef name, - const GlobalVertices &global_vertices, - Vector> &r_all_geometries, - VertexIndexOffset &r_offset) + Vector> &r_all_geometries) { auto new_geometry = [&]() { r_all_geometries.append(std::make_unique()); Geometry *g = r_all_geometries.last().get(); g->geom_type_ = new_type; g->geometry_name_ = name.is_empty() ? "New object" : name; -g->vertex_start_ = global_vertices.vertices.size(); -g->vertex_color_start_ = global_vertices.vertex_colors.size(); -r_offset.set_index_offset(g->vertex_start_); return g; }; if (prev_geometry && prev_geometry->geom_type_ == GEOM_MESH) { /* After the creation of a Geometry instance, at least one element has been found in the OBJ - * file that indicates that it is a mesh (basically anything but the vertex positions). */ -if (!prev_geometry->face_elements_.is_empty() || prev_geometry->has_vertex_normals_ || -!prev_geometry->edges_.is_empty()) { + * file that indicates that it is a mesh (faces or edges). */ +if (!prev_geometry->face_elements_.is_empty() || !prev_geometry->edges_.is_empty()) { return new_geometry(); } if (new_type == GEOM_MESH) { @@ -70,15 +62,11 @@ static Geometry *create_geometry(Geometry *const prev_geometry, return new_geometry(); } -static void geom_add_vertex(Geometry *geom, -const char *p, -const char *end, -GlobalVertices &r_global_vertices) +static void geom_add_vertex(const char *p, const char *end, GlobalVertices &r_global_vertices) { float3 vert; p = parse_floats(p, end, 0.0f, vert, 3); r_global_vertices.vertices.append(vert); - geom->vertex_count_++; /* OBJ extension: `xyzrgb` vertex colors, when the vertex position * is followed by 3 more RGB color components. See * http://paulbourke.net/dataformats/obj/colour.html */ @@ -88,16 +76,22 @@ static void geom_add_vertex(Geometry *geom, if (srgb.x >= 0 && srgb.y >= 0 && srgb.z >= 0) { float3 linear; srgb_to_linearrgb_v3_v3(linear, srgb); - r_
[Bf-blender-cvs] [4114ace6169] master: Fix T99536: new 3.2 OBJ importer fails with trailing space after wrapped lines
Commit: 4114ace6169282390b199ea593c93445af748903 Author: Aras Pranckevicius Date: Sun Jul 10 18:27:07 2022 +0300 Branches: master https://developer.blender.org/rB4114ace6169282390b199ea593c93445af748903 Fix T99536: new 3.2 OBJ importer fails with trailing space after wrapped lines Address the issue by re-working line continuation handling: stop trying to parse sequences like "backslash, newline" (which is the bug: it should also handle "backslash, possible whitespace, newline") during parsing. Instead, fixup line continuations after reading chunks of input file data - turn backslash and the following newline into spaces. The rest of parsing code does not have to be aware of them at all then. Makes the file attached to T99536 load correctly now. Also will extend one of the test files in subversion tests repo to contain backslashes followed by newlines. === M source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc M source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc M source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh M source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc === diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index c2aa96713b1..6eb1bbc51f3 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -427,6 +427,11 @@ void OBJParser::parse(Vector> &r_all_geometries, break; /* No more data to read. */ } +/* Take care of line continuations now (turn them into spaces); + * the rest of the parsing code does not need to worry about them anymore. */ +fixup_line_continuations(buffer.data() + buffer_offset, + buffer.data() + buffer_offset + bytes_read); + /* Ensure buffer ends in a newline. */ if (bytes_read < read_buffer_size_) { if (bytes_read == 0 || buffer[buffer_offset + bytes_read - 1] != '\n') { @@ -445,9 +450,7 @@ void OBJParser::parse(Vector> &r_all_geometries, while (last_nl > 0) { --last_nl; if (buffer[last_nl] == '\n') { -if (last_nl < 1 || buffer[last_nl - 1] != '\\') { - break; -} +break; } } if (buffer[last_nl] != '\n') { diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc index bc9006e1051..9a457167fca 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc @@ -18,14 +18,12 @@ StringRef read_next_line(StringRef &buffer) const char *start = buffer.begin(); const char *end = buffer.end(); size_t len = 0; - char prev = 0; const char *ptr = start; while (ptr < end) { char c = *ptr++; -if (c == '\n' && prev != '\\') { +if (c == '\n') { break; } -prev = c; ++len; } @@ -35,7 +33,27 @@ StringRef read_next_line(StringRef &buffer) static bool is_whitespace(char c) { - return c <= ' ' || c == '\\'; + return c <= ' '; +} + +void fixup_line_continuations(char *p, char *end) +{ + while (true) { +/* Find next backslash, if any. */ +char *backslash = std::find(p, end, '\\'); +if (backslash == end) + break; +/* Skip over possible whitespace right after it. */ +p = backslash + 1; +while (p < end && is_whitespace(*p) && *p != '\n') + ++p; +/* If then we have a newline, turn both backslash + * and the newline into regular spaces. */ +if (p < end && *p == '\n') { + *backslash = ' '; + *p = ' '; +} + } } const char *drop_whitespace(const char *p, const char *end) diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh index f6dd1a6b675..e42f5080d25 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh @@ -6,9 +6,6 @@ /* * Various text parsing utilities used by OBJ importer. - * The utilities are not directly usable by other formats, since - * they treat backslash (\) as a whitespace character (OBJ format - * allows backslashes to function as a line-continuation character). * * Many of these functions take two pointers (p, end) indicating * which part of a string to operate on, and return a possibly @@ -27,21 +24,22 @@ namespace blender::io::obj { * The returned line will not have '\n' characters at the end; * the `buffer` is modified to contain remaining text without * the input line. - * - * Note that backslash (\) characte