Skip to content

Commit f3645a4

Browse files
committed
- added implementation of "Position-Based Elastic Rods" paper and a corresponding demo
1 parent 934899f commit f3645a4

16 files changed

+1528
-4
lines changed

CMake/Common.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ set(CMAKE_MINSIZEREL_POSTFIX "_ms")
1111
if (WIN32)
1212
set(CMAKE_USE_RELATIVE_PATHS "1")
1313
# Set compiler flags for "release"
14-
set(CMAKE_CXX_FLAGS_RELEASE "/MD /EHsc /Ox /Ob2 /Oi /Ot /GL /D NDEBUG /openmp")
14+
set(CMAKE_CXX_FLAGS_RELEASE "/MD /EHsc /Ox /Ob2 /Oi /Ot /GL /D NDEBUG /openmp" CACHE STRING "Flags used by the compiler during release builds." FORCE)
15+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /EHsc" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
1516
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /LTCG")
1617
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /LTCG")
1718
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /LTCG")

Changelog.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
- added implementation of "Position-Based Elastic Rods" paper and a corresponding demo
2+
- fixed some problems with VS2015
3+
14
1.5.0
25
- added SceneGenerator.py to generate new scenarios easily by simple Python scripting
36
- added scene loader demo

Demos/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
include(Visualization/CMakeLists.txt)
22
add_definitions(-DPBD_DATA_PATH="../data")
33

