77 if (node->
isinternal() && ((depth < maxdepth) || (maxdepth < 0)))
79 drawTree(idraw, node->
childs[0], depth + 1, ncolor, lcolor, mindepth, maxdepth);
80 drawTree(idraw, node->
childs[1], depth + 1, ncolor, lcolor, mindepth, maxdepth);
82 if (depth >= mindepth)
100 for (
int i = 1, ni = items.
size();
i < ni; ++
i)
109template <
typename T,
typename Q>
112 for (
int i = 0, ni = items.
size();
i < ni; ++
i)
119template <
typename T,
typename Q>
122 for (
int i = 0, ni = items.
size();
i < ni; ++
i)
133 return (
sum(items) / n);
161 static const int ncolors=
sizeof(spectrum)/
sizeof(spectrum[0])-1;
164 const int sel=(int)stress;
166 return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
193 color = color.normalized() * 0.75;
196 for (j = 0, nj = vertices.
size(); j < nj; ++j)
200#define USE_NEW_CONVEX_HULL_COMPUTER
201#ifdef USE_NEW_CONVEX_HULL_COMPUTER
207 computer.compute(&vertices[0].
getX(), stride,
count, shrink, shrinkClamp);
210 int face = computer.
faces[
i];
217 while (edge != firstEdge)
237 for (j = 0; j < (int)hres.
mNumFaces; ++j)
284 const btSoftBody::Link&
l = psb->
m_links[
i];
286 idraw->
drawLine(
l.m_n[0]->m_x,
l.m_n[1]->m_x, lcolor);
314 idraw->
drawLine(o -
x * nscl, o +
x * nscl, ccolor);
315 idraw->
drawLine(o -
y * nscl, o +
y * nscl, ccolor);
332 (
x[1] - c) * scl + c,
333 (
x[2] - c) * scl + c,
349 idraw->
drawTriangle((
x[0] - c) * scl + c, (
x[1] - c) * scl + c, (
x[2] - c) * scl + c,
col, alp);
350 idraw->
drawTriangle((
x[0] - c) * scl + c, (
x[1] - c) * scl + c, (
x[3] - c) * scl + c,
col, alp);
351 idraw->
drawTriangle((
x[1] - c) * scl + c, (
x[2] - c) * scl + c, (
x[3] - c) * scl + c,
col, alp);
352 idraw->
drawTriangle((
x[2] - c) * scl + c, (
x[0] - c) * scl + c, (
x[3] - c) * scl + c,
col, alp);
385 for (
int j = 0; j < n.
m_rank; ++j)
448 char text[2048] = {0};
452 sprintf(buff,
" M(%.2f)", 1 / n.
m_im);
457 sprintf(buff,
" A(%.2f)", n.
m_area);
470 drawTree(idraw, psb->
m_ndbvt.
m_root, 0,
btVector3(1, 0, 1),
btVector3(1, 1, 1), mindepth, maxdepth);
479 drawTree(idraw, psb->
m_fdbvt.
m_root, 0,
btVector3(0, 1, 0),
btVector3(1, 0, 0), mindepth, maxdepth);
488 drawTree(idraw, psb->
m_cdbvt.
m_root, 0,
btVector3(0, 1, 1),
btVector3(1, 0, 0), mindepth, maxdepth);
539#define REOP_NOT_DEPENDENT -1
540#define REOP_NODE_COMPLETE -2
545 btSoftBody::Link* lr;
550 int readyListHead, readyListTail, linkNum, linkDepFrees, depLink;
553 int* nodeWrittenAt =
new int[nNodes + 1];
554 int* linkDepA =
new int[nLinks];
555 int* linkDepB =
new int[nLinks];
556 int* readyList =
new int[nLinks];
561 btSoftBody::Link* linkBuffer =
new btSoftBody::Link[nLinks];
562 memcpy(linkBuffer, &(psb->
m_links[0]),
sizeof(btSoftBody::Link) * nLinks);
565 for (
i = 0;
i < nNodes + 1;
i++)
569 for (
i = 0;
i < nLinks;
i++)
571 linkDepListStarts[
i] = NULL;
573 readyListHead = readyListTail = linkDepFrees = 0;
576 for (
i = 0;
i < nLinks;
i++)
580 ar = (lr->m_n[0] - node0) / (node1 - node0);
581 br = (lr->m_n[1] - node0) / (node1 - node0);
584 linkDepA[
i] = nodeWrittenAt[ar];
585 linkDep = &linkDepFreeList[linkDepFrees++];
587 linkDep->
next = linkDepListStarts[nodeWrittenAt[ar]];
588 linkDepListStarts[nodeWrittenAt[ar]] = linkDep;
596 linkDepB[
i] = nodeWrittenAt[br];
597 linkDep = &linkDepFreeList[linkDepFrees++];
598 linkDep->
value = -(
i + 1);
599 linkDep->
next = linkDepListStarts[nodeWrittenAt[br]];
600 linkDepListStarts[nodeWrittenAt[br]] = linkDep;
610 readyList[readyListTail++] =
i;
615 nodeWrittenAt[ar] = nodeWrittenAt[br] =
i;
624 while (readyListHead != readyListTail)
627 linkNum = readyList[readyListHead++];
629 psb->
m_links[
i++] = linkBuffer[linkNum];
632 linkDep = linkDepListStarts[linkNum];
635 depLink = linkDep->
value;
642 depLink = -depLink - 1;
648 readyList[readyListTail++] = depLink;
651 linkDep = linkDep->
next;
656 delete[] nodeWrittenAt;
660 delete[] linkDepFreeList;
661 delete[] linkDepListStarts;
696 const int r = res + 2;
701 for (
i = 0;
i < r; ++
i)
708 if (fixeds & 1) psb->
setMass(0, 0);
709 if (fixeds & 2) psb->
setMass(r - 1, 0);
713 for (
i = 1;
i < r; ++
i)
732#define IDX(_x_, _y_) ((_y_)*rx + (_x_))
734 if ((resx < 2) || (resy < 2))
return (0);
737 const int tot = rx * ry;
742 for (iy = 0; iy < ry; ++iy)
747 for (
int ix = 0; ix < rx; ++ix)
752 temp1.setY(py1.getY() + pert);
754 pert = perturbation *
btScalar(rand()) / RAND_MAX;
755 temp.setY(py0.getY() + pert);
756 x[
IDX(ix, iy)] =
lerp(temp, temp1, tx);
762 if (fixeds & 2) psb->
setMass(
IDX(rx - 1, 0), 0);
763 if (fixeds & 4) psb->
setMass(
IDX(0, ry - 1), 0);
764 if (fixeds & 8) psb->
setMass(
IDX(rx - 1, ry - 1), 0);
768 for (iy = 0; iy < ry; ++iy)
770 for (
int ix = 0; ix < rx; ++ix)
772 const int idx =
IDX(ix, iy);
773 const bool mdx = (ix + 1) < rx;
774 const bool mdy = (iy + 1) < ry;
884#define IDX(_x_, _y_) ((_y_)*rx + (_x_))
886 if ((resx < 2) || (resy < 2))
return (0);
889 const int tot = rx * ry;
895 for (iy = 0; iy < ry; ++iy)
900 for (
int ix = 0; ix < rx; ++ix)
903 x[
IDX(ix, iy)] =
lerp(py0, py1, tx);
909 if (fixeds & 2) psb->
setMass(
IDX(rx - 1, 0), 0);
910 if (fixeds & 4) psb->
setMass(
IDX(0, ry - 1), 0);
911 if (fixeds & 8) psb->
setMass(
IDX(rx - 1, ry - 1), 0);
912 if (fixeds & 16) psb->
setMass(
IDX((rx - 1) / 2, 0), 0);
913 if (fixeds & 32) psb->
setMass(
IDX(0, (ry - 1) / 2), 0);
914 if (fixeds & 64) psb->
setMass(
IDX(rx - 1, (ry - 1) / 2), 0);
915 if (fixeds & 128) psb->
setMass(
IDX((rx - 1) / 2, ry - 1), 0);
916 if (fixeds & 256) psb->
setMass(
IDX((rx - 1) / 2, (ry - 1) / 2), 0);
922 for (iy = 0; iy < ry; ++iy)
924 for (
int ix = 0; ix < rx; ++ix)
926 const bool mdx = (ix + 1) < rx;
927 const bool mdy = (iy + 1) < ry;
929 int node00 =
IDX(ix, iy);
930 int node01 =
IDX(ix + 1, iy);
931 int node10 =
IDX(ix, iy + 1);
932 int node11 =
IDX(ix + 1, iy + 1);
955 tex_coords[
z + 10] =
CalculateUV(resx, resy, ix, iy, 0);
956 tex_coords[
z + 11] =
CalculateUV(resx, resy, ix, iy, 1);
958 if (gendiags) psb->
appendLink(node00, node11);
998 tc = (1.0f / ((resx - 1)) * ix);
1002 tc = (1.0f / ((resy - 1)) * (resy - 1 - iy));
1006 tc = (1.0f / ((resy - 1)) * (resy - 1 - iy - 1));
1010 tc = (1.0f / ((resx - 1)) * (ix + 1));
1023 for (
int i = 0;
i < n;
i++)
1026 for (
int j =
i; j; p *= 0.5, j >>= 1)
1037 Hammersley::Generate(&vtx[0], vtx.
size());
1038 for (
int i = 0;
i < vtx.
size(); ++
i)
1040 vtx[
i] = vtx[
i] * radius + center;
1047 const int* triangles,
1048 int ntriangles,
bool randomizeConstraints)
1053 for (
i = 0, ni = ntriangles * 3;
i < ni; ++
i)
1055 maxidx =
btMax(triangles[
i], maxidx);
1060 chks.
resize(maxidx * maxidx,
false);
1062 for (
i = 0, j = 0, ni = maxidx * 3;
i < ni; ++j,
i += 3)
1064 vtx[j] =
btVector3(vertices[
i], vertices[
i + 1], vertices[
i + 2]);
1067 for (
i = 0, ni = ntriangles * 3;
i < ni;
i += 3)
1069 const int idx[] = {triangles[
i], triangles[
i + 1], triangles[
i + 2]};
1070#define IDX(_x_, _y_) ((_y_)*maxidx + (_x_))
1071 for (
int j = 2, k = 0; k < 3; j = k++)
1073 if (!chks[
IDX(idx[j], idx[k])])
1075 chks[
IDX(idx[j], idx[k])] =
true;
1076 chks[
IDX(idx[k], idx[j])] =
true;
1084 if (randomizeConstraints)
1094 int nvertices,
bool randomizeConstraints)
1105 const int idx[] = {
static_cast<int>(hres.
m_Indices[
i * 3 + 0]),
1107 static_cast<int>(hres.
m_Indices[
i * 3 + 2])};
1108 if (idx[0] < idx[1]) psb->
appendLink(idx[0], idx[1]);
1109 if (idx[1] < idx[2]) psb->
appendLink(idx[1], idx[2]);
1110 if (idx[2] < idx[0]) psb->
appendLink(idx[2], idx[0]);
1114 if (randomizeConstraints)
1123 int numBytesRead = 0;
1125 while (*buffer !=
'\n')
1131 if (buffer[0] == 0x0a)
1136 return numBytesRead;
1146 bool bfacesfromtetras)
1153 int result = sscanf(node,
"%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
1154 result = sscanf(node,
"%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds);
1158 for (
int i = 0;
i <
pos.size(); ++
i)
1163 sscanf(node,
"%d %f %f %f", &index, &
x, &
y, &
z);
1184 sf>>nface;sf>>hasbounds;
1185 for(
int i=0;
i<nface;++
i)
1191 sf>>ni[0];sf>>ni[1];sf>>ni[2];
1209 sscanf(ele,
"%d %d %d", &ntetra, &ncorner, &neattrb);
1213 for (
int i = 0;
i < ntetra; ++
i)
1220 sscanf(ele,
"%d %d %d %d %d", &index, &ni[0], &ni[1], &ni[2], &ni[3]);
1257 bool reading_points =
false;
1258 bool reading_tets =
false;
1259 size_t n_points = 0;
1262 size_t indices_count = 0;
1263 while (std::getline(fs, line))
1265 std::stringstream ss(line);
1266 if (line.size() == (
size_t)(0))
1269 else if (line.substr(0, 6) ==
"POINTS")
1271 reading_points =
true;
1272 reading_tets =
false;
1273 ss.ignore(128,
' ');
1277 else if (line.substr(0, 5) ==
"CELLS")
1279 reading_points =
false;
1280 reading_tets =
true;
1281 ss.ignore(128,
' ');
1285 else if (line.substr(0, 10) ==
"CELL_TYPES")
1287 reading_points =
false;
1288 reading_tets =
false;
1290 else if (reading_points)
1299 X[x_count++] = position;
1301 else if (reading_tets)
1307 printf(
"Load deformable failed: Only Tetrahedra are supported in VTK file.\n");
1311 ss.ignore(128,
' ');
1314 for (
size_t i = 0;
i < 4;
i++)
1320 indices[indices_count++] = tet;
1325 for (
int i = 0;
i < n_tets; ++
i)
1365 index.push_back(psb->
m_tetras[
i].m_n[0]->index);
1366 index.push_back(psb->
m_tetras[
i].m_n[1]->index);
1367 index.push_back(psb->
m_tetras[
i].m_n[2]->index);
1368 index.push_back(psb->
m_tetras[
i].m_n[3]->index);
1372 std::map<std::vector<int>, std::vector<int> > dict;
1375 for (
int j = 0; j < 4; ++j)
1402 std::vector<int> f_sorted = f;
1403 std::sort(f_sorted.begin(), f_sorted.end());
1404 if (dict.find(f_sorted) != dict.end())
1406 dict.erase(f_sorted);
1410 dict.insert(std::make_pair(f_sorted, f));
1415 for (std::map<std::vector<int>, std::vector<int> >::iterator it = dict.begin(); it != dict.end(); ++it)
1417 std::vector<int> f = it->second;
1432 std::map<int, int> dict;
1435 for (
int d = 0; d < 3; d++)
1437 int index = psb->
m_faces[
i].m_n[d]->index;
1438 if (dict.find(index) == dict.end())
1440 int dict_size = dict.size();
1441 dict[index] = dict_size;
1443 for (
int k = 0; k < 3; k++)
1445 fs <<
" " << psb->
m_nodes[index].m_x[k];
1455 for (
int n = 0; n < 3; n++)
1457 fs <<
" " << dict[psb->
m_faces[
i].m_n[n]->index] + 1;
1468 for (
int d = 0; d < 3; d++)
1470 fs <<
" " << psb->
m_nodes[
i].m_x[d];
1478 for (
int n = 0; n < 3; n++)
1480 fs <<
" " << psb->
m_faces[
i].m_n[n]->index + 1;
1490 std::ifstream fs_read;
1491 fs_read.open(filename);
1495 while (std::getline(fs_read, line))
1497 std::stringstream ss(line);
1501 else if (line[0] ==
'f')
1517 std::ofstream fs_write;
1518 fs_write.open(filename, std::ios_base::app);
1519 for (
int i = 0;
i < additional_faces.
size(); ++
i)
1522 for (
int n = 0; n < 3; n++)
1524 fs_write <<
" " << additional_faces[
i][n];
1543 btScalar va6 = (vbp.cross(vbd)).dot(vbc);
1544 btScalar vb6 = (vap.cross(vac)).dot(vad);
1545 btScalar vc6 = (vap.cross(vad)).dot(vab);
1546 btScalar vd6 = (vap.cross(vab)).dot(vac);
1548 bary =
btVector4(va6 * v6, vb6 * v6, vc6 * v6, vd6 * v6);
1560 btScalar invDenom = 1.0 / (d00 * d11 - d01 * d01);
1561 bary[1] = (d11 * d20 - d01 * d21) * invDenom;
1562 bary[2] = (d00 * d21 - d01 * d20) * invDenom;
1563 bary[0] = 1.0 - bary[1] - bary[2];
1585 btScalar new_min_bary_weight = bary[0];
1586 for (
int k = 1; k < 4; ++k)
1588 new_min_bary_weight =
btMin(new_min_bary_weight, bary[k]);
1590 if (new_min_bary_weight > min_bary_weight)
1597 optimal_parents = parents;
1598 optimal_bary = bary;
1599 min_bary_weight = new_min_bary_weight;
1601 if (bary[0] >= 0. && bary[1] >= 0. && bary[2] >= 0. && bary[3] >= 0.)
1625 btScalar dist = 0, optimal_dist = 0;
1634 btScalar new_min_bary_weight = bary[0];
1635 for (
int k = 1; k < 3; ++k)
1637 new_min_bary_weight =
btMin(new_min_bary_weight, bary[k]);
1641 bool better_than_closest_outisde = (new_min_bary_weight > min_bary_weight && min_bary_weight < 0.);
1643 bool better_than_best_inside = (new_min_bary_weight >= 0 && min_bary_weight >= 0 &&
btFabs(dist) <
btFabs(optimal_dist));
1645 if (better_than_closest_outisde || better_than_best_inside)
1651 optimal_parents = parents;
1652 optimal_bary = bary;
1653 optimal_dist = dist;
1654 min_bary_weight = new_min_bary_weight;
1659 psb->
m_z[
i] = optimal_dist;
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
SIMD_FORCE_INLINE const T & btMin(const T &a, const T &b)
SIMD_FORCE_INLINE const T & btMax(const T &a, const T &b)
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
SIMD_FORCE_INLINE const btScalar & getX() const
Return the x value.
SIMD_FORCE_INLINE btScalar btCos(btScalar x)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
SIMD_FORCE_INLINE btScalar btSin(btScalar x)
SIMD_FORCE_INLINE btScalar btFabs(btScalar x)
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
static T average(const btAlignedObjectArray< T > &items)
#define REOP_NODE_COMPLETE
static void drawTree(btIDebugDraw *idraw, const btDbvtNode *node, int depth, const btVector3 &ncolor, const btVector3 &lcolor, int mindepth, int maxdepth)
static void mul(btAlignedObjectArray< T > &items, const Q &value)
static int nextLine(const char *buffer)
static void add(btAlignedObjectArray< T > &items, const Q &value)
static T sum(const btAlignedObjectArray< T > &items)
static void drawBox(btIDebugDraw *idraw, const btVector3 &mins, const btVector3 &maxs, const btVector3 &color)
#define REOP_NOT_DEPENDENT
static void drawVertex(btIDebugDraw *idraw, const btVector3 &x, btScalar s, const btVector3 &c)
btSoftBodyHelpers.cpp by Nathanael Presson
LinkDeps_t * LinkDepsPtr_t
SIMD_FORCE_INLINE btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
SIMD_FORCE_INLINE btVector3 normalized() const
Return a normalized version of this vector.
SIMD_FORCE_INLINE btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
unsigned int mMaxVertices
HullError ReleaseResult(HullResult &result)
HullError CreateConvexHull(const HullDesc &desc, HullResult &result)
btAlignedObjectArray< btVector3 > m_OutputVertices
btAlignedObjectArray< unsigned int > m_Indices
unsigned int mNumOutputVertices
SIMD_FORCE_INLINE int size() const
return the number of elements in the array
SIMD_FORCE_INLINE void resize(int newsize, const T &fillData=T())
SIMD_FORCE_INLINE void push_back(const T &_Val)
const Edge * getNextEdgeOfFace() const
int getSourceVertex() const
int getTargetVertex() const
btAlignedObjectArray< btVector3 > vertices
btAlignedObjectArray< int > faces
btAlignedObjectArray< Edge > edges
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
virtual void draw3dText(const btVector3 &location, const char *textString)=0
virtual void drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &, const btVector3 &, const btVector3 &, const btVector3 &color, btScalar alpha)
void appendFace(int model=-1, Material *mat=0)
void setMass(int node, btScalar mass)
btAlignedObjectArray< TetraScratch > m_tetraScratchesTn
void appendTetra(int model, Material *mat)
btAlignedObjectArray< TetraScratch > m_tetraScratches
btAlignedObjectArray< btVector4 > m_renderNodesInterpolationWeights
btAlignedObjectArray< btScalar > m_z
tRContactArray m_rcontacts
btAlignedObjectArray< btAlignedObjectArray< const btSoftBody::Node * > > m_renderNodesParents
void randomizeConstraints()
void appendLink(int model=-1, Material *mat=0)
void initializeDmInverse()
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
DBVT_INLINE btVector3 Extents() const
DBVT_INLINE btVector3 Center() const
DBVT_INLINE bool isinternal() const
DBVT_INLINE bool isleaf() const
static btSoftBody * CreatePatchUV(btSoftBodyWorldInfo &worldInfo, const btVector3 &corner00, const btVector3 &corner10, const btVector3 &corner01, const btVector3 &corner11, int resx, int resy, int fixeds, bool gendiags, float *tex_coords=0)
static void writeObj(const char *file, const btSoftBody *psb)
static btSoftBody * CreateFromTriMesh(btSoftBodyWorldInfo &worldInfo, const btScalar *vertices, const int *triangles, int ntriangles, bool randomizeConstraints=true)
static void extrapolateBarycentricWeights(btSoftBody *psb)
static void DrawNodeTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static void getBarycentricWeights(const btVector3 &a, const btVector3 &b, const btVector3 &c, const btVector3 &d, const btVector3 &p, btVector4 &bary)
static btSoftBody * CreateFromTetGenData(btSoftBodyWorldInfo &worldInfo, const char *ele, const char *face, const char *node, bool bfacelinks, bool btetralinks, bool bfacesfromtetras)
static btSoftBody * CreateFromConvexHull(btSoftBodyWorldInfo &worldInfo, const btVector3 *vertices, int nvertices, bool randomizeConstraints=true)
static btSoftBody * CreateFromVtkFile(btSoftBodyWorldInfo &worldInfo, const char *vtk_file)
static void ReoptimizeLinkOrder(btSoftBody *psb)
static void DrawFaceTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static void DrawInfos(btSoftBody *psb, btIDebugDraw *idraw, bool masses, bool areas, bool stress)
static btSoftBody * CreateEllipsoid(btSoftBodyWorldInfo &worldInfo, const btVector3 ¢er, const btVector3 &radius, int res)
static void DrawClusterTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static float CalculateUV(int resx, int resy, int ix, int iy, int id)
static btSoftBody * CreatePatch(btSoftBodyWorldInfo &worldInfo, const btVector3 &corner00, const btVector3 &corner10, const btVector3 &corner01, const btVector3 &corner11, int resx, int resy, int fixeds, bool gendiags, btScalar perturbation=0.)
static void generateBoundaryFaces(btSoftBody *psb)
static void Draw(btSoftBody *psb, btIDebugDraw *idraw, int drawflags=fDrawFlags::Std)
static void duplicateFaces(const char *filename, const btSoftBody *psb)
static void DrawFrame(btSoftBody *psb, btIDebugDraw *idraw)
static btSoftBody * CreateRope(btSoftBodyWorldInfo &worldInfo, const btVector3 &from, const btVector3 &to, int res, int fixeds)
static void interpolateBarycentricWeights(btSoftBody *psb)
const btTransform & xform() const
btAlignedObjectArray< Node * > m_nodes
virtual eType::_ Type() const =0