diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-02-07 16:44:59 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-02-08 17:37:44 +0300 |
commit | e0597baed57fa7a9dfaf6dff6d0fa120784d21ea (patch) | |
tree | ee9976051369ac5ae1c2e65e4cb9fa5392d17243 /source/blender/modifiers/intern/MOD_boolean_util.c | |
parent | 9dc7dca3a22502f79131728a6d4441ea1851595c (diff) |
Remove Carve boolean
We've got quite comprehensive BMesh based implementation, which is way easier
for maintenance than abandoned Carve library.
After all the time BMesh implementation was working on the same level of
limitations about manifold meshes and touching edges than Carve. Is better
to focus on maintaining one boolean implementation now.
Reviewers: campbellbarton
Reviewed By: campbellbarton
Differential Revision: https://developer.blender.org/D3050
Diffstat (limited to 'source/blender/modifiers/intern/MOD_boolean_util.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_boolean_util.c | 790 |
1 files changed, 0 insertions, 790 deletions
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c deleted file mode 100644 index 49010664aa8..00000000000 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ /dev/null @@ -1,790 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) Blender Foundation - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/modifiers/intern/MOD_boolean_util.c - * \ingroup modifiers - */ - -#include "MEM_guardedalloc.h" - -#include "DNA_material_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" - -#include "BLI_utildefines.h" -#include "BLI_alloca.h" -#include "BLI_ghash.h" -#include "BLI_math.h" - -#include "BKE_cdderivedmesh.h" -#include "BKE_material.h" - -#include "MOD_boolean_util.h" - -#include "carve-capi.h" - -/* Adopted from BM_loop_interp_from_face(), - * - * Transform matrix is used in cases when target coordinate needs - * to be converted to source space (namely when interpolating - * boolean result loops from second operand). - * - * TODO(sergey): Consider making it a generic function in DerivedMesh.c. - */ -static void DM_loop_interp_from_poly(DerivedMesh *source_dm, - MVert *source_mverts, - MLoop *source_mloops, - MPoly *source_poly, - DerivedMesh *target_dm, - MVert *target_mverts, - MLoop *target_mloop, - float transform[4][4], - int target_loop_index) -{ - float (*cos_3d)[3] = BLI_array_alloca(cos_3d, source_poly->totloop); - int *source_indices = BLI_array_alloca(source_indices, source_poly->totloop); - float *weights = BLI_array_alloca(weights, source_poly->totloop); - int i; - int target_vert_index = target_mloop[target_loop_index].v; - float coord[3]; - - for (i = 0; i < source_poly->totloop; ++i) { - MLoop *mloop = &source_mloops[source_poly->loopstart + i]; - source_indices[i] = source_poly->loopstart + i; - copy_v3_v3(cos_3d[i], source_mverts[mloop->v].co); - } - - if (transform) { - mul_v3_m4v3(coord, transform, target_mverts[target_vert_index].co); - } - else { - copy_v3_v3(coord, target_mverts[target_vert_index].co); - } - - interp_weights_poly_v3(weights, cos_3d, source_poly->totloop, coord); - - DM_interp_loop_data(source_dm, target_dm, source_indices, weights, - source_poly->totloop, target_loop_index); -} - -typedef struct DMArrays { - MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; - bool mvert_allocated; - bool medge_allocated; - bool mloop_allocated; - bool mpoly_allocated; -} DMArrays; - -static void dm_arrays_get(DerivedMesh *dm, DMArrays *arrays) -{ - arrays->mvert = DM_get_vert_array(dm, &arrays->mvert_allocated); - arrays->medge = DM_get_edge_array(dm, &arrays->medge_allocated); - arrays->mloop = DM_get_loop_array(dm, &arrays->mloop_allocated); - arrays->mpoly = DM_get_poly_array(dm, &arrays->mpoly_allocated); -} - -static void dm_arrays_free(DMArrays *arrays) -{ - if (arrays->mvert_allocated) { - MEM_freeN(arrays->mvert); - } - if (arrays->medge_allocated) { - MEM_freeN(arrays->medge); - } - if (arrays->mloop_allocated) { - MEM_freeN(arrays->mloop); - } - if (arrays->mpoly_allocated) { - MEM_freeN(arrays->mpoly); - } -} - -/* **** Importer from derived mesh to Carve **** */ - -typedef struct ImportMeshData { - DerivedMesh *dm; - float obmat[4][4]; - MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; -} ImportMeshData; - -/* Get number of vertices. */ -static int importer_GetNumVerts(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumVerts(dm); -} - -/* Get number of edges. */ -static int importer_GetNumEdges(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumEdges(dm); -} - -/* Get number of loops. */ -static int importer_GetNumLoops(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumLoops(dm); -} - -/* Get number of polys. */ -static int importer_GetNumPolys(ImportMeshData *import_data) -{ - DerivedMesh *dm = import_data->dm; - return dm->getNumPolys(dm); -} - -/* Get 3D coordinate of vertex with given index. */ -static void importer_GetVertCoord(ImportMeshData *import_data, int vert_index, float coord[3]) -{ - MVert *mvert = import_data->mvert; - - BLI_assert(vert_index >= 0 && vert_index < import_data->dm->getNumVerts(import_data->dm)); - - mul_v3_m4v3(coord, import_data->obmat, mvert[vert_index].co); -} - -/* Get index of vertices which are adjucent to edge specified by it's index. */ -static void importer_GetEdgeVerts(ImportMeshData *import_data, int edge_index, int *v1, int *v2) -{ - MEdge *medge = &import_data->medge[edge_index]; - - BLI_assert(edge_index >= 0 && edge_index < import_data->dm->getNumEdges(import_data->dm)); - - *v1 = medge->v1; - *v2 = medge->v2; -} - -/* Get number of adjucent vertices to the poly specified by it's index. */ -static int importer_GetPolyNumVerts(ImportMeshData *import_data, int poly_index) -{ - MPoly *mpoly = import_data->mpoly; - - BLI_assert(poly_index >= 0 && poly_index < import_data->dm->getNumPolys(import_data->dm)); - - return mpoly[poly_index].totloop; -} - -/* Get list of adjucent vertices to the poly specified by it's index. */ -static void importer_GetPolyVerts(ImportMeshData *import_data, int poly_index, int *verts) -{ - MPoly *mpoly = &import_data->mpoly[poly_index]; - MLoop *mloop = import_data->mloop + mpoly->loopstart; - int i; - BLI_assert(poly_index >= 0 && poly_index < import_data->dm->getNumPolys(import_data->dm)); - for (i = 0; i < mpoly->totloop; i++, mloop++) { - verts[i] = mloop->v; - } -} - -// Triangulate 2D polygon. -#if 0 -static int importer_triangulate2DPoly(ImportMeshData *UNUSED(import_data), - const float (*vertices)[2], int num_vertices, - unsigned int (*triangles)[3]) -{ - // TODO(sergey): Currently import_data is unused but in the future we could - // put memory arena there which will reduce amount of allocations happening - // over the triangulation period. - // - // However that's not so much straighforward to do it right now because we - // also are tu consider threaded import/export. - - BLI_assert(num_vertices > 3); - - BLI_polyfill_calc(vertices, num_vertices, triangles); - - return num_vertices - 2; -} -#endif - -static CarveMeshImporter MeshImporter = { - importer_GetNumVerts, - importer_GetNumEdges, - importer_GetNumLoops, - importer_GetNumPolys, - importer_GetVertCoord, - importer_GetEdgeVerts, - importer_GetPolyNumVerts, - importer_GetPolyVerts, - - /* TODO(sergey): We don't use BLI_polyfill_calc() because it tends - * to generate degenerated geometry which is fatal for booleans. - * - * For now we stick to Carve's triangulation. - */ - NULL, /* importer_triangulate2DPoly */ -}; - -/* **** Exporter from Carve to derived mesh **** */ - -typedef struct ExportMeshData { - DerivedMesh *dm; - float obimat[4][4]; - MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; - int *vert_origindex; - int *edge_origindex; - int *poly_origindex; - int *loop_origindex; - - /* Objects and derived meshes of left and right operands. - * Used for custom data merge and interpolation. - */ - Object *ob_left; - Object *ob_right; - DerivedMesh *dm_left; - DerivedMesh *dm_right; - MVert *mvert_left; - MEdge *medge_left; - MLoop *mloop_left; - MPoly *mpoly_left; - MVert *mvert_right; - MEdge *medge_right; - MLoop *mloop_right; - MPoly *mpoly_right; - - float left_to_right_mat[4][4]; - - /* Hash to map materials from right object to result. */ - GHash *material_hash; -} ExportMeshData; - -BLI_INLINE Object *which_object(ExportMeshData *export_data, int which_mesh) -{ - Object *object = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - object = export_data->ob_left; - break; - case CARVE_MESH_RIGHT: - object = export_data->ob_right; - break; - } - return object; -} - -BLI_INLINE DerivedMesh *which_dm(ExportMeshData *export_data, int which_mesh) -{ - DerivedMesh *dm = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - dm = export_data->dm_left; - break; - case CARVE_MESH_RIGHT: - dm = export_data->dm_right; - break; - } - return dm; -} - -BLI_INLINE MVert *which_mvert(ExportMeshData *export_data, int which_mesh) -{ - MVert *mvert = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - mvert = export_data->mvert_left; - break; - case CARVE_MESH_RIGHT: - mvert = export_data->mvert_right; - break; - } - return mvert; -} - -BLI_INLINE MEdge *which_medge(ExportMeshData *export_data, int which_mesh) -{ - MEdge *medge = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - medge = export_data->medge_left; - break; - case CARVE_MESH_RIGHT: - medge = export_data->medge_right; - break; - } - return medge; -} - -BLI_INLINE MLoop *which_mloop(ExportMeshData *export_data, int which_mesh) -{ - MLoop *mloop = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - mloop = export_data->mloop_left; - break; - case CARVE_MESH_RIGHT: - mloop = export_data->mloop_right; - break; - } - return mloop; -} - -BLI_INLINE MPoly *which_mpoly(ExportMeshData *export_data, int which_mesh) -{ - MPoly *mpoly = NULL; - switch (which_mesh) { - case CARVE_MESH_LEFT: - mpoly = export_data->mpoly_left; - break; - case CARVE_MESH_RIGHT: - mpoly = export_data->mpoly_right; - break; - } - return mpoly; -} - -/* Create new external mesh */ -static void exporter_InitGeomArrays(ExportMeshData *export_data, - int num_verts, int num_edges, - int num_loops, int num_polys) -{ - DerivedMesh *dm = CDDM_new(num_verts, num_edges, 0, - num_loops, num_polys); - DerivedMesh *dm_left = export_data->dm_left, - *dm_right = export_data->dm_right; - - /* Mask for custom data layers to be merged from operands. */ - CustomDataMask merge_mask = CD_MASK_DERIVEDMESH & ~CD_MASK_ORIGINDEX; - - export_data->dm = dm; - export_data->mvert = dm->getVertArray(dm); - export_data->medge = dm->getEdgeArray(dm); - export_data->mloop = dm->getLoopArray(dm); - export_data->mpoly = dm->getPolyArray(dm); - - /* Merge custom data layers from operands. - * - * Will only create custom data layers for all the layers which appears in - * the operand. Data for those layers will not be allocated or initialized. - */ - - CustomData_merge(&dm_left->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts); - CustomData_merge(&dm_right->vertData, &dm->vertData, merge_mask, CD_DEFAULT, num_verts); - - CustomData_merge(&dm_left->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); - CustomData_merge(&dm_right->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops); - - CustomData_merge(&dm_left->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); - CustomData_merge(&dm_right->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys); - - CustomData_merge(&dm_left->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges); - CustomData_merge(&dm_right->edgeData, &dm->edgeData, merge_mask, CD_DEFAULT, num_edges); - - export_data->vert_origindex = dm->getVertDataArray(dm, CD_ORIGINDEX); - export_data->edge_origindex = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - export_data->poly_origindex = dm->getPolyDataArray(dm, CD_ORIGINDEX); - export_data->loop_origindex = dm->getLoopDataArray(dm, CD_ORIGINDEX); -} - -/* Set coordinate of vertex with given index. */ -static void exporter_SetVert(ExportMeshData *export_data, - int vert_index, float coord[3], - int which_orig_mesh, int orig_vert_index) -{ - DerivedMesh *dm = export_data->dm; - DerivedMesh *dm_orig; - MVert *mvert = export_data->mvert; - - BLI_assert(vert_index >= 0 && vert_index <= dm->getNumVerts(dm)); - - dm_orig = which_dm(export_data, which_orig_mesh); - if (dm_orig) { - BLI_assert(orig_vert_index >= 0 && orig_vert_index < dm_orig->getNumVerts(dm_orig)); - mvert[vert_index] = which_mvert(export_data, which_orig_mesh)[orig_vert_index]; - CustomData_copy_data(&dm_orig->vertData, &dm->vertData, orig_vert_index, vert_index, 1); - } - - /* Set original index of the vertex. */ - if (export_data->vert_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->vert_origindex[vert_index] = orig_vert_index; - } - else { - export_data->vert_origindex[vert_index] = ORIGINDEX_NONE; - } - } - - mul_v3_m4v3(mvert[vert_index].co, export_data->obimat, coord); -} - -/* Set vertices which are adjucent to the edge specified by it's index. */ -static void exporter_SetEdge(ExportMeshData *export_data, - int edge_index, int v1, int v2, - int which_orig_mesh, int orig_edge_index) -{ - DerivedMesh *dm = export_data->dm; - MEdge *medge = &export_data->medge[edge_index]; - DerivedMesh *dm_orig; - - BLI_assert(edge_index >= 0 && edge_index < dm->getNumEdges(dm)); - BLI_assert(v1 >= 0 && v1 < dm->getNumVerts(dm)); - BLI_assert(v2 >= 0 && v2 < dm->getNumVerts(dm)); - - dm_orig = which_dm(export_data, which_orig_mesh); - if (dm_orig) { - BLI_assert(orig_edge_index >= 0 && orig_edge_index < dm_orig->getNumEdges(dm_orig)); - - *medge = which_medge(export_data, which_orig_mesh)[orig_edge_index]; - - /* Copy all edge layers, including medge. */ - CustomData_copy_data(&dm_orig->edgeData, &dm->edgeData, orig_edge_index, edge_index, 1); - } - - /* Set original index of the edge. */ - if (export_data->edge_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->edge_origindex[edge_index] = orig_edge_index; - } - else { - export_data->edge_origindex[edge_index] = ORIGINDEX_NONE; - } - } - - medge->v1 = v1; - medge->v2 = v2; - - medge->flag |= ME_EDGEDRAW | ME_EDGERENDER; -} - -static void setMPolyMaterial(ExportMeshData *export_data, - MPoly *mpoly, - int which_orig_mesh) -{ - Object *orig_object; - GHash *material_hash; - Material *orig_mat; - - if (which_orig_mesh == CARVE_MESH_LEFT) { - /* No need to change materian index for faces from left operand */ - return; - } - - material_hash = export_data->material_hash; - orig_object = which_object(export_data, which_orig_mesh); - - /* Set material, based on lookup in hash table. */ - orig_mat = give_current_material(orig_object, mpoly->mat_nr + 1); - - if (orig_mat) { - /* For faces from right operand check if there's requested material - * in the left operand. And if it is, use index of that material, - * otherwise fallback to first material (material with index=0). - */ - if (!BLI_ghash_haskey(material_hash, orig_mat)) { - int a, mat_nr; - - mat_nr = 0; - for (a = 0; a < export_data->ob_left->totcol; a++) { - if (give_current_material(export_data->ob_left, a + 1) == orig_mat) { - mat_nr = a; - break; - } - } - - BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr)); - - mpoly->mat_nr = mat_nr; - } - else - mpoly->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat)); - } - else { - mpoly->mat_nr = 0; - } -} - -/* Set list of adjucent loops to the poly specified by it's index. */ -static void exporter_SetPoly(ExportMeshData *export_data, - int poly_index, int start_loop, int num_loops, - int which_orig_mesh, int orig_poly_index) -{ - DerivedMesh *dm = export_data->dm; - MPoly *mpoly = &export_data->mpoly[poly_index]; - DerivedMesh *dm_orig; - int i; - - /* Poly is always to be either from left or right operand. */ - dm_orig = which_dm(export_data, which_orig_mesh); - - BLI_assert(poly_index >= 0 && poly_index < dm->getNumPolys(dm)); - BLI_assert(start_loop >= 0 && start_loop <= dm->getNumLoops(dm) - num_loops); - BLI_assert(num_loops >= 3); - BLI_assert(dm_orig != NULL); - BLI_assert(orig_poly_index >= 0 && orig_poly_index < dm_orig->getNumPolys(dm_orig)); - - /* Copy all poly layers, including mpoly. */ - *mpoly = which_mpoly(export_data, which_orig_mesh)[orig_poly_index]; - CustomData_copy_data(&dm_orig->polyData, &dm->polyData, orig_poly_index, poly_index, 1); - - /* Set material of the curren poly. - * This would re-map materials from right operand to materials from the - * left one as well. - */ - setMPolyMaterial(export_data, mpoly, which_orig_mesh); - - /* Set original index of the poly. */ - if (export_data->poly_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->poly_origindex[poly_index] = orig_poly_index; - } - else { - export_data->poly_origindex[poly_index] = ORIGINDEX_NONE; - } - } - - /* Set poly data itself. */ - mpoly->loopstart = start_loop; - mpoly->totloop = num_loops; - - /* Interpolate data for poly loops. */ - { - MVert *source_mverts = which_mvert(export_data, which_orig_mesh); - MLoop *source_mloops = which_mloop(export_data, which_orig_mesh); - MPoly *source_mpolys = which_mpoly(export_data, which_orig_mesh); - MPoly *source_poly = &source_mpolys[orig_poly_index]; - MVert *target_mverts = export_data->mvert; - MLoop *target_mloops = export_data->mloop; - float (*transform)[4] = NULL; - - if (which_orig_mesh == CARVE_MESH_RIGHT) { - transform = export_data->left_to_right_mat; - } - - for (i = 0; i < mpoly->totloop; i++) { - DM_loop_interp_from_poly(dm_orig, - source_mverts, - source_mloops, - source_poly, - dm, - target_mverts, - target_mloops, - transform, - i + mpoly->loopstart); - } - } -} - -/* Set list vertex and edge which are adjucent to loop with given index. */ -static void exporter_SetLoop(ExportMeshData *export_data, - int loop_index, int vertex, int edge, - int which_orig_mesh, int orig_loop_index) -{ - DerivedMesh *dm = export_data->dm; - MLoop *mloop = &export_data->mloop[loop_index]; - DerivedMesh *dm_orig; - - BLI_assert(loop_index >= 0 && loop_index < dm->getNumLoops(dm)); - BLI_assert(vertex >= 0 && vertex < dm->getNumVerts(dm)); - BLI_assert(edge >= 0 && vertex < dm->getNumEdges(dm)); - - dm_orig = which_dm(export_data, which_orig_mesh); - if (dm_orig) { - BLI_assert(orig_loop_index >= 0 && orig_loop_index < dm_orig->getNumLoops(dm_orig)); - - /* Copy all loop layers, including mloop. */ - *mloop = which_mloop(export_data, which_orig_mesh)[orig_loop_index]; - CustomData_copy_data(&dm_orig->loopData, &dm->loopData, orig_loop_index, loop_index, 1); - } - - /* Set original index of the loop. */ - if (export_data->loop_origindex) { - if (which_orig_mesh == CARVE_MESH_LEFT) { - export_data->loop_origindex[loop_index] = orig_loop_index; - } - else { - export_data->loop_origindex[loop_index] = ORIGINDEX_NONE; - } - } - - mloop->v = vertex; - mloop->e = edge; -} - -/* Edge index from a loop index for a given original mesh. */ -static int exporter_MapLoopToEdge(ExportMeshData *export_data, - int which_mesh, int loop_index) -{ - DerivedMesh *dm = which_dm(export_data, which_mesh); - MLoop *mloop = which_mloop(export_data, which_mesh); - - (void) dm; /* Unused in release builds. */ - - BLI_assert(dm != NULL); - BLI_assert(loop_index >= 0 && loop_index < dm->getNumLoops(dm)); - - return mloop[loop_index].e; -} - -static CarveMeshExporter MeshExporter = { - exporter_InitGeomArrays, - exporter_SetVert, - exporter_SetEdge, - exporter_SetPoly, - exporter_SetLoop, - exporter_MapLoopToEdge -}; - -static int operation_from_optype(int int_op_type) -{ - int operation; - - switch (int_op_type) { - case 1: - operation = CARVE_OP_INTERSECTION; - break; - case 2: - operation = CARVE_OP_UNION; - break; - case 3: - operation = CARVE_OP_A_MINUS_B; - break; - default: - BLI_assert(!"Should not happen"); - operation = -1; - break; - } - - return operation; -} - -static void prepare_import_data(Object *object, - DerivedMesh *dm, - const DMArrays *dm_arrays, - ImportMeshData *import_data) -{ - import_data->dm = dm; - copy_m4_m4(import_data->obmat, object->obmat); - import_data->mvert = dm_arrays->mvert; - import_data->medge = dm_arrays->medge; - import_data->mloop = dm_arrays->mloop; - import_data->mpoly = dm_arrays->mpoly; -} - -static struct CarveMeshDescr *carve_mesh_from_dm(Object *object, - DerivedMesh *dm, - const DMArrays *dm_arrays) -{ - ImportMeshData import_data; - prepare_import_data(object, dm, dm_arrays, &import_data); - return carve_addMesh(&import_data, &MeshImporter); -} - -static void prepare_export_data(Object *object_left, DerivedMesh *dm_left, const DMArrays *dm_left_arrays, - Object *object_right, DerivedMesh *dm_right, const DMArrays *dm_right_arrays, - ExportMeshData *export_data) -{ - float object_right_imat[4][4]; - - invert_m4_m4(export_data->obimat, object_left->obmat); - - export_data->ob_left = object_left; - export_data->ob_right = object_right; - - export_data->dm_left = dm_left; - export_data->dm_right = dm_right; - - export_data->mvert_left = dm_left_arrays->mvert; - export_data->medge_left = dm_left_arrays->medge; - export_data->mloop_left = dm_left_arrays->mloop; - export_data->mpoly_left = dm_left_arrays->mpoly; - export_data->mvert_right = dm_right_arrays->mvert; - export_data->medge_right = dm_right_arrays->medge; - export_data->mloop_right = dm_right_arrays->mloop; - export_data->mpoly_right = dm_right_arrays->mpoly; - - export_data->material_hash = BLI_ghash_ptr_new("CSG_mat gh"); - - /* Matrix to convert coord from left object's loca; space to - * right object's local space. - */ - invert_m4_m4(object_right_imat, object_right->obmat); - mul_m4_m4m4(export_data->left_to_right_mat, object_left->obmat, - object_right_imat); -} - -DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob, - DerivedMesh *dm_select, struct Object *ob_select, - int int_op_type) -{ - - struct CarveMeshDescr *left, *right, *output = NULL; - DerivedMesh *output_dm = NULL; - int operation; - bool result; - DMArrays dm_left_arrays, dm_right_arrays; - - if (dm == NULL || dm_select == NULL) { - return NULL; - } - - operation = operation_from_optype(int_op_type); - if (operation == -1) { - return NULL; - } - - dm_arrays_get(dm_select, &dm_left_arrays); - dm_arrays_get(dm, &dm_right_arrays); - - left = carve_mesh_from_dm(ob_select, dm_select, &dm_left_arrays); - right = carve_mesh_from_dm(ob, dm, &dm_right_arrays); - - result = carve_performBooleanOperation(left, right, operation, &output); - - carve_deleteMesh(left); - carve_deleteMesh(right); - - if (result) { - ExportMeshData export_data; - - prepare_export_data(ob_select, dm_select, &dm_left_arrays, - ob, dm, &dm_right_arrays, - &export_data); - - carve_exportMesh(output, &MeshExporter, &export_data); - output_dm = export_data.dm; - - /* Free memory used by export mesh. */ - BLI_ghash_free(export_data.material_hash, NULL, NULL); - - output_dm->cd_flag |= dm->cd_flag | dm_select->cd_flag; - output_dm->dirty |= DM_DIRTY_NORMALS; - carve_deleteMesh(output); - } - - dm_arrays_free(&dm_left_arrays); - dm_arrays_free(&dm_right_arrays); - - return output_dm; -} |