Advertisement
Guest User

Untitled

a guest
Jun 20th, 2019
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.70 KB | None | 0 0
  1. // struct added to DNA_modifier_types.h
  2. typedef struct VertexSnapModifierData {
  3.     ModifierData modifier;
  4.     struct Object *target;  /* bind target object */
  5.     char vertex_group[64];
  6.     int *bindings;  /* This is not unsigned so that -1 can be skipped */
  7.     int total_bindings;
  8.     int binding_type;
  9.     float binding_distance;
  10.     float blend;
  11.     int deform_space;
  12.     int flags;
  13. } VertexSnapModifierData;
  14.  
  15. enum {
  16.   MOD_VSNAP_NEEDS_BIND   = (1 << 1),
  17.   MOD_VSNAP_NEEDS_UNBIND = (1 << 2)
  18. };
  19.  
  20. enum {
  21.     MOD_VSNAP_LOCAL = 0,
  22.     MOD_VSNAP_WORLD = 1
  23. };
  24.  
  25. enum {
  26.     MOD_VSNAP_BIND_INDEX   = 0,
  27.     MOD_VSNAP_BIND_CLOSEST = 1,
  28.     MOD_VSNAP_BIND_NORMAL  = 2
  29. };
  30.  
  31.  
  32.  
  33. // MOD_vertexsnap.c
  34. /*
  35.  * ***** BEGIN GPL LICENSE BLOCK *****
  36.  *
  37.  * This program is free software; you can redistribute it and/or
  38.  * modify it under the terms of the GNU General Public License
  39.  * as published by the Free Software Foundation; either version 2
  40.  * of the License, or (at your option) any later version.
  41.  *
  42.  * This program is distributed in the hope that it will be useful,
  43.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  44.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  45.  * GNU General Public License for more details.
  46.  *
  47.  * You should have received a copy of the GNU General Public License
  48.  * along with this program; if not, write to the Free Software  Foundation,
  49.  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  50.  *
  51.  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
  52.  * All rights reserved.
  53.  *
  54.  * Contributor(s): Your name
  55.  *
  56.  * ***** END GPL LICENSE BLOCK *****
  57.  *
  58.  */
  59.  
  60. /** \file blender/modifiers/intern/MOD_Snap.c
  61.  *  \ingroup modifiers
  62.  */
  63.  
  64. #include "DNA_mesh_types.h"
  65. #include "DNA_meshdata_types.h"
  66. #include "DNA_object_types.h"
  67.  
  68. #include "BLI_math.h"
  69. #include "BLI_task.h"
  70. #include "BLI_string.h"
  71. #include "BLI_utildefines.h"
  72.  
  73. #include "MEM_guardedalloc.h"
  74.  
  75. #include "BKE_action.h"
  76. #include "BKE_bvhutils.h"
  77. #include "BKE_cdderivedmesh.h"
  78. #include "BKE_deform.h"
  79. #include "BKE_library.h"
  80. #include "BKE_library_query.h"
  81. #include "BKE_mesh.h"
  82. #include "BKE_particle.h"
  83.  
  84. #include "MOD_util.h"
  85.  
  86. #include "DEG_depsgraph_query.h"
  87.  
  88.  
  89. // #define DEBUG_TIME 1
  90.  
  91. #include "PIL_time.h"
  92. #ifdef DEBUG_TIME
  93.     #include "PIL_time_utildefines.h"
  94. #endif
  95.  
  96.  
  97. static void initData(ModifierData *md)
  98. {
  99.     VertexSnapModifierData* vmd = (VertexSnapModifierData*) md;
  100.     vmd->blend = 1.0f;
  101.     vmd->target = NULL;
  102.     vmd->vertex_group[0] = 0;
  103.     vmd->deform_space = MOD_VSNAP_LOCAL;
  104.     vmd->bindings = NULL;
  105.     vmd->total_bindings = 0;
  106.     vmd->binding_type = MOD_VSNAP_BIND_INDEX;
  107.     vmd->binding_distance = 64.0f;
  108.     vmd->flags = 0;
  109. }
  110.  
  111. static bool isDisabled(const struct Scene *scene, ModifierData *md, bool userRenderParams)
  112. {
  113.     /* disable if modifier there is no connected target object*/
  114.     VertexSnapModifierData* vmd = (VertexSnapModifierData*)md;
  115.    
  116.     if ( vmd->target ) {
  117.         if ( vmd->target->type == OB_MESH ) {
  118.             return false;
  119.         }
  120.     }
  121.  
  122.     return true;
  123. }
  124.  
  125. static void requiredDataMask(Object *UNUSED(ob),
  126.                              ModifierData *md,
  127.                              CustomData_MeshMasks *r_cddata_masks)
  128. {
  129.     VertexSnapModifierData* enmd = (VertexSnapModifierData*)md;
  130.  
  131.     /* Ask for vertexgroups if we need them. */
  132.     if (enmd->vertex_group[0] != '\0') {
  133.         r_cddata_masks->vmask |= ( CD_MASK_MDEFORMVERT );
  134.     }
  135. }
  136.  
  137. static void freeData(ModifierData *md)
  138. {
  139.     VertexSnapModifierData* vmd = (VertexSnapModifierData*)md;
  140.  
  141.     if (vmd->bindings && vmd->total_bindings) {
  142.         printf("Freeing bindings...\n");
  143.         MEM_SAFE_FREE(vmd->bindings);
  144.     }
  145.  
  146.     vmd->total_bindings = 0;
  147.     vmd->flags &= ~MOD_VSNAP_NEEDS_UNBIND;
  148.  
  149.     if (vmd->modifier.orig_modifier_data) {
  150.         VertexSnapModifierData* orig_vmd = (VertexSnapModifierData*)vmd->modifier.orig_modifier_data;
  151.         if (orig_vmd->bindings && orig_vmd->total_bindings) {
  152.             MEM_SAFE_FREE(orig_vmd->bindings);
  153.         }
  154.         orig_vmd->total_bindings = 0;
  155.         orig_vmd->flags &= ~MOD_VSNAP_NEEDS_UNBIND;
  156.     }
  157. }
  158.  
  159.  
  160. static void copyData(const ModifierData *md, ModifierData *target, const int flag)
  161. {
  162.     const VertexSnapModifierData* vmd  = (VertexSnapModifierData*)md;
  163.     VertexSnapModifierData* target_vmd = (VertexSnapModifierData*)target;
  164.  
  165.     modifier_copyData_generic(md, target, flag);
  166.  
  167.     target_vmd->bindings = NULL;
  168.     target_vmd->total_bindings = 0;
  169.  
  170.     // avoid a possible memory leak
  171.     // freeData(target);
  172.  
  173.     if (vmd->bindings && vmd->total_bindings) {
  174.         target_vmd->bindings = MEM_dupallocN(vmd->bindings);
  175.         target_vmd->total_bindings = vmd->total_bindings;
  176.     }
  177. }
  178.  
  179. static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
  180. {
  181.     VertexSnapModifierData* vmd = (VertexSnapModifierData*)md;
  182.  
  183.     walk( userData, ob, &vmd->target, IDWALK_NOP );
  184. }
  185.  
  186. static void updateDepsgraph(ModifierData *md,
  187.                             const ModifierUpdateDepsgraphContext *ctx)
  188.  
  189. {
  190.     VertexSnapModifierData* vmd = (VertexSnapModifierData*)md;
  191.     if (vmd->target != NULL) {
  192.         DEG_add_object_relation(ctx->node, vmd->target,
  193.                 DEG_OB_COMP_GEOMETRY, "VertexSnap Modifier");
  194.         DEG_add_object_relation(ctx->node, vmd->target,
  195.                 DEG_OB_COMP_TRANSFORM, "VertexSnap Modifier");
  196.     }
  197.  
  198.     // make sure we're linked to our own transform
  199.     // do we need this? Yes, we do.
  200.     DEG_add_modifier_to_transform_relation(ctx->node, "VertexSnap Modifier");
  201. }
  202.  
  203. static inline void propagate_bindings_to_original(VertexSnapModifierData* vmd) {
  204.     if (vmd && vmd->modifier.orig_modifier_data) {
  205.         /*
  206.          So this is new:
  207.          If you don't copy this information to the original modifier,
  208.          including the rebind flag, then the original modifier never
  209.          really gets changed and you end up in a terrible rebind loop,
  210.          with a copy of the original "unbound + needs rebind" data
  211.          getting passed in at certain times instead of the data you
  212.          stuffed into a copy that no longer exists.
  213.          */
  214.         VertexSnapModifierData* orig_vmd = (VertexSnapModifierData*)vmd->modifier.orig_modifier_data;
  215.         if (vmd->bindings) {
  216.             orig_vmd->bindings = MEM_dupallocN(vmd->bindings);
  217.             orig_vmd->total_bindings = vmd->total_bindings;
  218.         }
  219.         orig_vmd->flags = vmd->flags;
  220.     }
  221. }
  222.  
  223. /* binding calculations */
  224. static inline void calculate_closest_point_bindings(ModifierData* md, Mesh* mesh,
  225.                                                     Mesh* target_mesh, const float (*world_matrix)[4],
  226.                                                                                                         const float (*target_inverse_matrix)[4]) {
  227.     int index = 0;
  228.     BVHTreeFromMesh bvh_tree = {NULL};
  229.     BVHTreeNearest nearest = {0};
  230.     VertexSnapModifierData* vmd = (VertexSnapModifierData*)md;
  231.     freeData(md);
  232.  
  233.     if (!mesh) {
  234.         // should never happen...
  235.         modifier_setError(md, "Cannot bind-- no mesh data.");
  236.         return;
  237.     }
  238.  
  239.     if (!target_mesh) {
  240.         modifier_setError(md, "Cannot bind-- no target mesh.");
  241.         return;
  242.     }
  243.  
  244.     vmd->bindings = (unsigned int*)MEM_mallocN(sizeof(unsigned int) * mesh->totvert, "VertexSnapModifier Bindings");
  245.     BKE_bvhtree_from_mesh_get(&bvh_tree, target_mesh, BVHTREE_FROM_VERTS, 2);
  246.    
  247.     if (bvh_tree.tree == NULL) {
  248.         freeData(md);
  249.         modifier_setError((ModifierData*)md, "Out of memory");
  250.         return;
  251.     }
  252.  
  253.     for (index = 0; index < mesh->totvert; index++) {
  254.         float world_coordinate[3];
  255.         if (vmd->deform_space == MOD_VSNAP_WORLD) {
  256.             mul_v3_m4v3(world_coordinate, world_matrix, mesh->mvert[index].co);
  257.             mul_v3_m4v3(world_coordinate, target_inverse_matrix, world_coordinate);
  258.         }
  259.         else {
  260.             copy_v3_v3(world_coordinate, mesh->mvert[index].co);
  261.         }
  262.         nearest.index = -1;
  263.         nearest.dist_sq = 64.0f;
  264.         BLI_bvhtree_find_nearest(bvh_tree.tree,
  265.                                  world_coordinate,
  266.                                  &nearest,
  267.                                  NULL,
  268.                                  &bvh_tree);
  269.  
  270.         // We're going to skip bindings whose
  271.         // index is -1 later on.
  272.         vmd->bindings[index] = nearest.index;
  273.     }
  274.  
  275.     vmd->total_bindings = mesh->totvert;
  276.     vmd->flags = 0;
  277.  
  278.     propagate_bindings_to_original(vmd);
  279.     free_bvhtree_from_mesh(&bvh_tree);
  280. }
  281.  
  282. static inline void calculate_closest_point_and_normal_bindings(ModifierData* md, Mesh* mesh, Mesh* target_mesh) {
  283.     /*
  284.         check out BLI_bvhtree_range_query.
  285.         It seems to do what I want for looking
  286.         within a radius and applies the
  287.         callback function to each found point.
  288.     */
  289.  
  290. }
  291.  
  292. typedef struct VertexSnapUserdata {
  293.     /*const*/ VertexSnapModifierData* vmd;
  294.     MDeformVert *dverts;
  295.     MVert *target_mvert;
  296.     float (*vertexCos)[3];
  297.     float object_matrix[4][4];
  298.     float target_matrix[4][4];
  299.     float object_matrix_inv[4][4];
  300.     int   deform_group_index;
  301. } VertexSnapUserdata;
  302.  
  303.  
  304. static void VertexSnapModifier_do_task(void *__restrict userdata,
  305.                                        const int iter,
  306.                                        const ParallelRangeTLS *__restrict UNUSED(tls))
  307. {
  308.     VertexSnapUserdata     *data  = (VertexSnapUserdata *)userdata;
  309.     VertexSnapModifierData* vmd   = data->vmd;
  310.     MDeformVert *dverts           = data->dverts;
  311.     // MVert       *mesh_mvert       = data->mesh_mvert;
  312.     MVert       *target_mvert     = data->target_mvert;
  313.     float      (*vertexCos)[3]    = data->vertexCos;
  314.     int          target_index     = iter;
  315.  
  316.     float blend = vmd->blend;
  317.     const float deform_group_index = data->deform_group_index;
  318.  
  319.     if (dverts) {
  320.         blend *= defvert_find_weight( &dverts[iter], deform_group_index);
  321.     }
  322.  
  323.     if (!blend) {
  324.         return;
  325.     }
  326.  
  327.     if (vmd->binding_type != MOD_VSNAP_BIND_INDEX) {
  328.         target_index = vmd->bindings[iter];
  329.         if (target_index < 0) {
  330.             // some sort of an error has happened in the bind--
  331.             // skip this vertex
  332.             return;
  333.         }
  334.     }
  335.  
  336.     if ( vmd->deform_space == MOD_VSNAP_WORLD ) {
  337.         float object_co[3];
  338.         float target_co[3];
  339.  
  340.         // calculate lerp in world space
  341.         //!FIXME: This is dumb. Should calculate in object space
  342.         mul_v3_m4v3( object_co, data->object_matrix, vertexCos[iter] );
  343.         mul_v3_m4v3( target_co, data->target_matrix, target_mvert[target_index].co );
  344.         interp_v3_v3v3( object_co, object_co, target_co, blend);
  345.        
  346.         // remove the world matrix of the deforming object
  347.         // after doing the lerp
  348.         mul_v3_m4v3( vertexCos[iter], data->object_matrix_inv, object_co );
  349.  
  350.     } else {
  351.         interp_v3_v3v3( vertexCos[iter], vertexCos[iter], target_mvert[target_index].co, blend);
  352.     }
  353. }
  354.  
  355.  
  356. static void VertexSnapModifier_do(ModifierData *md,
  357.                                   const ModifierEvalContext *ctx,
  358.                                   Object *ob,
  359.                                   Mesh *mesh,
  360.                                   float (*vertexCos)[3],
  361.                                   int numVerts)
  362. {
  363.     VertexSnapModifierData* vmd = (VertexSnapModifierData* )md;
  364.     struct Object *target       = vmd->target;
  365.     MDeformVert   *dverts       = NULL;
  366.     int deform_group_index      = -1;
  367.     const int vertex_count      = numVerts;
  368.     const float blend           = vmd->blend;
  369.  
  370.     if ( blend == 0.0 )
  371.         return;
  372.  
  373.     struct Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(target, false);;
  374.     if (!target_mesh) {
  375.         modifier_setError(md, "Cannot get the target mesh object.");
  376.         return;
  377.     }
  378.  
  379.     if (!(target && target != ob && target->type == OB_MESH)) {
  380.         // this shouldn't happen
  381.         modifier_setError(md, "Target %s is not a Mesh.", target->id.name + 2);
  382.         return;
  383.     }
  384.  
  385.     if (vmd->binding_type == MOD_VSNAP_BIND_INDEX && vertex_count != target_mesh->totvert) {
  386.         modifier_setError(md, "Target vertex count is %d; should be %d.",
  387.                         target_mesh->totvert, vertex_count);
  388.         return;
  389.     }
  390.  
  391.     invert_m4_m4( ob->imat, ob->obmat );
  392.     invert_m4_m4( target->imat, target->obmat );
  393.  
  394.     /* bindings calculations */
  395.     if (vmd->flags & MOD_VSNAP_NEEDS_UNBIND) {
  396.         printf("Unbinding...\n");
  397.         freeData(md);
  398.     }
  399.  
  400.     // if (DEG_is_active(ctx->depsgraph)) {
  401.         if (vmd->flags & MOD_VSNAP_NEEDS_BIND) {
  402.             if (vmd->binding_type == MOD_VSNAP_BIND_CLOSEST) {
  403.                 calculate_closest_point_bindings(md, mesh, target_mesh, ob->obmat, target->imat);
  404.             }
  405.             else if (vmd->binding_type == MOD_VSNAP_BIND_NORMAL) {
  406.                 //!FIXME: Do this one
  407.                 modifier_setError(md, "Tried to rebind, but type is not Closest.");
  408.                 return;
  409.                 calculate_closest_point_and_normal_bindings(md, mesh, target_mesh);
  410.             }
  411.         }
  412.     // }
  413.     // else {
  414.     //  modifier_setError(md, "Attempt to bind from inactive dependency graph");
  415.     //  return;
  416.     // }
  417.  
  418.     if (vmd->binding_type != MOD_VSNAP_BIND_INDEX && !vmd->bindings) {
  419.         //##!FIXME: This shouldn't fire when it's in non-depsgraph mode
  420.         modifier_setError(md, "Not bound.");
  421.         return;
  422.     }
  423.  
  424.     vmd->total_bindings = mesh->totvert;
  425.  
  426.     MOD_get_vgroup(ob, mesh, vmd->vertex_group, &dverts, &deform_group_index);
  427.  
  428.     VertexSnapUserdata data;
  429.     data.vmd    = vmd;
  430.     data.dverts = dverts;
  431.     copy_m4_m4(data.object_matrix, ob->obmat);
  432.     copy_m4_m4(data.object_matrix_inv, ob->imat);
  433.     copy_m4_m4(data.target_matrix,target->obmat);
  434.     data.target_mvert = target_mesh->mvert;
  435.     data.vertexCos    = vertexCos;
  436.     data.deform_group_index = deform_group_index;
  437.  
  438.     #ifdef DEBUG_TIME
  439.         TIMEIT_START( vertex_snap_modifier );
  440.     #endif
  441.  
  442.     ParallelRangeSettings settings;
  443.     BLI_parallel_range_settings_defaults(&settings);
  444.     settings.use_threading = (vertex_count > 512);
  445.     BLI_task_parallel_range(0, vertex_count, &data, VertexSnapModifier_do_task, &settings);
  446.  
  447.     #ifdef DEBUG_TIME
  448.         TIMEIT_END( vertex_snap_modifier );
  449.     #endif
  450. }
  451.  
  452. static void deformVerts(struct ModifierData *md,
  453.  
  454.                         const struct ModifierEvalContext *ctx,
  455.                         struct Mesh *mesh,
  456.                         float (*vertexCos)[3],
  457.                         int numVerts)
  458. {
  459.     Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh,
  460.                                                 NULL, numVerts, false, false);
  461.  
  462.     VertexSnapModifier_do(md, ctx, ctx->object, mesh_src, vertexCos, numVerts);
  463. }
  464.  
  465. static void deformVertsEM(struct ModifierData *md,
  466.                           const struct ModifierEvalContext *ctx,
  467.                           struct BMEditMesh *editData,
  468.                           struct Mesh *mesh,
  469.                           float (*vertexCos)[3],
  470.                           int numVerts)
  471. {
  472.     VertexSnapModifier_do(md, ctx, ctx->object, mesh, vertexCos, numVerts);
  473. }
  474.  
  475.  
  476. ModifierTypeInfo modifierType_VertexSnap = {
  477.     /* name */              "VertexSnap",
  478.     /* structName */        "VertexSnapModifierData",
  479.     /* structSize */        sizeof(VertexSnapModifierData),
  480.     /* type */              eModifierTypeType_OnlyDeform,
  481.     /* flags */             eModifierTypeFlag_AcceptsMesh |
  482.                             eModifierTypeFlag_SupportsEditmode,
  483.  
  484.     /* copyData */          copyData,
  485.     /* deformVerts */       deformVerts,
  486.     /* deformMatrices */    NULL,
  487.     /* deformVertsEM */     deformVertsEM,
  488.     /* deformMatricesEM */  NULL,
  489.     /* applyModifier */     NULL,
  490.     /* initData */          initData,
  491.     /* requiredDataMask */  requiredDataMask,
  492.     /* freeData */          freeData,
  493.     /* isDisabled */        isDisabled,
  494.     /* updateDepsgraph */   updateDepsgraph,
  495.     /* dependsOnTime */     NULL,
  496.     /* dependsOnNormals */  NULL,
  497.     /* foreachObjectLink */ foreachObjectLink,
  498.     /* foreachIDLink */     NULL,
  499.     /* foreachTexLink */    NULL,
  500.     /* freeRuntimeData */   NULL
  501. };
  502.  
  503.  
  504.  
  505.  
  506. // below was added to object_modifier.c, and properly registered.
  507. /************************ VertexSnap bind operator *********************/
  508.  
  509. static bool vertexsnap_poll(bContext *C)
  510. {
  511.   return true;
  512.   // return edit_modifier_poll_generic(C, &RNA_VertexSnapModifier, 0);
  513. }
  514.  
  515. static int vertexsnap_bind_exec(bContext *C, wmOperator *op)
  516. {
  517.     Object *ob = ED_object_active_context(C);
  518.     Depsgraph *depsgraph = CTX_data_depsgraph(C);
  519.     VertexSnapModifierData *vmd = (VertexSnapModifierData *)edit_modifier_property_get(
  520.         op, ob, eModifierType_VertexSnap);
  521.  
  522.     if (vmd == NULL) {
  523.         return OPERATOR_CANCELLED;
  524.     }
  525.  
  526.     VertexSnapModifierData *vmd_eval = (VertexSnapModifierData *)modifier_get_evaluated(
  527.         depsgraph, ob, &vmd->modifier);
  528.  
  529.     if (vmd->bindings && vmd->total_bindings) {
  530.         vmd->flags = MOD_VSNAP_NEEDS_UNBIND;
  531.     }
  532.     else {
  533.         vmd->flags = MOD_VSNAP_NEEDS_BIND;
  534.     }
  535.  
  536.   vmd_eval->flags = vmd->flags;
  537.  
  538.     object_force_modifier_bind_simple_options(depsgraph, ob, &vmd->modifier);
  539.     vmd->flags = vmd_eval->flags = 0;
  540.  
  541.     DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
  542.     WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
  543.     return OPERATOR_FINISHED;
  544. }
  545.  
  546. static int vertexsnap_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
  547. {
  548.   if (edit_modifier_invoke_properties(C, op)) {
  549.     return vertexsnap_bind_exec(C, op);
  550.   }
  551.   else {
  552.     return OPERATOR_CANCELLED;
  553.   }
  554. }
  555.  
  556. void OBJECT_OT_vertexsnap_bind(wmOperatorType *ot)
  557. {
  558.   /* identifiers */
  559.   ot->name        = "VertexSnap Bind";
  560.   ot->description = "Bind mesh to target in VertexSnap modifier";
  561.   ot->idname      = "OBJECT_OT_vertexsnap_bind";
  562.  
  563.   /* api callbacks */
  564.   ot->poll   = vertexsnap_poll;
  565.   ot->invoke = vertexsnap_bind_invoke;
  566.   ot->exec   = vertexsnap_bind_exec;
  567.  
  568.   /* flags */
  569.   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
  570.   edit_modifier_properties(ot);
  571. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement