@@ -104,8 +104,10 @@ CollisionMesh::CollisionMesh(
104104
105105 m_faces_to_edges = construct_faces_to_edges (m_faces, m_edges);
106106
107- init_adjacencies ();
108107 init_areas ();
108+ // Compute these manually if needed.
109+ // init_adjacencies();
110+ // init_area_jacobian();
109111}
110112
111113// /////////////////////////////////////////////////////////////////////////////
@@ -203,66 +205,40 @@ void CollisionMesh::init_areas()
203205 // Compute vertex areas as the sum of ½ the length of connected edges
204206 Eigen::VectorXd vertex_edge_areas =
205207 Eigen::VectorXd::Constant (num_vertices (), -1 );
206- m_vertex_area_jacobian.resize (
207- num_vertices (), Eigen::SparseVector<double >(ndof ()));
208208 for (int i = 0 ; i < m_edges.rows (); i++) {
209209 const auto & e0 = m_vertices_at_rest.row (m_edges (i, 0 ));
210210 const auto & e1 = m_vertices_at_rest.row (m_edges (i, 1 ));
211211 double edge_len = (e1 - e0 ).norm ();
212212
213- VectorMax6d edge_len_gradient;
214- edge_length_gradient (e0 , e1 , edge_len_gradient);
215-
216213 for (int j = 0 ; j < m_edges.cols (); j++) {
217214 if (vertex_edge_areas[m_edges (i, j)] < 0 ) {
218215 vertex_edge_areas[m_edges (i, j)] = 0 ;
219216 }
220217 vertex_edge_areas[m_edges (i, j)] += edge_len / 2 ;
221-
222- local_gradient_to_global_gradient (
223- edge_len_gradient / 2 , m_edges.row (i), dim (),
224- m_vertex_area_jacobian[m_edges (i, j)]);
225218 }
226219 }
227220
228221 // Compute vertex/edge areas as the sum of ⅓ the area of connected face
229222 Eigen::VectorXd vertex_face_areas =
230223 Eigen::VectorXd::Constant (num_vertices (), -1 );
231224 m_edge_areas.setConstant (m_edges.rows (), -1 );
232- m_edge_area_jacobian.resize (
233- m_edges.rows (), Eigen::SparseVector<double >(ndof ()));
234225 if (dim () == 3 ) {
235226 for (int i = 0 ; i < m_faces.rows (); i++) {
236227 const auto & f0 = m_vertices_at_rest.row (m_faces (i, 0 ));
237228 const auto & f1 = m_vertices_at_rest.row (m_faces (i, 1 ));
238229 const auto & f2 = m_vertices_at_rest.row (m_faces (i, 2 ));
239230 double face_area = cross (f1 - f0, f2 - f0).norm () / 2 ;
240231
241- VectorMax9d face_area_gradient;
242- triangle_area_gradient (f0, f1, f2, face_area_gradient);
243-
244232 for (int j = 0 ; j < m_faces.cols (); ++j) {
245233 if (vertex_face_areas[m_faces (i, j)] < 0 ) {
246234 vertex_face_areas[m_faces (i, j)] = 0 ;
247- // remove the computed value from vertex_edge_areas
248- m_vertex_area_jacobian[m_faces (i, j)].setZero ();
249235 }
250236 vertex_face_areas[m_faces (i, j)] += face_area / 3 ;
251237
252238 if (m_edge_areas[m_faces_to_edges (i, j)] < 0 ) {
253239 m_edge_areas[m_faces_to_edges (i, j)] = 0 ;
254240 }
255241 m_edge_areas[m_faces_to_edges (i, j)] += face_area / 3 ;
256-
257- // compute gradient of area
258-
259- local_gradient_to_global_gradient (
260- face_area_gradient / 3 , m_faces.row (i), dim (),
261- m_vertex_area_jacobian[m_faces (i, j)]);
262-
263- local_gradient_to_global_gradient (
264- face_area_gradient / 3 , m_faces.row (i), dim (),
265- m_edge_area_jacobian[m_faces_to_edges (i, j)]);
266242 }
267243 }
268244 }
@@ -278,6 +254,59 @@ void CollisionMesh::init_areas()
278254 m_edge_areas = (m_edge_areas.array () < 0 ).select (1 , m_edge_areas);
279255}
280256
257+ void CollisionMesh::init_area_jacobians ()
258+ {
259+ // Compute vertex areas as the sum of ½ the length of connected edges
260+ m_vertex_area_jacobian.resize (
261+ num_vertices (), Eigen::SparseVector<double >(ndof ()));
262+ for (int i = 0 ; i < m_edges.rows (); i++) {
263+ const auto & e0 = m_vertices_at_rest.row (m_edges (i, 0 ));
264+ const auto & e1 = m_vertices_at_rest.row (m_edges (i, 1 ));
265+
266+ VectorMax6d edge_len_gradient;
267+ edge_length_gradient (e0 , e1 , edge_len_gradient);
268+
269+ for (int j = 0 ; j < m_edges.cols (); j++) {
270+ local_gradient_to_global_gradient (
271+ edge_len_gradient / 2 , m_edges.row (i), dim (),
272+ m_vertex_area_jacobian[m_edges (i, j)]);
273+ }
274+ }
275+
276+ // Compute vertex/edge areas as the sum of ⅓ the area of connected face
277+ m_edge_area_jacobian.resize (
278+ m_edges.rows (), Eigen::SparseVector<double >(ndof ()));
279+ if (dim () == 3 ) {
280+ std::vector<bool > visited_vertex_before (num_vertices (), false );
281+ for (int i = 0 ; i < m_faces.rows (); i++) {
282+ const auto & f0 = m_vertices_at_rest.row (m_faces (i, 0 ));
283+ const auto & f1 = m_vertices_at_rest.row (m_faces (i, 1 ));
284+ const auto & f2 = m_vertices_at_rest.row (m_faces (i, 2 ));
285+
286+ VectorMax9d face_area_gradient;
287+ triangle_area_gradient (f0, f1, f2, face_area_gradient);
288+
289+ for (int j = 0 ; j < m_faces.cols (); ++j) {
290+ if (!visited_vertex_before[m_faces (i, j)]) {
291+ // remove the computed value from vertex_edge_areas
292+ m_vertex_area_jacobian[m_faces (i, j)].setZero ();
293+ visited_vertex_before[m_faces (i, j)] = true ;
294+ }
295+
296+ // compute gradient of area
297+
298+ local_gradient_to_global_gradient (
299+ face_area_gradient / 3 , m_faces.row (i), dim (),
300+ m_vertex_area_jacobian[m_faces (i, j)]);
301+
302+ local_gradient_to_global_gradient (
303+ face_area_gradient / 3 , m_faces.row (i), dim (),
304+ m_edge_area_jacobian[m_faces_to_edges (i, j)]);
305+ }
306+ }
307+ }
308+ }
309+
281310// //////////////////////////////////////////////////////////////////////////////
282311
283312Eigen::MatrixXd
0 commit comments