Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph/intern/builder')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_map.cc15
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc45
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc20
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc143
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc9
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc4
9 files changed, 201 insertions, 47 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 4cbc7700947..8f5925a5ce3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -67,6 +67,12 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
}
if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
flag |= DEG_TAG_COPY_ON_WRITE;
+ /* This means ID is being added to the dependency graph first
+ * time, which is similar to "ob-visible-change"
+ */
+ if (GS(id->name) == ID_OB) {
+ flag |= OB_RECALC_OB | OB_RECALC_DATA;
+ }
}
if (flag != 0) {
DEG_graph_id_tag_update(bmain,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_map.cc b/source/blender/depsgraph/intern/builder/deg_builder_map.cc
index 218483d1dc5..cde7b9721b7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_map.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_map.cc
@@ -37,24 +37,29 @@
namespace DEG {
-BuilderMap::BuilderMap() {
+BuilderMap::BuilderMap()
+{
set = BLI_gset_ptr_new("deg builder gset");
}
-BuilderMap::~BuilderMap() {
+BuilderMap::~BuilderMap()
+{
BLI_gset_free(set, NULL);
}
-bool BuilderMap::checkIsBuilt(ID *id) {
+bool BuilderMap::checkIsBuilt(ID *id)
+{
return BLI_gset_haskey(set, id);
}
-void BuilderMap::tagBuild(ID *id) {
+void BuilderMap::tagBuild(ID *id)
+{
BLI_gset_insert(set, id);
}
-bool BuilderMap::checkIsBuiltAndTag(ID *id) {
+bool BuilderMap::checkIsBuiltAndTag(ID *id)
+{
void **key_p;
if (!BLI_gset_ensure_p_ex(set, id, &key_p)) {
*key_p = id;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index ab7ddb507a0..efd57734b48 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -77,6 +77,8 @@ extern "C" {
#include "BKE_curve.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_modifier.h"
#include "BKE_idcode.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
@@ -93,6 +95,7 @@ extern "C" {
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
+#include "BKE_shader_fx.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
#include "BKE_world.h"
@@ -514,6 +517,18 @@ void DepsgraphNodeBuilder::build_object(int base_index,
data.builder = this;
modifiers_foreachIDLink(object, modifier_walk, &data);
}
+ /* Grease Pencil Modifiers. */
+ if (object->greasepencil_modifiers.first != NULL) {
+ BuilderWalkUserData data;
+ data.builder = this;
+ BKE_gpencil_modifiers_foreachIDLink(object, modifier_walk, &data);
+ }
+ /* Shadr FX. */
+ if (object->shader_fx.first != NULL) {
+ BuilderWalkUserData data;
+ data.builder = this;
+ BKE_shaderfx_foreachIDLink(object, modifier_walk, &data);
+ }
/* Constraints. */
if (object->constraints.first != NULL) {
BuilderWalkUserData data;
@@ -538,10 +553,6 @@ void DepsgraphNodeBuilder::build_object(int base_index,
if (object->particlesystem.first != NULL) {
build_particles(object);
}
- /* Grease pencil. */
- if (object->gpd != NULL) {
- build_gpencil(object->gpd);
- }
/* Proxy object to copy from. */
if (object->proxy_from != NULL) {
build_object(-1, object->proxy_from, DEG_ID_LINKED_INDIRECTLY);
@@ -592,6 +603,7 @@ void DepsgraphNodeBuilder::build_object_data(Object *object)
case OB_SURF:
case OB_MBALL:
case OB_LATTICE:
+ case OB_GPENCIL:
build_object_data_geometry(object);
/* TODO(sergey): Only for until we support granular
* update of curves.
@@ -829,8 +841,19 @@ void DepsgraphNodeBuilder::build_driver_variables(ID * id, FCurve *fcurve)
LISTBASE_FOREACH (DriverVar *, dvar, &fcurve->driver->variables) {
DRIVER_TARGETS_USED_LOOPER(dvar)
{
+ if (dtar->id == NULL) {
+ continue;
+ }
build_id(dtar->id);
build_driver_id_property(dtar->id, dtar->rna_path);
+ /* Corresponds to dtar_id_ensure_proxy_from(). */
+ if ((GS(dtar->id->name) == ID_OB) &&
+ (((Object *)dtar->id)->proxy_from != NULL))
+ {
+ Object *proxy_from = ((Object *)dtar->id)->proxy_from;
+ build_id(&proxy_from->id);
+ build_driver_id_property(&proxy_from->id, dtar->rna_path);
+ }
}
DRIVER_TARGETS_LOOPER_END
}
@@ -1202,6 +1225,20 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata)
op_node->set_as_entry();
break;
}
+
+ case ID_GD:
+ {
+ /* GPencil evaluation operations. */
+ op_node = add_operation_node(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ function_bind(BKE_gpencil_eval_geometry,
+ _1,
+ (bGPdata *)obdata_cow),
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
+ op_node->set_as_entry();
+ break;
+ }
default:
BLI_assert(!"Should not happen");
break;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 6899a86b3e9..66293a91e85 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -158,7 +158,7 @@ struct DepsgraphNodeBuilder {
const char *name = "",
int name_tag = -1);
- void build_id(ID* id);
+ void build_id(ID *id);
void build_layer_collections(ListBase *lb);
void build_view_layer(Scene *scene,
ViewLayer *view_layer,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 00d7a5da455..b1486e82af5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -161,7 +161,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
build_armature(armature);
/* Rebuild pose if not up to date. */
if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) {
- BKE_pose_rebuild(object, armature);
+ /* By definition, no need to tag depsgraph as dirty from here, so we can pass NULL bmain. */
+ BKE_pose_rebuild(NULL, object, armature, true);
/* XXX: Without this animation gets lost in certain circumstances
* after loading file. Need to investigate further since it does
* not happen with simple scenes..
@@ -313,12 +314,13 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
}
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_EVAL_POSE,
- function_bind(BKE_pose_eval_proxy_copy,
+ function_bind(BKE_pose_eval_proxy_pose_init,
_1,
object_cow),
DEG_OPCODE_POSE_INIT);
op_node->set_as_entry();
+ int pchan_index = 0;
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_BONE,
@@ -333,10 +335,14 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
NULL,
DEG_OPCODE_BONE_READY);
/* Bone is fully evaluated. */
- op_node = add_operation_node(&object->id,
+ op_node = add_operation_node(
+ &object->id,
DEG_NODE_TYPE_BONE,
pchan->name,
- NULL,
+ function_bind(BKE_pose_eval_proxy_copy_bone,
+ _1,
+ object_cow,
+ pchan_index),
DEG_OPCODE_BONE_DONE);
op_node->set_as_exit();
@@ -348,10 +354,14 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
DEG_OPCODE_PARAMETERS_EVAL,
pchan->name);
}
+
+ pchan_index++;
}
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_EVAL_POSE,
- NULL,
+ function_bind(BKE_pose_eval_proxy_pose_done,
+ _1,
+ object_cow),
DEG_OPCODE_POSE_DONE);
op_node->set_as_exit();
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index f1db05b7220..3d7b2d6d232 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -134,10 +134,6 @@ void DepsgraphNodeBuilder::build_view_layer(
if (scene->nodetree != NULL) {
build_compositor(scene);
}
- /* Grease pencil. */
- if (scene->gpd != NULL) {
- build_gpencil(scene->gpd);
- }
/* Cache file. */
LISTBASE_FOREACH (CacheFile *, cachefile, &bmain_->cachefiles) {
build_cachefile(cachefile);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index bba1ba67962..4f94066f3bb 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -85,10 +85,12 @@ extern "C" {
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
+#include "BKE_gpencil_modifier.h"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_rigidbody.h"
+#include "BKE_shader_fx.h"
#include "BKE_sound.h"
#include "BKE_tracking.h"
#include "BKE_world.h"
@@ -525,6 +527,18 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
data.builder = this;
modifiers_foreachIDLink(object, modifier_walk, &data);
}
+ /* Grease Pencil Modifiers. */
+ if (object->greasepencil_modifiers.first != NULL) {
+ BuilderWalkUserData data;
+ data.builder = this;
+ BKE_gpencil_modifiers_foreachIDLink(object, modifier_walk, &data);
+ }
+ /* Shader FX. */
+ if (object->shader_fx.first != NULL) {
+ BuilderWalkUserData data;
+ data.builder = this;
+ BKE_shaderfx_foreachIDLink(object, modifier_walk, &data);
+ }
/* Constraints. */
if (object->constraints.first != NULL) {
BuilderWalkUserData data;
@@ -570,17 +584,9 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
if (object->particlesystem.first != NULL) {
build_particles(object);
}
- /* Grease pencil. */
- if (object->gpd != NULL) {
- build_gpencil(object->gpd);
- }
/* Proxy object to copy from. */
if (object->proxy_from != NULL) {
build_object(NULL, object->proxy_from);
- ComponentKey ob_pose_key(&object->proxy_from->id, DEG_NODE_TYPE_EVAL_POSE);
- ComponentKey proxy_pose_key(&object->id, DEG_NODE_TYPE_EVAL_POSE);
- add_relation(ob_pose_key, proxy_pose_key, "Proxy Pose");
-
ComponentKey ob_transform_key(&object->proxy_from->id, DEG_NODE_TYPE_TRANSFORM);
ComponentKey proxy_transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(ob_transform_key, proxy_transform_key, "Proxy Transform");
@@ -630,6 +636,7 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
case OB_SURF:
case OB_MBALL:
case OB_LATTICE:
+ case OB_GPENCIL:
{
build_object_data_geometry(object);
break;
@@ -1351,6 +1358,14 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
continue;
}
build_id(dtar->id);
+ /* Initialize relations coming to proxy_from. */
+ Object *proxy_from = NULL;
+ if ((GS(dtar->id->name) == ID_OB) &&
+ (((Object *)dtar->id)->proxy_from != NULL))
+ {
+ proxy_from = ((Object *)dtar->id)->proxy_from;
+ build_id(&proxy_from->id);
+ }
/* Special handling for directly-named bones. */
if ((dtar->flag & DTAR_FLAG_STRUCT_REF) &&
(((Object *)dtar->id)->type == OB_ARMATURE) &&
@@ -1398,6 +1413,13 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
continue;
}
add_relation(variable_key, driver_key, "RNA Target -> Driver");
+ if (proxy_from != NULL) {
+ RNAPathKey proxy_from_variable_key(&proxy_from->id,
+ dtar->rna_path);
+ add_relation(proxy_from_variable_key,
+ variable_key,
+ "Proxy From -> Variable");
+ }
}
else {
if (dtar->id == id) {
@@ -1783,6 +1805,42 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
}
}
}
+ /* Grease Pencil Modifiers */
+ if (object->greasepencil_modifiers.first != NULL) {
+ ModifierUpdateDepsgraphContext ctx = {};
+ ctx.scene = scene_;
+ ctx.object = object;
+ LISTBASE_FOREACH(GpencilModifierData *, md, &object->greasepencil_modifiers) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo((GpencilModifierType)md->type);
+ if (mti->updateDepsgraph) {
+ DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
+ ctx.node = reinterpret_cast< ::DepsNodeHandle* >(&handle);
+ mti->updateDepsgraph(md, &ctx);
+ }
+ if (BKE_object_modifier_gpencil_use_time(object, md)) {
+ TimeSourceKey time_src_key;
+ add_relation(time_src_key, obdata_ubereval_key, "Time Source");
+ }
+ }
+ }
+ /* Shader FX */
+ if (object->shader_fx.first != NULL) {
+ ModifierUpdateDepsgraphContext ctx = {};
+ ctx.scene = scene_;
+ ctx.object = object;
+ LISTBASE_FOREACH(ShaderFxData *, fx, &object->shader_fx) {
+ const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo((ShaderFxType)fx->type);
+ if (fxi->updateDepsgraph) {
+ DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
+ ctx.node = reinterpret_cast< ::DepsNodeHandle* >(&handle);
+ fxi->updateDepsgraph(fx, &ctx);
+ }
+ if (BKE_object_shaderfx_use_time(object, fx)) {
+ TimeSourceKey time_src_key;
+ add_relation(time_src_key, obdata_ubereval_key, "Time Source");
+ }
+ }
+ }
/* Materials. */
if (object->totcol) {
for (int a = 1; a <= object->totcol; a++) {
@@ -1880,13 +1938,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
}
/* Link object data evaluation node to exit operation. */
OperationKey obdata_geom_eval_key(obdata,
- DEG_NODE_TYPE_GEOMETRY,
- DEG_OPCODE_PLACEHOLDER,
- "Geometry Eval");
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
OperationKey obdata_geom_done_key(obdata,
- DEG_NODE_TYPE_GEOMETRY,
- DEG_OPCODE_PLACEHOLDER,
- "Eval Done");
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_PLACEHOLDER,
+ "Eval Done");
add_relation(obdata_geom_eval_key,
obdata_geom_done_key,
"ObData Geom Eval Done");
@@ -1902,35 +1960,67 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
Curve *cu = (Curve *)obdata;
if (cu->bevobj != NULL) {
ComponentKey bevob_geom_key(&cu->bevobj->id,
- DEG_NODE_TYPE_GEOMETRY);
+ DEG_NODE_TYPE_GEOMETRY);
add_relation(bevob_geom_key,
- obdata_geom_eval_key,
- "Curve Bevel Geometry");
+ obdata_geom_eval_key,
+ "Curve Bevel Geometry");
ComponentKey bevob_key(&cu->bevobj->id,
- DEG_NODE_TYPE_TRANSFORM);
+ DEG_NODE_TYPE_TRANSFORM);
add_relation(bevob_key,
- obdata_geom_eval_key,
- "Curve Bevel Transform");
+ obdata_geom_eval_key,
+ "Curve Bevel Transform");
build_object(NULL, cu->bevobj);
}
if (cu->taperobj != NULL) {
ComponentKey taperob_key(&cu->taperobj->id,
- DEG_NODE_TYPE_GEOMETRY);
+ DEG_NODE_TYPE_GEOMETRY);
add_relation(taperob_key, obdata_geom_eval_key, "Curve Taper");
build_object(NULL, cu->taperobj);
}
if (cu->textoncurve != NULL) {
ComponentKey textoncurve_key(&cu->textoncurve->id,
- DEG_NODE_TYPE_GEOMETRY);
+ DEG_NODE_TYPE_GEOMETRY);
add_relation(textoncurve_key,
- obdata_geom_eval_key,
- "Text on Curve");
+ obdata_geom_eval_key,
+ "Text on Curve");
build_object(NULL, cu->textoncurve);
}
break;
}
case ID_LT:
break;
+ case ID_GD: /* Grease Pencil */
+ {
+ bGPdata *gpd = (bGPdata *)obdata;
+
+ /* Geometry cache needs to be recalculated on frame change
+ * (e.g. to fix crashes after scrubbing the timeline when
+ * onion skinning is enabled, since the ghosts need to be
+ * re-added to the cache once scrubbing ends)
+ */
+ TimeSourceKey time_key;
+ ComponentKey geometry_key(obdata, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(time_key,
+ geometry_key,
+ "GP Frame Change");
+
+ /* Geometry cache also needs to be recalculated when Material
+ * settings change (e.g. when fill.opacity changes on/off,
+ * we need to rebuild the bGPDstroke->triangles caches)
+ */
+ for (int i = 0; i < gpd->totcol; i++) {
+ Material *ma = gpd->mat[i];
+ if ((ma != NULL) && (ma->gp_style != NULL)) {
+ OperationKey material_key(&ma->id,
+ DEG_NODE_TYPE_SHADING,
+ DEG_OPCODE_MATERIAL_UPDATE);
+ add_relation(material_key,
+ geometry_key,
+ "Material -> GP Data");
+ }
+ }
+ break;
+ }
default:
BLI_assert(!"Should not happen");
break;
@@ -2213,6 +2303,11 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node
if (id_type == ID_ME && comp_node->type == DEG_NODE_TYPE_GEOMETRY) {
rel_flag &= ~DEPSREL_FLAG_NO_FLUSH;
}
+ /* materials need update grease pencil objects */
+ if (id_type == ID_MA) {
+ rel_flag &= ~DEPSREL_FLAG_NO_FLUSH;
+ }
+
/* Notes on exceptions:
* - Parameters component is where drivers are living. Changing any
* of the (custom) properties in the original datablock (even the
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index eaa17d27ffc..811986ea0e8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -469,11 +469,20 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
DEG_NODE_TYPE_BONE,
pchan->name,
DEG_OPCODE_BONE_DONE);
+ OperationKey from_bone_done_key(&proxy_from->id,
+ DEG_NODE_TYPE_BONE,
+ pchan->name,
+ DEG_OPCODE_BONE_DONE);
add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local");
add_relation(bone_local_key, bone_ready_key, "Local -> Ready");
add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done");
+ /* Make sure bone in the proxy is not done before it's FROM is done. */
+ add_relation(from_bone_done_key,
+ bone_done_key,
+ "From Bone Done -> Pose Done");
+
if (pchan->prop != NULL) {
OperationKey bone_parameters(&object->id,
DEG_NODE_TYPE_PARAMETERS,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index f069c63f138..78d1a930eb7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -123,10 +123,6 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
if (scene->nodetree != NULL) {
build_compositor(scene);
}
- /* Grease pencil. */
- if (scene->gpd != NULL) {
- build_gpencil(scene->gpd);
- }
/* Masks. */
LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) {
build_mask(mask);