Skip to content

Commit efda0c1

Browse files
authored
Merge branch 'master' into 202601_lifecycle_attribute_disabled_1
2 parents 38e0723 + fd4087f commit efda0c1

17 files changed

Lines changed: 304 additions & 75 deletions

File tree

CMakePresets.json

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,6 @@
168168
"type": "BOOL",
169169
"value": "ON"
170170
},
171-
"SOFA_FETCH_SOFAVISCOELASTIC": {
172-
"type": "BOOL",
173-
"value": "ON"
174-
},
175-
"PLUGIN_SOFAVISCOELASTIC": {
176-
"type": "BOOL",
177-
"value": "ON"
178-
},
179171
"PLUGIN_SOFAMATRIX": {
180172
"type": "BOOL",
181173
"value": "ON"
@@ -220,14 +212,6 @@
220212
"type": "BOOL",
221213
"value": "ON"
222214
},
223-
"SOFA_FETCH_CGALPLUGIN": {
224-
"type": "BOOL",
225-
"value": "ON"
226-
},
227-
"PLUGIN_CGALPLUGIN": {
228-
"type": "BOOL",
229-
"value": "ON"
230-
},
231215
"SOFA_FETCH_SOFA_METIS": {
232216
"type": "BOOL",
233217
"value": "ON"

Sofa/Component/Mass/src/sofa/component/mass/DiagonalMass.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public :
5454
* @class DiagonalMass
5555
* @brief This component computes the integral of this mass density over the volume of the object geometry but it supposes that the Mass matrix is diagonal.
5656
* @remark Similar to MeshMatrixMass but it does not simplify the Mass Matrix as diagonal.
57-
* @remark https://www.sofa-framework.org/community/doc/components/masses/diagonalmass/
5857
* @tparam DataTypes type of the state associated with this mass
5958
* @tparam GeometricalTypes type of the geometry, i.e type of the state associated with the topology (if the topology and the mass relates to the same state, this will be the same as DataTypes)
6059
*/

Sofa/Component/Mass/src/sofa/component/mass/MeshMatrixMass.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ template <class DataTypes, class TMassType>
5757
* @class MeshMatrixMass
5858
* @brief This component computes the integral of this mass density over the volume of the object geometry.
5959
* @remark Similar to DiagonalMass which simplifies the Mass Matrix as diagonal.
60-
* @remark https://www.sofa-framework.org/community/doc/components/masses/meshmatrixmass/
6160
* @tparam DataTypes type of the state associated to this mass
6261
* @tparam GeometricalTypes type of the geometry, i.e type of the state associated with the topology (if the topology and the mass relates to the same state, this will be the same as DataTypes)
6362
*/

Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,28 +259,26 @@ void HexahedronFEMForceField<DataTypes>::addDForce (const core::MechanicalParams
259259
typename VecElement::const_iterator it;
260260

261261
const auto* indexedElements = this->getIndexedElements();
262+
const auto& elementStiffnesses = d_elementStiffnesses.getValue();
262263

263264
for(it = indexedElements->begin() ; it != indexedElements->end() ; ++it, ++i)
264265
{
265-
// Transformation R_0_2;
266-
// R_0_2.transpose(_rotations[i]);
267266

268-
Displacement X;
267+
Displacement X(sofa::type::NOINIT);
269268

270-
for(int w=0; w<8; ++w)
269+
for (int w = 0; w < 8; ++w)
271270
{
272-
Coord x_2;
273-
x_2 = _rotations[i] * _dx[(*it)[w]];
271+
const Coord x_2 = _rotations[i] * _dx[(*it)[w]];
274272

275273
X[w*3] = x_2[0];
276274
X[w*3+1] = x_2[1];
277275
X[w*3+2] = x_2[2];
278276
}
279277

280-
Displacement F;
281-
computeForce(F, X, d_elementStiffnesses.getValue()[i] );
278+
Displacement F(sofa::type::NOINIT);
279+
computeForce(F, X, elementStiffnesses[i] );
282280

283-
for(int w=0; w<8; ++w)
281+
for (int w = 0; w < 8; ++w)
284282
{
285283
_df[(*it)[w]] -= _rotations[i].multTranspose(Deriv(F[w*3], F[w*3+1], F[w*3+2])) * kFactor;
286284
}

Sofa/GL/src/sofa/gl/VideoRecorderFFMPEG.cpp

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,23 @@ bool VideoRecorderFFMPEG::init(const std::string& ffmpeg_exec_filepath, const st
8787
m_ffmpegBuffer = new unsigned char [m_ffmpegBufferSize];
8888

8989
m_FrameCount = 0;
90-
90+
std::string extension;
91+
#ifdef WIN32
92+
extension = ".exe";
93+
#endif
9194
m_ffmpegExecPath = ffmpeg_exec_filepath;
9295
if(m_ffmpegExecPath.empty())
9396
{
94-
std::string extension;
95-
#ifdef WIN32
96-
extension = ".exe";
97-
#endif
9897
m_ffmpegExecPath = helper::Utils::getExecutablePath() + "/ffmpeg" + extension;
99-
if(!FileSystem::isFile(m_ffmpegExecPath))
100-
{
101-
// Fallback to a relative FFMPEG (may be in system or exposed in PATH)
102-
m_ffmpegExecPath = "ffmpeg" + extension;
103-
}
98+
}
99+
if(!FileSystem::isFile(m_ffmpegExecPath, true))
100+
{
101+
msg_warning("VideoRecorderFFMPEG")<< "ffmpeg hasn't been found automatically. Falling back to simply calling ffmpeg"<< extension <<" and hope that the OS finds it on its own. " ;
102+
// Fallback to a relative FFMPEG (may be in system or exposed in PATH)
103+
m_ffmpegExecPath = "ffmpeg" + extension;
104104
}
105105

106+
106107
std::stringstream ss;
107108
ss << m_ffmpegExecPath
108109
<< " -r " << m_framerate
@@ -122,6 +123,7 @@ bool VideoRecorderFFMPEG::init(const std::string& ffmpeg_exec_filepath, const st
122123
#else
123124
m_ffmpeg = popen(command_line.c_str(), "w");
124125
#endif
126+
125127
if (m_ffmpeg == nullptr) {
126128
msg_error("VideoRecorderFFMPEG") << "ffmpeg process failed to open (error " << errno << "). Command line : " << command_line;
127129
return false;
@@ -138,31 +140,38 @@ void VideoRecorderFFMPEG::addFrame()
138140
{
139141
GLint viewport[4];
140142
glGetIntegerv(GL_VIEWPORT, viewport);
141-
143+
142144
if ((viewport[2] != m_viewportWidth) || (viewport[3] != m_viewportHeight))
143145
{
144146
std::cout << "WARNING viewport changed during video capture from " << m_viewportWidth << "x" << m_viewportHeight << " to " << viewport[2] << "x" << viewport[3] << std::endl;
145147
}
146148

149+
glReadPixels(viewport[0], viewport[1], m_viewportWidth, m_viewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_viewportBuffer);
150+
151+
addFrame(m_viewportBuffer, m_viewportWidth, m_viewportHeight);
152+
}
147153

148-
glReadPixels(0, 0, m_viewportWidth, m_viewportHeight, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_viewportBuffer);
149154

150-
// set ffmpeg buffer: initialize to 0 (black)
155+
156+
void VideoRecorderFFMPEG::addFrame(unsigned char* rgbData, int fbWidth, int fbHeight)
157+
{
158+
159+
// set ffmpeg buffer: initialize to 0 (black)
151160
memset(m_ffmpegBuffer, 0, m_ffmpegBufferSize);
152161

153-
if (m_viewportWidth == m_ffmpegWidth)
162+
if (fbWidth == m_ffmpegWidth)
154163
{
155-
memcpy(m_ffmpegBuffer, m_viewportBuffer, m_viewportBufferSize);
164+
memcpy(m_ffmpegBuffer, rgbData, fbHeight * fbWidth * m_pixelFormatSize);
156165
}
157166
else
158167
{
159-
const unsigned char* viewportBufferIter = m_viewportBuffer;
160-
const size_t viewportRowSizeInBytes = m_pixelFormatSize * m_viewportWidth;
168+
const unsigned char* viewportBufferIter = rgbData;
169+
const size_t viewportRowSizeInBytes = m_pixelFormatSize * fbWidth;
161170

162171
unsigned char* ffmpegBufferIter = m_ffmpegBuffer;
163172
const size_t ffmpegRowSizeInBytes = m_pixelFormatSize * m_ffmpegWidth;
164173

165-
int row = m_viewportHeight;
174+
int row = fbHeight;
166175
while ( row-- > 0 )
167176
{
168177
memcpy( ffmpegBufferIter, viewportBufferIter, viewportRowSizeInBytes);
@@ -174,8 +183,6 @@ void VideoRecorderFFMPEG::addFrame()
174183

175184

176185
fwrite(m_ffmpegBuffer, m_ffmpegBufferSize, 1, m_ffmpeg);
177-
178-
return;
179186
}
180187

181188
void VideoRecorderFFMPEG::finishVideo()

Sofa/GL/src/sofa/gl/VideoRecorderFFMPEG.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,14 @@ class SOFA_GL_API VideoRecorderFFMPEG
6262
bool init(const std::string& ffmpeg_exec_filepath, const std::string& filename, int width, int height, unsigned int framerate, unsigned int bitrate, const std::string& codec="");
6363

6464
void addFrame();
65+
void addFrame(unsigned char* rgbData, int fbWidth, int fbHeight);
6566
void saveVideo();
6667
void finishVideo();
6768

69+
int getPixelFormatSize()
70+
{
71+
return m_pixelFormatSize;
72+
};
6873

6974
void setPrefix(const std::string v) { m_prefix = v; }
7075

Sofa/framework/Core/src/sofa/core/ObjectFactory.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,14 @@ objectmodel::BaseObject::SPtr ObjectFactory::createObject(objectmodel::BaseConte
279279
possibleNames.emplace_back(k.first);
280280
}
281281

282-
arg->logError("But the following object(s) exist:");
283-
for(auto& [name, score] : sofa::helper::getClosestMatch(classname, possibleNames, 5, 0.6))
282+
const auto closestMatches = sofa::helper::getClosestMatch(classname, possibleNames, 5, 0.6);
283+
if (!closestMatches.empty())
284284
{
285-
arg->logError( " : " + name + " ("+ std::to_string((int)(100*score))+"% match)");
285+
arg->logError("But the following object(s) exist:");
286+
for(auto& [name, score] : closestMatches)
287+
{
288+
arg->logError( " : " + name + " ("+ std::to_string((int)(100*score))+"% match)");
289+
}
286290
}
287291
}
288292
}

Sofa/framework/Core/src/sofa/core/visual/DrawMesh.h

Lines changed: 136 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,58 @@ struct BaseDrawMesh
141141
template<class ElementType>
142142
struct DrawElementMesh{};
143143

144+
template<>
145+
struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Edge>
146+
: public BaseDrawMesh<DrawElementMesh<sofa::geometry::Edge>, 2>
147+
{
148+
using ElementType = sofa::geometry::Edge;
149+
friend BaseDrawMesh;
150+
static constexpr ColorContainer defaultColors {
151+
sofa::type::RGBAColor::lime(),
152+
sofa::type::RGBAColor::silver()
153+
};
154+
155+
private:
156+
template<class PositionContainer, class IndicesContainer>
157+
void doDraw(
158+
sofa::helper::visual::DrawTool* drawTool,
159+
const PositionContainer& position,
160+
sofa::core::topology::BaseMeshTopology* topology,
161+
const IndicesContainer& elementIndices,
162+
const ColorContainer& colors)
163+
{
164+
if (!topology)
165+
return;
166+
167+
const auto& elements = topology->getEdges();
168+
169+
const auto size = elementIndices.size() * sofa::geometry::Edge::NumberOfNodes;
170+
for ( auto& p : renderedPoints)
171+
{
172+
p.resize(size);
173+
}
174+
175+
std::array<std::size_t, NumberColors> renderedPointId {};
176+
for (auto i : elementIndices)
177+
{
178+
const auto& element = elements[i];
179+
180+
const auto center = this->elementCenter(position, element);
181+
182+
for (std::size_t j = 0; j < sofa::geometry::Edge::NumberOfNodes; ++j)
183+
{
184+
const auto p = this->applyElementSpace(position[element[j]], center);
185+
renderedPoints[i % NumberColors][renderedPointId[i%NumberColors]++] = sofa::type::toVec3(p);
186+
}
187+
}
188+
189+
for (std::size_t j = 0; j < NumberColors; ++j)
190+
{
191+
drawTool->drawLines(renderedPoints[j], 2.f, colors[j]);
192+
}
193+
}
194+
};
195+
144196
template<>
145197
struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Triangle>
146198
: public BaseDrawMesh<DrawElementMesh<sofa::geometry::Triangle>, 3>
@@ -194,6 +246,59 @@ struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Triangle>
194246
}
195247
};
196248

249+
250+
template<>
251+
struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Quad>
252+
: public BaseDrawMesh<DrawElementMesh<sofa::geometry::Quad>, 2>
253+
{
254+
using ElementType = sofa::geometry::Quad;
255+
friend BaseDrawMesh;
256+
static constexpr ColorContainer defaultColors {
257+
sofa::type::RGBAColor::green(),
258+
sofa::type::RGBAColor::orange()
259+
};
260+
261+
private:
262+
template<class PositionContainer, class IndicesContainer>
263+
void doDraw(
264+
sofa::helper::visual::DrawTool* drawTool,
265+
const PositionContainer& position,
266+
sofa::core::topology::BaseMeshTopology* topology,
267+
const IndicesContainer& elementIndices,
268+
const ColorContainer& colors)
269+
{
270+
if (!topology)
271+
return;
272+
273+
const auto& elements = topology->getQuads();
274+
275+
const auto size = elementIndices.size() * sofa::geometry::Quad::NumberOfNodes;
276+
for ( auto& p : renderedPoints)
277+
{
278+
p.resize(size);
279+
}
280+
281+
std::array<std::size_t, NumberColors> renderedPointId {};
282+
for (auto i : elementIndices)
283+
{
284+
const auto& element = elements[i];
285+
286+
const auto center = this->elementCenter(position, element);
287+
288+
for (std::size_t j = 0; j < sofa::geometry::Quad::NumberOfNodes; ++j)
289+
{
290+
const auto p = this->applyElementSpace(position[element[j]], center);
291+
renderedPoints[i % NumberColors][renderedPointId[i%NumberColors]++] = sofa::type::toVec3(p);
292+
}
293+
}
294+
295+
for (std::size_t j = 0; j < NumberColors; ++j)
296+
{
297+
drawTool->drawQuads(renderedPoints[j], colors[j]);
298+
}
299+
}
300+
};
301+
197302
template<>
198303
struct SOFA_CORE_API DrawElementMesh<sofa::geometry::Tetrahedron>
199304
: public BaseDrawMesh<DrawElementMesh<sofa::geometry::Tetrahedron>, 4>
@@ -338,10 +443,17 @@ class SOFA_CORE_API DrawMesh
338443

339444
void setElementSpace(SReal elementSpace);
340445

446+
template<class PositionContainer>
447+
void drawLine(sofa::helper::visual::DrawTool* drawTool, const PositionContainer& position, sofa::core::topology::BaseMeshTopology* topology)
448+
{
449+
drawElements<sofa::geometry::Edge>(drawTool, position, topology);
450+
}
451+
341452
template<class PositionContainer>
342453
void drawSurface(sofa::helper::visual::DrawTool* drawTool, const PositionContainer& position, sofa::core::topology::BaseMeshTopology* topology)
343454
{
344455
drawElements<sofa::geometry::Triangle>(drawTool, position, topology);
456+
drawElements<sofa::geometry::Quad>(drawTool, position, topology);
345457
}
346458

347459
template<class PositionContainer>
@@ -359,19 +471,38 @@ class SOFA_CORE_API DrawMesh
359471
return;
360472
}
361473

362-
const auto hasTetra = topology && !topology->getTetrahedra().empty();
363-
const auto hasHexa = topology && !topology->getHexahedra().empty();
474+
const auto hasTriangles = !topology->getTriangles().empty();
475+
const auto hasQuads = !topology->getQuads().empty();
476+
477+
const auto hasSurfaceElements = hasTriangles || hasQuads;
478+
479+
const auto hasTetra = !topology->getTetrahedra().empty();
480+
const auto hasHexa = !topology->getHexahedra().empty();
481+
482+
const bool hasVolumeElements = hasTetra || hasHexa;
364483

365-
if (!hasTetra && !hasHexa)
484+
if (!hasSurfaceElements && !hasVolumeElements)
366485
{
367-
drawSurface(drawTool, position, topology);
486+
drawLine(drawTool, position, topology);
487+
}
488+
else
489+
{
490+
if (!hasVolumeElements)
491+
{
492+
drawSurface(drawTool, position, topology);
493+
}
494+
else
495+
{
496+
drawVolume(drawTool, position, topology);
497+
}
368498
}
369-
drawVolume(drawTool, position, topology);
370499
}
371500

372501
private:
373502
std::tuple<
503+
DrawElementMesh<sofa::geometry::Edge>,
374504
DrawElementMesh<sofa::geometry::Triangle>,
505+
DrawElementMesh<sofa::geometry::Quad>,
375506
DrawElementMesh<sofa::geometry::Tetrahedron>,
376507
DrawElementMesh<sofa::geometry::Hexahedron>
377508
> m_meshes;

0 commit comments

Comments
 (0)