doxygen: add newline after \file
[blender.git] / source / blender / blenkernel / BKE_subdiv.h
index 0a09d35..4fddb3d 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * ***** 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
  *
  * The Original Code is Copyright (C) 2018 by Blender Foundation.
  * All rights reserved.
- *
- * Contributor(s): Sergey Sharybin.
- *
- * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file BKE_subdiv.h
- *  \ingroup bke
- *  \since July 2018
- *  \author Sergey Sharybin
+/** \file
+ * \ingroup bke
  */
 
 #ifndef __BKE_SUBDIV_H__
@@ -79,6 +71,7 @@ typedef enum eSubdivStatsValue {
        SUBDIV_STATS_EVALUATOR_REFINE,
        SUBDIV_STATS_SUBDIV_TO_CCG,
        SUBDIV_STATS_SUBDIV_TO_CCG_ELEMENTS,
+       SUBDIV_STATS_TOPOLOGY_COMPARE,
 
        NUM_SUBDIV_STATS_VALUES,
 } eSubdivStatsValue;
@@ -88,8 +81,7 @@ typedef struct SubdivStats {
                struct {
                        /* Time spend on creating topology refiner, which includes time
                         * spend on conversion from Blender data to OpenSubdiv data, and
-                        * time spend on topology orientation on OpenSubdiv C-API side.
-                        */
+                        * time spend on topology orientation on OpenSubdiv C-API side. */
                        double topology_refiner_creation_time;
                        /* Total time spent in BKE_subdiv_to_mesh(). */
                        double subdiv_to_mesh_time;
@@ -103,18 +95,26 @@ typedef struct SubdivStats {
                        double subdiv_to_ccg_time;
                        /* Time spent on CCG elements evaluation/initialization. */
                        double subdiv_to_ccg_elements_time;
+                       /* Time spent on CCG elements evaluation/initialization. */
+                       double topology_compare_time;
                };
                double values_[NUM_SUBDIV_STATS_VALUES];
        };
 
        /* Per-value timestamp on when corresponding BKE_subdiv_stats_begin() was
-        * called.
-        */
+        * called. */
        double begin_timestamp_[NUM_SUBDIV_STATS_VALUES];
 } SubdivStats;
 
 /* Functor which evaluates dispalcement at a given (u, v) of given ptex face. */
 typedef struct SubdivDisplacement {
+       /* Initialize displacement evaluator.
+        *
+        * Is called right before evaluation is actually needed. This allows to do
+        * some lazy initialization, like allocate evaluator from a main thread but
+        * then do actual evaluation from background job. */
+       void (*initialize)(struct SubdivDisplacement *displacement);
+
        /* Return displacement which is to be added to the original coordinate.
         *
         * NOTE: This function is supposed to return "continuous" displacement for
@@ -124,8 +124,7 @@ typedef struct SubdivDisplacement {
         * displacement grids if needed.
         *
         * Averaging of displacement for vertices created for over coarse vertices
-        * and edges is done by subdiv code.
-        */
+        * and edges is done by subdiv code. */
        void (*eval_displacement)(struct SubdivDisplacement *displacement,
                                  const int ptex_face_index,
                                  const float u, const float v,
@@ -142,8 +141,7 @@ typedef struct SubdivDisplacement {
  * It does not specify storage, memory layout or anything else.
  * It is possible to create different storages (like, grid based CPU side
  * buffers, GPU subdivision mesh, CPU side fully qualified mesh) from the same
- * Subdiv structure.
- */
+ * Subdiv structure. */
 typedef struct Subdiv {
        /* Settings this subdivision surface is created for.
         *
@@ -152,8 +150,7 @@ typedef struct Subdiv {
        SubdivSettings settings;
        /* Topology refiner includes all the glue logic to feed Blender side
         * topology to OpenSubdiv. It can be shared by both evaluator and GL mesh
-        * drawer.
-        */
+        * drawer. */
        struct OpenSubdiv_TopologyRefiner *topology_refiner;
        /* CPU side evaluator. */
        struct OpenSubdiv_Evaluator *evaluator;
@@ -165,13 +162,12 @@ typedef struct Subdiv {
        /* Cached values, are not supposed to be accessed directly. */
        struct {
                /* Indexed by base face index, element indicates total number of ptex
-                *faces created for preceding base faces.
-                */
+                *faces created for preceding base faces. */
                int *face_ptex_offset;
        } cache_;
 } Subdiv;
 
-/* ================================ HELPERS ================================= */
+/* ========================== CONVERSION HELPERS ============================ */
 
 /* NOTE: uv_smooth is eSubsurfUVSmooth. */
 eSubdivFVarLinearInterpolation
@@ -184,15 +180,43 @@ void BKE_subdiv_stats_init(SubdivStats *stats);
 void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value);
 void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value);
 
+void BKE_subdiv_stats_reset(SubdivStats *stats, eSubdivStatsValue value);
+
 void BKE_subdiv_stats_print(const SubdivStats *stats);
 
+/* ================================ SETTINGS ================================ */
+
+void BKE_subdiv_settings_validate_for_mesh(SubdivSettings *settings,
+                                           const struct Mesh *mesh);
+
+bool BKE_subdiv_settings_equal(const SubdivSettings *settings_a,
+                               const SubdivSettings *settings_b);
+
 /* ============================== CONSTRUCTION ============================== */
 
+/* Construct new subdivision surface descriptor, from scratch, using given
+ * settings and topology. */
 Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
                                       struct OpenSubdiv_Converter *converter);
-
 Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings,
-                                 struct Mesh *mesh);
+                                 const struct Mesh *mesh);
+
+/* Similar to above, but will not re-create descriptor if it was created for the
+ * same settings and topology.
+ * If settings or topology did change, the existing descriptor is freed and a
+ * new one is created from scratch.
+ *
+ * NOTE: It is allowed to pass NULL as an existing subdivision surface
+ * descriptor. This will create enw descriptor without any extra checks.
+ */
+Subdiv *BKE_subdiv_update_from_converter(
+        Subdiv *subdiv,
+        const SubdivSettings *settings,
+        struct OpenSubdiv_Converter *converter);
+Subdiv *BKE_subdiv_update_from_mesh(
+        Subdiv *subdiv,
+        const SubdivSettings *settings,
+        const struct Mesh *mesh);
 
 void BKE_subdiv_free(Subdiv *subdiv);
 
