29class gsVolumeBlock :
public gsSolidElement<T>
34 typedef gsSolidElement<T> SolidElement;
35 typedef typename SolidElement::scalar_t scalar_t;
36 typedef gsSolidHalfFace<T> HalfFace;
37 typedef gsSolidHalfEdge<T> HalfEdge;
38 typedef gsSolidHeVertex<T> Vertex;
41 gsVolumeBlock() : SolidElement() { }
43 explicit gsVolumeBlock(
int const& i) : SolidElement(i) { }
45 explicit gsVolumeBlock(std::vector<HalfFace*>
const & hfaces)
48 typename std::vector<HalfFace*>::const_iterator it;
49 for (it = hfaces.begin();it!=hfaces.end();++it)
55 virtual ~gsVolumeBlock()
66 boxSide getSideOfHexahedron(
const unsigned faceId)
73 HalfEdge* edge = face[0]->loop[0];
74 std::vector<HalfEdge* > hex;
75 getHexEdges(hex, edge);
77 HalfFace* myFace = face[faceId];
81 for (
size_t edgeIndx = 0; edgeIndx < hex.size(); edgeIndx++)
83 HalfEdge* faceEdge = hex[edgeIndx];
86 HalfEdge* e = myFace->loop[0];
87 for (
unsigned i = 0; i < 4; i++)
91 sideIndex =
static_cast<int>(edgeIndx);
100 gsWarn <<
"Didn't transform face with id = " << faceId <<
"\n";
103 return boxSide(sideIndex + 1);
114 bool isHexahedron()
const
117 if (face.size() != 6)
123 for (
unsigned idFace = 0; idFace != face.size(); idFace++)
125 HalfFace* myFace = face[idFace];
127 if (1 < myFace->loopN())
129 gsWarn <<
"Input volume has a hole in its face. "
134 gsPlanarDomain<T>& domain = myFace->surf->domain();
137 gsCurveLoop<T>& curveLoop = domain.loop(0);
139 if (curveLoop.numCurves() != 4)
148 gsTensorBSpline<3, T> getTensorBSplineVolume(
int numSamplePoints,
149 int numInternalKnots,
157 "Function getVolume can not tranform VolumeBlock into "
158 "gsVolume if VolumeBlock is not hexahedron.\n");
165 getUniformPoints(numSamplePoints, params, points, eps);
167 gsKnotVector<T> kv1(0, 1, numInternalKnots, degree + 1, 1);
168 gsKnotVector<T> kv2(0, 1, numInternalKnots, degree + 1, 1);
169 gsKnotVector<T> kv3(0, 1, numInternalKnots, degree + 1, 1);
171 gsTensorBSplineBasis<3, T> basis(kv1, kv2, kv3);
173 gsDebugVar(kv1.detail());
175 gsFitting<T> fitting(params, points, basis);
176 fitting.compute(lambda);
179 gsGeometry<T>* geo = fitting.result();
181 gsTensorBSpline<3, T>* bspline =
dynamic_cast<gsTensorBSpline<3, T>*
> (geo);
185 GISMO_ERROR(
"Problems with casting gsGeometry to gsTensorBspline");
197 void getUniformPoints(
const int n,
202 gsMatrix<T> bParams, bPoints;
203 getUniformBoundaryPoints(n, bParams, bPoints, eps);
205 typedef std::pair<std::pair<T, T>, T> tuple;
208 std::map<tuple, int> map;
209 for (
int col = 0; col < bParams.cols(); col++)
211 tuple t = makeTuple(bParams(0, col), bParams(1, col), bParams(2, col));
216 const gsVector<T> p000 = bPoints.col(map[makeTuple(0., 0., 0.)]);
217 const gsVector<T> p001 = bPoints.col(map[makeTuple(0., 0., 1.)]);
218 const gsVector<T> p010 = bPoints.col(map[makeTuple(0., 1., 0.)]);
219 const gsVector<T> p011 = bPoints.col(map[makeTuple(0., 1., 1.)]);
220 const gsVector<T> p100 = bPoints.col(map[makeTuple(1., 0., 0.)]);
221 const gsVector<T> p101 = bPoints.col(map[makeTuple(1., 0., 1.)]);
222 const gsVector<T> p110 = bPoints.col(map[makeTuple(1., 1., 0.)]);
223 const gsVector<T> p111 = bPoints.col(map[makeTuple(1., 1., 1.)]);
225 const int numPoints = (n - 2) * (n - 2) * (n - 2) + bParams.cols();
226 params.resize(3, numPoints);
227 points.resize(3, numPoints);
231 for (
int indx = 1; indx != n - 1; indx++)
233 const T x = (indx * 1.0) / (n - 1);
235 for (
int indy = 1; indy != n - 1; indy++)
237 const T y = (indy * 1.0) / (n - 1);
239 for (
int indz = 1; indz != n - 1; indz++)
241 const T z = (indz * 1.0) / (n - 1);
244 params(0, column) = x;
245 params(1, column) = y;
246 params(2, column) = z;
251 const gsVector<T> A =
252 (1 - x) * bPoints.col(map[makeTuple(0, y, z)]) +
253 x * bPoints.col(map[makeTuple(1, y, z)]);
255 const gsVector<T> B =
256 (1 - y) * bPoints.col(map[makeTuple(x, 0, z)]) +
257 y * bPoints.col(map[makeTuple(x, 1, z)]);
259 const gsVector<T> C =
260 (1 - z) * bPoints.col(map[makeTuple(x, y, 0)]) +
261 z * bPoints.col(map[makeTuple(x, y, 1)]);
264 const gsVector<T> AB =
265 (1 - x) * (1 - y) * bPoints.col(map[makeTuple(0, 0, z)]) +
266 (1 - x) * y * bPoints.col(map[makeTuple(0, 1, z)]) +
267 x * (1 - y) * bPoints.col(map[makeTuple(1, 0, z)]) +
268 x * y * bPoints.col(map[makeTuple(1, 1, z)]);
270 const gsVector<T> BC =
271 (1 - y) * (1 - z) * bPoints.col(map[makeTuple(x, 0, 0)]) +
272 (1 - y) * z * bPoints.col(map[makeTuple(x, 0, 1)]) +
273 y * (1 - z) * bPoints.col(map[makeTuple(x, 1, 0)]) +
274 y * z * bPoints.col(map[makeTuple(x, 1, 1)]);
276 const gsVector<T> AC =
277 (1 - x) * (1 - z) * bPoints.col(map[makeTuple(0, y, 0)]) +
278 (1 - x) * z * bPoints.col(map[makeTuple(0, y, 1)]) +
279 x * (1 - z) * bPoints.col(map[makeTuple(1, y, 0)]) +
280 x * z * bPoints.col(map[makeTuple(1, y, 1)]);
283 const gsVector<T> ABC =
284 (1 - x) * ((1 - y) * ((1 - z) * p000 + z * p001) +
285 y * ((1 - z) * p010 + z * p011)) +
286 x * ((1 - y) * ((1 - z) * p100 + z * p101) +
287 y * ((1 - z) * p110 + z * p111));
289 points.col(column) = A + B + C - AB - BC - AC + ABC;
298 for (
int col = 0; col < bPoints.cols(); ++col)
300 points.col(column) = bPoints.col(col);
301 params.col(column) = bParams.col(col);
311 void getUniformBoundaryPoints(
const int n,
312 gsMatrix<T>& params3D,
316 HalfEdge* edge = face[0]->loop[0];
317 std::vector<HalfEdge* > hex;
318 getHexEdges(hex, edge);
320 int nmbOfPts = 6 * (n * n + 4);
321 points .resize(3, nmbOfPts);
322 params3D.resize(3, nmbOfPts);
324 gsVector<T> params1D(n);
325 for (
int index = 0; index != n; index++)
327 params1D(index) = index * 1.0 / (n - 1);
337 bool turnAround = turnCurveLoopAround(side);
338 T fixedConstant = side.parameter() ? 1.0 : 0.0;
346 int fixed = side.direction();
347 int first = (fixed == 0) ? 1 : 0;
348 int second = (fixed == 2) ? 1 : 2;
363 std::vector<gsVector<T> > faceBoundaryParams;
364 HalfEdge* faceEdge = hex[side - 1];
369 for (
int curveId = 0; curveId < 4; curveId++)
371 HalfEdge* edge2 = faceEdge->moveAlongEdge(curveId);
374 int index = edge2->face->indexOfEdge(edge2);
377 edge2->face->surf->getPhysicalyUniformCurveParameters(
378 0, index, n, params, eps);
381 gsMatrix<T> curvePoints;
382 edge2->face->surf->evalCurve_into(
383 0, index, params.transpose(), curvePoints);
386 bool turnCurve = turnCurveAround(turnAround, curveId);
393 T curveConstant = 0.0;
394 if ( (turnAround && (curveId == 2 || curveId == 3)) ||
395 (!turnAround && (curveId == 1 || curveId == 2)) )
404 int curveConstantIndex = first;
405 int curveNonConstIndex = second;
406 if (curveId == 0 || curveId == 2)
408 curveConstantIndex = second;
409 curveNonConstIndex = first;
413 for (
int col = 0; col < n; col++)
415 params3D(fixed, column) = fixedConstant;
416 params3D(curveConstantIndex, column) = curveConstant;
417 params3D(curveNonConstIndex, column) = params1D(col);
421 points.col(column) = curvePoints.col(n - 1 - col);
425 points.col(column) = curvePoints.col(col);
441 params.reverseInPlace();
444 faceBoundaryParams.push_back(params);
451 bool switch1and3curve =
false;
452 if (side == boundary::east ||
453 side == boundary::front ||
454 side == boundary::north)
456 switch1and3curve =
true;
462 gsMatrix<T> cpParams;
463 modifiedCoonsPatch(hex[side - 1], faceBoundaryParams,
464 params1D, cpParams, switch1and3curve);
466 gsMatrix<T> cpPoints;
467 faceEdge->face->surf->evalSurface_into(cpParams, cpPoints);
470 for (
int indv = 0; indv != n - 2; indv++)
472 for (
int indu = 0; indu != n - 2; indu++)
474 params3D(fixed, column) = fixedConstant;
475 params3D(first, column) = params1D(indu + 1);
476 params3D(second, column) = params1D(indv + 1);
478 points.col(column) = cpPoints.col(indv * (n - 2) + indu);
488 static std::pair<std::pair<T, T>, T> makeTuple(T x, T y, T z)
490 return std::make_pair(std::make_pair(x, y), z);
512 void modifiedCoonsPatch(HalfEdge* edge,
513 const std::vector<gsVector<T> >& boundaryParams,
514 const gsVector<T>& params1D,
515 gsMatrix<T>& cpPoints,
516 const bool switch1and3curve)
518 int n = boundaryParams[0].size();
519 int m = boundaryParams[1].size();
521 cpPoints.resize(2, (n - 2) * (m - 2));
524 std::vector<gsMatrix<T> > values;
525 for (
int curveId = 0; curveId != 4; curveId++)
527 HalfEdge* curveEdge = edge->moveAlongEdge(curveId);
528 int internalIndex = getInternalIndexOfCurve(curveEdge);
529 gsCurve<T>& curve = edge->face->surf->getCurve(0, internalIndex);
531 gsMatrix<T> curvePoints;
532 curve.eval_into(boundaryParams[curveId].transpose(), curvePoints);
533 values.push_back(curvePoints);
537 gsVector<T> c00 = values[0].col(0);
538 gsVector<T> c01 = values[0].col(n - 1);
540 gsVector<T> c20 = values[2].col(0);
541 gsVector<T> c21 = values[2].col(n - 1);
547 for (
int indv = 1; indv != n - 1; indv++)
549 T v = params1D[indv];
552 for (
int indu = 1; indu != m - 1; indu++)
554 T u = params1D[indu];
555 cpPoints.col(column) = (1 - v) * values[0].col(indu) +
556 v * values[2].col(indu)
557 - (1 - v) * (1 - u) * c00
563 if (switch1and3curve)
565 vec = (1 - u) * values[3].col(indv) +
566 u * values[1].col(indv);
570 vec = (1 - u) * values[1].col(indv) +
571 u * values[3].col(indv);
574 cpPoints.col(column) += vec;
623 bool turnCurveAround(
const bool curveLoopAround,
const int curveId)
625 if ( (!curveLoopAround && (curveId == 2 || curveId == 3)) ||
626 (curveLoopAround && (curveId == 0 || curveId == 3)) )
642 bool turnCurveLoopAround(boxSide side)
644 if (side == boundary::west ||
645 side == boundary::south ||
646 side == boundary::back)
660 int getInternalIndexOfCurve(HalfEdge* edge)
const
662 return edge->face->indexOfEdge(edge);
670 void getHexEdges(std::vector<HalfEdge*>& hex, HalfEdge* edge)
677 hex.push_back(getEastEdge(edge));
679 hex.push_back(getSouthEdge(edge));
681 hex.push_back(getNorthEdge(edge));
683 hex.push_back(getFrontEdge(edge));
685 hex.push_back(getBackEdge(edge));
690 HalfEdge* getEastEdge(HalfEdge* edge)
694 edge = edge->moveAlongEdge(2);
701 HalfEdge* getSouthEdge(HalfEdge* edge)
709 HalfEdge* getNorthEdge(HalfEdge* edge)
711 edge = edge->moveAlongEdge(2);
718 HalfEdge* getFrontEdge(HalfEdge* edge)
727 HalfEdge* getBackEdge(HalfEdge* edge)
738 std::vector<HalfFace*> face;
static boxSide getEnd(short_t dim)
helper for iterating on sides of an n-dimensional box
Definition gsBoundary.h:176
static boxSide getFirst(short_t)
helper for iterating on sides of an n-dimensional box
Definition gsBoundary.h:160
Provides structs and classes related to interfaces and boundaries.
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define gsWarn
Definition gsDebug.h:50
Provides declaration of data fitting algorithms by least squares approximation.
Provides gsSolidElement class - interface for an element (vertex, edge or face) of a solid.
Provides declaration of gsSolid class, a boundary-represented solid.
Provides declaration of Volume abstract interface.
The G+Smo namespace, containing all definitions for the library.