4-
subdirs(Simulation BarDemo ClothDemo DistanceFieldDemos FluidDemo RigidBodyDemos CouplingDemos GenericConstraintsDemos SceneLoaderDemo)
4+
subdirs(Simulation BarDemo ClothDemo PositionBasedElasticRodsDemo DistanceFieldDemos FluidDemo RigidBodyDemos CouplingDemos GenericConstraintsDemos SceneLoaderDemo)
55

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
set(SIMULATION_LINK_LIBRARIES AntTweakBar glew PositionBasedDynamics Simulation)
2+
set(SIMULATION_DEPENDENCIES AntTweakBar glew PositionBasedDynamics Simulation)
3+
4+
if(WIN32)
5+
set(SIMULATION_LINK_LIBRARIES freeglut opengl32.lib glu32.lib ${SIMULATION_LINK_LIBRARIES})
6+
set(SIMULATION_DEPENDENCIES freeglut ${SIMULATION_DEPENDENCIES})
7+
else()
8+
find_package(GLUT REQUIRED)
9+
find_package(OpenGL REQUIRED)
10+
11+
set(SIMULATION_LINK_LIBRARIES
12+
${SIMULATION_LINK_LIBRARIES}
13+
${GLUT_LIBRARIES}
14+
${OPENGL_LIBRARIES}
15+
)
16+
endif()
17+
18+
add_executable(ElasticRodDemo
19+
PositionBasedElasticRodsDemo.cpp
20+
PositionBasedElasticRodsConstraints.cpp
21+
PositionBasedElasticRodsConstraints.h
22+
PositionBasedElasticRodsModel.cpp
23+
PositionBasedElasticRodsModel.h
24+
PositionBasedElasticRodsTSC.cpp
25+
PositionBasedElasticRodsTSC.h
26+
27+
${VIS_FILES}
28+
${PROJECT_PATH}/Common/Common.h
29+
${PROJECT_PATH}/Demos/Common/Config.h
30+
${PROJECT_PATH}/Demos/Utils/IndexedFaceMesh.cpp
31+
${PROJECT_PATH}/Demos/Utils/IndexedFaceMesh.h
32+
${PROJECT_PATH}/Demos/Utils/IndexedTetMesh.cpp
33+
${PROJECT_PATH}/Demos/Utils/IndexedTetMesh.h
34+
${PROJECT_PATH}/Demos/Utils/Utilities.cpp
35+
${PROJECT_PATH}/Demos/Utils/Utilities.h
36+
${PROJECT_PATH}/Demos/Utils/VolumeIntegration.cpp
37+
${PROJECT_PATH}/Demos/Utils/VolumeIntegration.h
38+
39+
CMakeLists.txt
40+
)
41+
42+
add_definitions(-DTW_NO_LIB_PRAGMA -DTW_STATIC)
43+
44+
find_package( Eigen3 REQUIRED )
45+
include_directories( ${EIGEN3_INCLUDE_DIR} )
46+
include_directories(${PROJECT_PATH}/extern/freeglut/include)
47+
include_directories(${PROJECT_PATH}/extern/glew/include)
48+
49+
set_target_properties(ElasticRodDemo PROPERTIES FOLDER "Demos")
50+
set_target_properties(ElasticRodDemo PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
51+
set_target_properties(ElasticRodDemo PROPERTIES RELWITHDEBINFO_POSTFIX ${CMAKE_RELWITHDEBINFO_POSTFIX})
52+
set_target_properties(ElasticRodDemo PROPERTIES MINSIZEREL_POSTFIX ${CMAKE_MINSIZEREL_POSTFIX})
53+
add_dependencies(ElasticRodDemo ${SIMULATION_DEPENDENCIES})
54+
target_link_libraries(ElasticRodDemo ${SIMULATION_LINK_LIBRARIES})
55+
56+
57+
VIS_SOURCE_GROUPS()
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
#include "PositionBasedElasticRodsConstraints.h"
2+
#include "Demos/Simulation/SimulationModel.h"
3+
#include "PositionBasedDynamics/PositionBasedDynamics.h"
4+
#include "PositionBasedDynamics/PositionBasedElasticRods.h"
5+
#include "Demos/Simulation/IDFactory.h"
6+
7+
using namespace PBD;
8+
9+
int PerpendiculaBisectorConstraint::TYPE_ID = IDFactory::getId();
10+
int GhostPointEdgeDistanceConstraint::TYPE_ID = IDFactory::getId();
11+
int DarbouxVectorConstraint::TYPE_ID = IDFactory::getId();
12+
13+
14+
//////////////////////////////////////////////////////////////////////////
15+
// PerpendiculaBisectorConstraint
16+
//////////////////////////////////////////////////////////////////////////
17+
bool PerpendiculaBisectorConstraint::initConstraint(SimulationModel &model,
18+
const unsigned int particle1, const unsigned int particle2, const unsigned int particle3)
19+
{
20+
m_bodies[0] = particle1;
21+
m_bodies[1] = particle2;
22+
m_bodies[2] = particle3;
23+
24+
return true;
25+
}
26+
27+
bool PerpendiculaBisectorConstraint::solvePositionConstraint(SimulationModel &model)
28+
{
29+
PositionBasedElasticRodsModel &simModel = static_cast<PositionBasedElasticRodsModel&>(model);
30+
31+
ParticleData &pd = model.getParticles();
32+
ParticleData &pg = simModel.getGhostParticles();
33+
34+
const unsigned i1 = m_bodies[0];
35+
const unsigned i2 = m_bodies[1];
36+
const unsigned i3 = m_bodies[2];
37+
38+
Vector3r &x1 = pd.getPosition(i1);
39+
Vector3r &x2 = pd.getPosition(i2);
40+
Vector3r &x3 = pg.getPosition(i3);
41+
42+
const Real invMass1 = pd.getInvMass(i1);
43+
const Real invMass2 = pd.getInvMass(i2);
44+
const Real invMass3 = pg.getInvMass(i3);
45+
46+
Vector3r corr[3];
47+
const bool res = PositionBasedElasticRods::solve_PerpendiculaBisectorConstraint(
48+
x1, invMass1,
49+
x2, invMass2,
50+
x3, invMass3,
51+
1.0,
52+
corr[0], corr[1], corr[2]);
53+
54+
if (res)
55+
{
56+
if (invMass1 != 0.0f)
57+
x1 += corr[0];
58+
59+
if (invMass2 != 0.0f)
60+
x2 += corr[1];
61+
62+
if (invMass2 != 0.0f)
63+
x3 += corr[2];
64+
}
65+
66+
return res;
67+
}
68+
69+
//////////////////////////////////////////////////////////////////////////
70+
// GhostPointEdgeDistanceConstraint
71+
//////////////////////////////////////////////////////////////////////////
72+
bool GhostPointEdgeDistanceConstraint::initConstraint(PositionBasedElasticRodsModel &model, const unsigned int particle1, const unsigned int particle2, const unsigned int particle3)
73+
{
74+
m_bodies[0] = particle1;
75+
m_bodies[1] = particle2;
76+
m_bodies[2] = particle3;
77+
78+
ParticleData &pd = model.getParticles();
79+
ParticleData &pg = model.getGhostParticles();
80+
81+
Vector3r &x1 = pd.getPosition( particle1);
82+
Vector3r &x2 = pd.getPosition( particle2);
83+
Vector3r &x3 = pg.getPosition( particle3);
84+
85+
Vector3r xm = 0.5 * (x1 + x2);
86+
87+
m_restLength = (x3 - xm).norm();
88+
89+
return true;
90+
}
91+
92+
bool GhostPointEdgeDistanceConstraint::solvePositionConstraint(SimulationModel &model)
93+
{
94+
PositionBasedElasticRodsModel &simModel = static_cast<PositionBasedElasticRodsModel&>(model);
95+
96+
ParticleData &pd = model.getParticles();
97+
ParticleData &pg = simModel.getGhostParticles();
98+
99+
const unsigned i1 = m_bodies[0];
100+
const unsigned i2 = m_bodies[1];
101+
const unsigned i3 = m_bodies[2];
102+
103+
Vector3r &x1 = pd.getPosition(i1);
104+
Vector3r &x2 = pd.getPosition(i2);
105+
Vector3r &x3 = pg.getPosition(i3);
106+
107+
const Real invMass1 = pd.getInvMass(i1);
108+
const Real invMass2 = pd.getInvMass(i2);
109+
const Real invMass3 = pg.getInvMass(i3);
110+
111+
Vector3r corr[3];
112+
const bool res = PositionBasedElasticRods::solve_GhostPointEdgeDistanceConstraint(x1, invMass1, x2, invMass2, x3, invMass3, 1.0, m_restLength, corr[0], corr[1], corr[2]);
113+
114+
if (res)
115+
{
116+
if (invMass1 != 0.0f)
117+
x1 += corr[0];
118+
119+
if (invMass2 != 0.0f)
120+
x2 += corr[1];
121+
122+
if (invMass3 != 0.0f)
123+
x3 += corr[2];
124+
}
125+
126+
return res;
127+
}
128+
129+
//////////////////////////////////////////////////////////////////////////
130+
// DarbouxVectorConstraint
131+
//////////////////////////////////////////////////////////////////////////
132+
bool DarbouxVectorConstraint::initConstraint(PositionBasedElasticRodsModel &model, const unsigned int particle1, const unsigned int particle2,
133+
const unsigned int particle3, const unsigned int particle4, const unsigned int particle5)
134+
{
135+
m_bodies[0] = particle1;
136+
m_bodies[1] = particle2;
137+
m_bodies[2] = particle3;
138+
m_bodies[3] = particle4; //ghost point id
139+
m_bodies[4] = particle5; //ghost point id
140+
141+
ParticleData &pd = model.getParticles();
142+
ParticleData &pg = model.getGhostParticles();
143+
144+
const Vector3r &x1 = pd.getPosition0(m_bodies[0]);
145+
const Vector3r &x2 = pd.getPosition0(m_bodies[1]);
146+
const Vector3r &x3 = pd.getPosition0(m_bodies[2]);
147+
const Vector3r &x4 = pg.getPosition0(m_bodies[3]);
148+
const Vector3r &x5 = pg.getPosition0(m_bodies[4]);
149+
150+
PositionBasedElasticRods::computeMaterialFrame(x1, x2, x4, m_dA);
151+
PositionBasedElasticRods::computeMaterialFrame(x2, x3, x5, m_dB);
152+
Vector3r restDarbouxVector;
153+
PositionBasedElasticRods::computeDarbouxVector(m_dA, m_dB, 1.0, restDarbouxVector);
154+
model.setRestDarbouxVector(restDarbouxVector);
155+
156+
return true;
157+
}
158+
159+
bool DarbouxVectorConstraint::solvePositionConstraint(SimulationModel &model)
160+
{
161+
PositionBasedElasticRodsModel &simModel = static_cast<PositionBasedElasticRodsModel&>(model);
162+
163+
ParticleData &pd = model.getParticles();
164+
ParticleData &pg = simModel.getGhostParticles();
165+
166+
Vector3r &x1 = pd.getPosition(m_bodies[0]);
167+
Vector3r &x2 = pd.getPosition(m_bodies[1]);
168+
Vector3r &x3 = pd.getPosition(m_bodies[2]);
169+
Vector3r &x4 = pg.getPosition(m_bodies[3]);
170+
Vector3r &x5 = pg.getPosition(m_bodies[4]);
171+
172+
const Real invMass1 = pd.getInvMass(m_bodies[0]);
173+
const Real invMass2 = pd.getInvMass(m_bodies[1]);
174+
const Real invMass3 = pd.getInvMass(m_bodies[2]);
175+
const Real invMass4 = pg.getInvMass(m_bodies[3]);
176+
const Real invMass5 = pg.getInvMass(m_bodies[4]);
177+
178+
Vector3r corr[5];
179+
180+
bool res = PositionBasedElasticRods::solve_DarbouxVectorConstraint(
181+
x1, invMass1, x2, invMass2, x3, invMass3, x4, invMass4, x5, invMass5,
182+
simModel.getBendingAndTwistingStiffness(), 1.0, simModel.getRestDarbouxVector(),
183+
corr[0], corr[1], corr[2], corr[3], corr[4]);
184+
185+
if (res)
186+
{
187+
if (invMass1 != 0.0f)
188+
x1 += corr[0];
189+
190+
if (invMass2 != 0.0f)
191+
x2 += corr[1];
192+
193+
if (invMass3 != 0.0f)
194+
x3 += corr[2];
195+
196+
if (invMass4 != 0.0f)
197+
x4 += corr[3];
198+
199+
if (invMass5 != 0.0f)
200+
x5 += corr[4];
201+
}
202+
return res;
203+
}
204+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#ifndef _POSITIONBASEDELASTICRODSCONSTRAINTS_H
2+
#define _POSITIONBASEDELASTICRODSCONSTRAINTS_H
3+
4+
#include "Demos/Common/Config.h"
5+
#include <Eigen/Dense>
6+
#include "Demos/Simulation/Constraints.h"
7+
#include "PositionBasedElasticRodsModel.h"
8+
9+
namespace PBD
10+
{
11+
class SimulationModel;
12+
13+
class GhostPointEdgeDistanceConstraint : public Constraint
14+
{
15+
public:
16+
static int TYPE_ID;
17+
Real m_restLength;
18+
19+
GhostPointEdgeDistanceConstraint() : Constraint(3) {}
20+
virtual int &getTypeId() const { return TYPE_ID; }
21+
22+
bool initConstraint(PositionBasedElasticRodsModel &model, const unsigned int particle1, const unsigned int particle2, const unsigned int particle3);
23+
virtual bool solvePositionConstraint(SimulationModel &model);
24+
};
25+
26+
class PerpendiculaBisectorConstraint : public Constraint
27+
{
28+
public:
29+
static int TYPE_ID;
30+
31+
PerpendiculaBisectorConstraint() : Constraint(3) {}
32+
virtual int &getTypeId() const { return TYPE_ID; }
33+
34+
bool initConstraint(SimulationModel &model, const unsigned int particle1, const unsigned int particle2, const unsigned int particle3);
35+
virtual bool solvePositionConstraint(SimulationModel &model);
36+
};
37+
38+
class DarbouxVectorConstraint : public Constraint
39+
{
40+
public:
41+
static int TYPE_ID;
42+
Matrix3r m_dA; //material frame A
43+
Matrix3r m_dB; //material frame B
44+
45+
DarbouxVectorConstraint() : Constraint(5) {}
46+
virtual int &getTypeId() const { return TYPE_ID; }
47+
48+
virtual bool initConstraint(PositionBasedElasticRodsModel &model, const unsigned int particle1, const unsigned int particle2,
49+
const unsigned int particle3, const unsigned int particle4, const unsigned int particle5);
50+
51+
virtual bool solvePositionConstraint(SimulationModel &model);
52+
};
53+
54+
}
55+
56+
#endif

0 commit comments

Comments
 (0)