Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh_boolean_convert.cc
| Show First 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | public: | ||||
| /* For each Mesh vertex in all the meshes (with concatenated indexing), | /* For each Mesh vertex in all the meshes (with concatenated indexing), | ||||
| * what is the IMesh Vert* allocated for it in the input IMesh? */ | * what is the IMesh Vert* allocated for it in the input IMesh? */ | ||||
| Array<const Vert *> mesh_to_imesh_vert; | Array<const Vert *> mesh_to_imesh_vert; | ||||
| /* Similarly for each Mesh poly. */ | /* Similarly for each Mesh poly. */ | ||||
| Array<Face *> mesh_to_imesh_face; | Array<Face *> mesh_to_imesh_face; | ||||
| /* Transformation matrix to transform a coordinate in the corresponding | /* Transformation matrix to transform a coordinate in the corresponding | ||||
| * Mesh to the local space of the first Mesh. */ | * Mesh to the local space of the first Mesh. */ | ||||
| Array<float4x4> to_target_transform; | Array<float4x4> to_target_transform; | ||||
| /* For each input mesh, whether or not their transform is negative. */ | |||||
| Array<bool> has_negative_transform; | |||||
| /* For each input mesh, how to remap the material slot numbers to | /* For each input mesh, how to remap the material slot numbers to | ||||
| * the material slots in the first mesh. */ | * the material slots in the first mesh. */ | ||||
| Span<Array<short>> material_remaps; | Span<Array<short>> material_remaps; | ||||
| /* Total number of input mesh vertices. */ | /* Total number of input mesh vertices. */ | ||||
| int tot_meshes_verts; | int tot_meshes_verts; | ||||
| /* Total number of input mesh edges. */ | /* Total number of input mesh edges. */ | ||||
| int tot_meshes_edges; | int tot_meshes_edges; | ||||
| /* Total number of input mesh polys. */ | /* Total number of input mesh polys. */ | ||||
| ▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | static IMesh meshes_to_imesh(Span<const Mesh *> meshes, | ||||
| const int estimate_num_outf = 4 * totpoly; | const int estimate_num_outf = 4 * totpoly; | ||||
| arena.reserve(estimate_num_outv, estimate_num_outf); | arena.reserve(estimate_num_outv, estimate_num_outf); | ||||
| r_info->mesh_to_imesh_vert = Array<const Vert *>(totvert); | r_info->mesh_to_imesh_vert = Array<const Vert *>(totvert); | ||||
| r_info->mesh_to_imesh_face = Array<Face *>(totpoly); | r_info->mesh_to_imesh_face = Array<Face *>(totpoly); | ||||
| r_info->mesh_vert_offset = Array<int>(nmeshes); | r_info->mesh_vert_offset = Array<int>(nmeshes); | ||||
| r_info->mesh_edge_offset = Array<int>(nmeshes); | r_info->mesh_edge_offset = Array<int>(nmeshes); | ||||
| r_info->mesh_poly_offset = Array<int>(nmeshes); | r_info->mesh_poly_offset = Array<int>(nmeshes); | ||||
| r_info->to_target_transform = Array<float4x4>(nmeshes); | r_info->to_target_transform = Array<float4x4>(nmeshes); | ||||
| r_info->has_negative_transform = Array<bool>(nmeshes); | |||||
| r_info->material_remaps = material_remaps; | r_info->material_remaps = material_remaps; | ||||
| int v = 0; | int v = 0; | ||||
| int e = 0; | int e = 0; | ||||
| int f = 0; | int f = 0; | ||||
| /* Put these Vectors here, with a size unlikely to need resizing, | /* Put these Vectors here, with a size unlikely to need resizing, | ||||
| * so that the loop to make new Faces will likely not need to allocate | * so that the loop to make new Faces will likely not need to allocate | ||||
| * over and over. */ | * over and over. */ | ||||
| Show All 16 Lines | for (int mi : meshes.index_range()) { | ||||
| r_info->mesh_vert_offset[mi] = v; | r_info->mesh_vert_offset[mi] = v; | ||||
| r_info->mesh_edge_offset[mi] = e; | r_info->mesh_edge_offset[mi] = e; | ||||
| r_info->mesh_poly_offset[mi] = f; | r_info->mesh_poly_offset[mi] = f; | ||||
| /* Get matrix that transforms a coordinate in objects[mi]'s local space | /* Get matrix that transforms a coordinate in objects[mi]'s local space | ||||
| * to the target space space. */ | * to the target space space. */ | ||||
| const float4x4 objn_mat = (obmats[mi] == nullptr) ? float4x4::identity() : | const float4x4 objn_mat = (obmats[mi] == nullptr) ? float4x4::identity() : | ||||
| clean_obmat(*obmats[mi]); | clean_obmat(*obmats[mi]); | ||||
| r_info->to_target_transform[mi] = inv_target_mat * objn_mat; | r_info->to_target_transform[mi] = inv_target_mat * objn_mat; | ||||
| r_info->has_negative_transform[mi] = objn_mat.is_negative(); | |||||
| /* All meshes 1 and up will be transformed into the local space of operand 0. | |||||
| * Historical behavior of the modifier has been to flip the faces of any meshes | |||||
| * that would have a negative transform if you do that. */ | |||||
| bool need_face_flip = r_info->has_negative_transform[mi] != r_info->has_negative_transform[0]; | |||||
| Vector<Vert *> verts(me->totvert); | Vector<Vert *> verts(me->totvert); | ||||
| Span<MVert> mverts = Span(me->mvert, me->totvert); | Span<MVert> mverts = Span(me->mvert, me->totvert); | ||||
| /* Allocate verts | /* Allocate verts | ||||
| * Skip the matrix multiplication for each point when there is no transform for a mesh, | * Skip the matrix multiplication for each point when there is no transform for a mesh, | ||||
| * for example when the first mesh is already in the target space. (Note the logic | * for example when the first mesh is already in the target space. (Note the logic | ||||
| * directly above, which uses an identity matrix with a null input transform). */ | * directly above, which uses an identity matrix with a null input transform). */ | ||||
| Show All 21 Lines | for (int mi : meshes.index_range()) { | ||||
| } | } | ||||
| for (int i : mverts.index_range()) { | for (int i : mverts.index_range()) { | ||||
| r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]); | r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]); | ||||
| ++v; | ++v; | ||||
| } | } | ||||
| for (const MPoly &poly : Span(me->mpoly, me->totpoly)) { | for (const MPoly &poly : Span(me->mpoly, me->totpoly)) { | ||||
| int flen = poly.totloop; | int flen = poly.totloop; | ||||
| face_vert.clear(); | face_vert.resize(flen); | ||||
| face_edge_orig.clear(); | face_edge_orig.resize(flen); | ||||
| const MLoop *l = &me->mloop[poly.loopstart]; | const MLoop *l = &me->mloop[poly.loopstart]; | ||||
| for (int i = 0; i < flen; ++i) { | for (int i = 0; i < flen; ++i) { | ||||
| int mverti = r_info->mesh_vert_offset[mi] + l->v; | int mverti = r_info->mesh_vert_offset[mi] + l->v; | ||||
| const Vert *fv = r_info->mesh_to_imesh_vert[mverti]; | const Vert *fv = r_info->mesh_to_imesh_vert[mverti]; | ||||
| face_vert.append(fv); | if (need_face_flip) { | ||||
| face_edge_orig.append(e + l->e); | face_vert[flen - i - 1] = fv; | ||||
| int iedge = i < flen - 1 ? flen - i - 2 : flen - 1; | |||||
| face_edge_orig[iedge] = e + l->e; | |||||
| } | |||||
| else { | |||||
| face_vert[i] = fv; | |||||
| face_edge_orig[i] = e + l->e; | |||||
| } | |||||
| ++l; | ++l; | ||||
| } | } | ||||
| r_info->mesh_to_imesh_face[f] = arena.add_face(face_vert, f, face_edge_orig); | r_info->mesh_to_imesh_face[f] = arena.add_face(face_vert, f, face_edge_orig); | ||||
| ++f; | ++f; | ||||
| } | } | ||||
| e += me->totedge; | e += me->totedge; | ||||
| } | } | ||||
| return IMesh(r_info->mesh_to_imesh_face); | return IMesh(r_info->mesh_to_imesh_face); | ||||
| ▲ Show 20 Lines • Show All 491 Lines • Show Last 20 Lines | |||||