@@ -200,7 +224,7 @@ void BKE_subdiv_free(Subdiv *subdiv);
 
 void BKE_subdiv_displacement_attach_from_multires(
         Subdiv *subdiv,
-        const struct Mesh *mesh,
+        struct Mesh *mesh,
         const struct MultiresModifierData *mmd);
 
 void BKE_subdiv_displacement_detach(Subdiv *subdiv);
@@ -209,15 +233,19 @@ void BKE_subdiv_displacement_detach(Subdiv *subdiv);
 
 int *BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv);
 
-/* ============================= VARIOUS HELPERS ============================ */
+/* =========================== PTEX FACES AND GRIDS ========================= */
 
 /* For a given (ptex_u, ptex_v) within a ptex face get corresponding
- * (grid_u, grid_v) within a grid.
- */
+ * (grid_u, grid_v) within a grid. */
 BLI_INLINE void BKE_subdiv_ptex_face_uv_to_grid_uv(
         const float ptex_u, const float ptex_v,
         float *r_grid_u, float *r_grid_v);
 
+/* Onverse of above. */
+BLI_INLINE void BKE_subdiv_grid_uv_to_ptex_face_uv(
+        const float grid_u, const float grid_v,
+        float *r_ptex_u, float *r_ptex_v);
+
 /* For a given subdivision level (which is NOT refinement level) get size of
  * CCG grid (number of grid points on a side).
  */
@@ -226,12 +254,18 @@ BLI_INLINE int BKE_subdiv_grid_size_from_level(const int level);
 /* Simplified version of mdisp_rot_face_to_crn, only handles quad and
  * works in normalized coordinates.
  *
- * NOTE: Output coordinates are in ptex coordinates.
- */
+ * NOTE: Output coordinates are in ptex coordinates. */
 BLI_INLINE int BKE_subdiv_rotate_quad_to_corner(
-        const float u, const float v,
-        float *r_u, float *r_v);
+        const float quad_u, const float quad_v,
+        float *r_corner_u, float *r_corner_v);
 
-#endif  /* __BKE_SUBDIV_H__ */
+/* Converts (u, v) coordinate from within a grid to a quad coordinate in
+ * normalized ptex coordinates. */
+BLI_INLINE void BKE_subdiv_rotate_grid_to_quad(
+        const int corner,
+        const float grid_u, const float grid_v,
+        float *r_quad_u, float *r_quad_v);
 
 #include "intern/subdiv_inline.h"
+
+#endif  /* __BKE_SUBDIV_H__ */