3 #include <sofa/version.h>
4 #include <sofa/core/objectmodel/BaseObject.h>
5 #include <sofa/defaulttype/Vec.h>
6 #include <sofa/defaulttype/VecTypes.h>
7 #include <sofa/core/topology/BaseMeshTopology.h>
9 #include <Caribou/Geometry/RectangularQuad.h>
10 #include <Caribou/Geometry/RectangularHexahedron.h>
11 #include <Caribou/Topology/Grid/Grid.h>
12 #include <Caribou/config.h>
14 #include <SofaCaribou/Topology/IsoSurface.h>
22 #if (defined(SOFA_VERSION) && SOFA_VERSION < 201299)
23 namespace sofa {
using Index =
unsigned int; }
26 namespace SofaCaribou::topology {
28 using namespace sofa::core::objectmodel;
30 using sofa::defaulttype::Vec2Types;
31 using sofa::defaulttype::Vec3Types;
33 template <
typename DataTypes>
40 static constexpr
unsigned char Dimension = DataTypes::spatial_dimensions;
45 using Index = std::size_t;
46 using Int = INTEGER_TYPE;
47 using Float = FLOATING_POINT_TYPE;
52 using SofaFloat =
typename DataTypes::Real;
53 using SofaVecInt = sofa::defaulttype::Vec<Dimension, UNSIGNED_INTEGER_TYPE>;
54 using SofaVecFloat = sofa::defaulttype::Vec<Dimension, SofaFloat>;
55 using Coord =
typename DataTypes::Coord;
56 using SofaVecCoord = sofa::helper::vector<Coord>;
57 using ElementId = sofa::Index;
58 using VecElementId = sofa::helper::vector<ElementId>;
59 using SofaHexahedron = sofa::core::topology::BaseMeshTopology::Hexahedron;
60 using SofaQuad = sofa::core::topology::BaseMeshTopology::Quad;
61 using SofaTriangle = sofa::core::topology::BaseMeshTopology::Triangle;
62 using SofaEdge = sofa::core::topology::BaseMeshTopology::Edge;
68 using NodeIndex =
typename GridType::NodeIndex;
69 using CellIndex =
typename GridType::CellIndex;
70 using Dimensions =
typename GridType::Dimensions;
71 using Subdivisions =
typename GridType::Subdivisions;
72 using LocalCoordinates =
typename GridType::LocalCoordinates;
73 using WorldCoordinates =
typename GridType::WorldCoordinates;
74 using GridCoordinates =
typename GridType::GridCoordinates;
75 using CellSet =
typename GridType::CellSet;
76 using CellElement =
typename GridType::Element;
81 enum class Type : INTEGER_TYPE {
82 Undefined = std::numeric_limits<INTEGER_TYPE>::lowest(),
83 Inside = (unsigned) 1 << (
unsigned) 0,
84 Outside = (unsigned) 1 << (
unsigned) 1,
85 Boundary = (unsigned) 1 << (
unsigned) 2
90 CellData(
const Type & t,
const Float& w,
const int & r,
const bool &b)
91 : type(t), weight(w), region_id(r), boundary_of_region(b) {}
92 Type type = Type::Undefined;
95 bool boundary_of_region =
false;
100 Cell * parent =
nullptr;
102 std::unique_ptr<CellData> data;
103 std::unique_ptr<std::array<
Cell,(unsigned) 1 << Dimension>> childs;
105 inline bool is_leaf()
const {
return childs.get() ==
nullptr;}
111 Type type = Type::Undefined;
112 std::vector<Cell*> cells;
119 template <
typename ObjectType>
120 using Link = SingleLink<FictitiousGrid<DataTypes>, ObjectType, BaseLink::FLAG_STRONGLINK>;
132 inline UNSIGNED_INTEGER_TYPE
134 return p_cell_index_in_grid.size();
138 inline UNSIGNED_INTEGER_TYPE
140 return p_node_index_in_grid.size();
144 inline UNSIGNED_INTEGER_TYPE
146 return d_number_of_subdivision.getValue();
154 get_neighbors(
const Cell * cell)
const;
162 get_neighbors(
const Cell * cell, UNSIGNED_INTEGER_TYPE axis, INTEGER_TYPE direction)
const;
171 std::vector<std::pair<LocalCoordinates, FLOATING_POINT_TYPE>>
172 get_gauss_nodes_of_cell(
const CellIndex & sparse_cell_index)
const;
185 std::vector<std::pair<LocalCoordinates, FLOATING_POINT_TYPE>>
186 get_gauss_nodes_of_cell(
const CellIndex & sparse_cell_index,
const UNSIGNED_INTEGER_TYPE level)
const;
193 const auto cell_index = p_cell_index_in_grid[sparse_cell_index];
194 return std::move(p_grid->cell_at(cell_index));
200 inline const SofaHexahedron &
202 return d_hexahedrons.getValue().at(sparse_cell_index);
209 get_type_at(
const WorldCoordinates & p)
const;
229 inline std::map<FLOATING_POINT_TYPE, std::vector<CellIndex>>
230 cell_volume_ratio_distribution(UNSIGNED_INTEGER_TYPE number_of_decimals=0)
const;
236 void init()
override;
237 void draw(
const sofa::core::visual::VisualParams* vparams)
override;
239 void computeBBox(
const sofa::core::ExecParams*,
bool onlyVisible)
override {
243 if (Dimension == 2) {
244 const Float min[3] = {
245 d_min.getValue()[0], d_min.getValue()[1], -1
247 const Float max[3] = {
248 d_max.getValue()[0], d_max.getValue()[1], +1
250 this->f_bbox.setValue(sofa::defaulttype::TBoundingBox<Float>(min, max));
252 this->f_bbox.setValue(sofa::defaulttype::TBoundingBox<Float>(
253 d_min.getValue().array(),d_max.getValue().array()));
257 std::string getTemplateName()
const override {
258 return templateName(
this);
261 static std::string templateName(
const FictitiousGrid<DataTypes>* =
nullptr) {
262 return DataTypes::Name();
266 virtual void tag_intersected_cells_from_implicit_surface();
267 virtual void tag_intersected_cells();
268 virtual void tag_outside_cells();
269 virtual void tag_inside_cells();
270 virtual void subdivide_intersected_cells();
271 virtual void create_regions_from_same_type_cells();
272 virtual void create_sparse_grid();
273 virtual void populate_drawing_vectors();
274 virtual void validate_grid();
276 std::array<CellElement, (unsigned) 1 << Dimension> get_subcells_elements(
const CellElement & e)
const;
277 std::vector<Cell *> get_leaf_cells(
const Cell & c)
const {
return std::move(get_leaf_cells(&c));}
278 std::vector<Cell *> get_leaf_cells(
const Cell * c)
const;
279 inline FLOATING_POINT_TYPE get_cell_weight(
const Cell & c)
const;
285 Data<SofaVecInt> d_n;
286 Data<SofaVecFloat> d_min;
287 Data<SofaVecFloat> d_max;
288 Data<UNSIGNED_INTEGER_TYPE> d_number_of_subdivision;
289 Data<Float> d_volume_threshold;
290 Link<IsoSurface<DataTypes>> d_iso_surface;
291 Data<bool> d_draw_boundary_cells;
292 Data<bool> d_draw_outside_cells;
293 Data<bool> d_draw_inside_cells;
294 Data<double> d_draw_scale;
296 Data< SofaVecCoord > d_surface_positions;
299 Data<sofa::helper::vector<SofaEdge> > d_surface_edges;
302 Data<sofa::helper::vector<SofaTriangle> > d_surface_triangles;
308 Data< SofaVecCoord > d_positions;
311 Data < sofa::helper::vector<SofaQuad> > d_quads;
314 Data < sofa::helper::vector<SofaHexahedron> > d_hexahedrons;
322 std::unique_ptr<GridType> p_grid;
325 std::vector<Type> p_cells_types;
328 std::vector<std::vector<Index>> p_triangles_of_cell;
331 std::vector<Cell> p_cells;
334 std::vector<Region> p_regions;
338 std::vector<INTEGER_TYPE> p_node_index_in_sparse_grid;
341 std::vector<UNSIGNED_INTEGER_TYPE> p_node_index_in_grid;
345 std::vector<INTEGER_TYPE> p_cell_index_in_sparse_grid;
348 std::vector<UNSIGNED_INTEGER_TYPE> p_cell_index_in_grid;
351 std::vector<sofa::defaulttype::Vector3> p_drawing_nodes_vector;
354 std::vector<sofa::defaulttype::Vector3> p_drawing_edges_vector;
357 std::vector<std::vector<sofa::defaulttype::Vector3>> p_drawing_subdivided_edges_vector;
360 std::vector<std::vector<sofa::defaulttype::Vector3>> p_drawing_cells_vector;
366 static const GridCoordinates subcell_coordinates[(unsigned) 1 << Dimension];
370 template<>
const FictitiousGrid<Vec2Types>::GridCoordinates FictitiousGrid<Vec2Types>::subcell_coordinates[4];
371 template<>
const FictitiousGrid<Vec3Types>::GridCoordinates FictitiousGrid<Vec3Types>::subcell_coordinates[8];
373 template<>
void FictitiousGrid<Vec2Types>::tag_intersected_cells ();
374 template<>
void FictitiousGrid<Vec3Types>::tag_intersected_cells ();
376 template<>
void FictitiousGrid<Vec2Types>::subdivide_intersected_cells ();
377 template<>
void FictitiousGrid<Vec3Types>::subdivide_intersected_cells ();
379 extern template class FictitiousGrid<Vec2Types>;
380 extern template class FictitiousGrid<Vec3Types>;