37 os<<
"\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
38 os<<
"A free-form solid modeled as a gsSolid:\n";
39 os<<
"Number of volumes : "<< numVolumes <<
"\n";
40 os<<
"Number of half faces: "<< numHalfFaces <<
"\n";
41 os<<
"Number of half edges: "<< numHalfEdges <<
"\n";
42 os<<
"Number of vertices : "<< numVertices <<
"\n";
45 os<<
"vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n";
53 gsSolidHeVertexHandle v = this->makeHeVertex(x,y,z);
55 v->setId(numVertices++);
58 bb.pMax.x() = bb.pMin.x() = x;
59 bb.pMax.y() = bb.pMin.y() = y;
60 bb.pMax.z() = bb.pMin.z() = z;
86 return addFace_PlanarPolygon(V);
90 for (
unsigned i=0; i<=3; i++)
92 for (
unsigned xi=0;xi<=2;xi++)
94 corner(i,xi) = (V[i]->coords)[xi];
99 return addFace(V,tsurf);
120 typename gsSolid<T>::gsSolidHalfFaceHandle
gsSolid<T>::addFace(std::vector<gsSolidHeVertexHandle> V, gsTrimSurface<T> * tsurf)
122 gsSolidHalfFaceHandle f =
new gsSolidHalfFace<T>();
124 std::vector<gsSolidHalfEdgeHandle> H;
125 for (
typename std::vector<gsSolidHeVertexHandle>::iterator
126 it = V.begin(); it!= V.end(); ++it)
129 gsSolidHalfEdgeHandle tempHe = this->makeSolidHalfEdge(*it,f);
130 tempHe->setId(numHalfEdges++);
131 H.push_back( tempHe );
132 edge.push_back( tempHe );
141 f->setId(numHalfFaces++);
148 gsSolidHalfFaceHandle f =
new gsSolidHalfFace<T>();
150 std::vector<gsSolidHalfEdgeHandle> H;
152 std::vector<gsSolidHeVertexHandle> V;
153 for (
size_t il=0; il<loopV.size(); il++)
157 for (
typename std::vector<gsSolidHeVertexHandle>::iterator
158 it = V.begin(); it!= V.end(); ++it)
161 gsSolidHalfEdgeHandle tempHe = this->makeSolidHalfEdge(*it,f);
162 tempHe->setId(numHalfEdges++);
163 H.push_back( tempHe );
164 edge.push_back( tempHe );
174 f->setId(numHalfFaces++);
183 int faceVerts = V.size();
184 assert(faceVerts >= 3);
189 int minVert = faceVerts - 1;
190 for(
int i = 0; i < faceVerts - 1; i++)
192 if(V[i]->coords(0) < V[minVert]->coords(0) ||
193 (V[i]->coords(0) <= V[minVert]->coords(0) && V[i]->coords(1) < V[minVert]->coords(1)))
199 gsVector3d<T> prevVector = V[(minVert + faceVerts - 1) % faceVerts]->coords - V[minVert]->coords;
202 int nextVertex = minVert;
203 while(normal.squaredNorm() == 0)
205 nextVertex = (nextVertex + 1) % faceVerts;
206 assert(nextVertex != minVert);
207 normal = (V[nextVertex]->coords - V[minVert]->coords).cross(prevVector);
210 for(
int i = 3; i < faceVerts; i++)
212 assert((V[i]->coords - V[0]->coords).dot(normal) == 0);
214 T normalCoord = normal.dot(V[0]->coords);
225 a1 = a1.cross(normal);
226 a2 = a2.cross(normal);
228 if(a1.squaredNorm() > a2.squaredNorm())
237 b2 = normal.cross(b1);
248 for(
int i = 0; i < faceVerts; i++)
251 x = b1.dot(V[i]->coords);
252 y = b2.dot(V[i]->coords);
257 DomCor(faceVerts, 0) = DomCor(0, 0);
258 DomCor(faceVerts, 1) = DomCor(0, 1);
261 T minx = DomCor.col(0).minCoeff();
262 T maxx = DomCor.col(0).maxCoeff();
263 T miny = DomCor.col(1).minCoeff();
264 T maxy = DomCor.col(1).maxCoeff();
265 T rangex = maxx - minx, rangey = maxy - miny;
266 T midx = (minx + maxx) / (T)(2), midy = (miny + maxy) / (T)(2);
267 T halfMaxRange = std::max(rangex, rangey) * (margin * (T)(2) + (T)(1)) / (T)(2);
268 minx -= rangex * margin;
269 maxx += rangex * margin;
270 miny -= rangey * margin;
271 maxy += rangey * margin;
280 for(
int i = 0; i < faceVerts; i++)
283 tcp << DomCor(i, 0), DomCor(i, 1), DomCor(i + 1, 0), DomCor(i + 1, 1);
285 tloop->insertCurve(tcurve);
301 for(
int xi = 0; xi < 3; xi++)
303 pcp(0, xi) = normal[xi] * normalCoord + (midx - halfMaxRange) * b1[xi] + (midy - halfMaxRange) * b2[xi];
304 pcp(1, xi) = normal[xi] * normalCoord + (midx + halfMaxRange) * b1[xi] + (midy - halfMaxRange) * b2[xi];
305 pcp(2, xi) = normal[xi] * normalCoord + (midx - halfMaxRange) * b1[xi] + (midy + halfMaxRange) * b2[xi];
306 pcp(3, xi) = normal[xi] * normalCoord + (midx + halfMaxRange) * b1[xi] + (midy + halfMaxRange) * b2[xi];
315 return addFace(V, ts);
324 unsigned int noMate(0);
325 for (
typename std::vector<gsSolidHalfEdgeHandle>::iterator it1=edge.begin(); it1!=edge.end()-1; ++it1)
327 for (
typename std::vector<gsSolidHalfEdgeHandle>::iterator it2=it1+1; it2!=edge.end(); ++it2)
330 gsSolidHeVertexHandle source1, source2, target1, target2;
331 source1 = (*it1)->source;
332 source2 = (*it2)->source;
333 target1 = (*it1)->next->source;
334 target2 = (*it2)->next->source;
335 if (source1 == target2 && source2 == target1)
344 if (2*noMate!=edge.size())
348 gsWarn <<
"The number of assignments of HE mates (="<< noMate <<
") is NOT equal to number of edges (not halfedges) (="<< edge.size()/2 <<
"), this is most likely because of the wrong order of the vertices of a face, or the model is not a manifold\n";
356 size_t nEdge = ncEdgeV1.size();
357 gsSolidHalfEdgeHandle he;
358 assert(nEdge==ncEdgeV2.size());
359 std::vector<gsSolidHalfEdgeHandle> nce;
360 for (
size_t i=0;i<nEdge;i++)
362 he = this->getVertexFromID(ncEdgeV1[i])->getHalfEdge( this->getVertexFromID(ncEdgeV2[i]) );
363 he->is_convex =
false;
364 he->mate->is_convex =
false;
375 gsSolidHalfFaceHandle f,
376 gsSolidHeVertexHandle startVertex, gsSolidHeVertexHandle endVertex,
gsBSpline<T> *domainSpline)
380 int numEdges = f->surf->domain().outer().size();
382 gsSolidHalfEdgeHandle nextEdge = endVertex->getHalfEdgeOnFace(f,
false);
383 gsSolidHalfEdgeHandle matesPrev = nextEdge->prev;
384 int nextEdgeIdx = f->indexOfEdge(nextEdge);
386 gsSolidHalfEdgeHandle prevEdge = startVertex->getHalfEdgeOnFace(f,
true);
387 gsSolidHalfEdgeHandle matesNext = prevEdge->next;
388 int prevEdgeIdx = f->indexOfEdge(prevEdge);
390 gsSolidHalfEdgeHandle newHE = this->makeSolidHalfEdge(startVertex, f);
392 newHE->setId(numHalfEdges++);
395 newHE->prev = prevEdge;
396 newHE->next = nextEdge;
397 prevEdge->next = newHE;
398 nextEdge->prev = newHE;
400 gsSolidHalfEdgeHandle mate = this->makeSolidHalfEdge(endVertex, f);
403 mate->setId(numHalfEdges++);
406 mate->prev = matesPrev;
407 mate->next = matesNext;
408 matesPrev->next = mate;
409 matesNext->prev = mate;
411 std::vector<gsSolidHalfEdgeHandle> newFaceBoundary;
412 newFaceBoundary.push_back(mate);
413 gsSolidHalfEdgeHandle tempEdge;
414 for(tempEdge = matesNext; tempEdge != mate; tempEdge = tempEdge->next)
416 newFaceBoundary.push_back(tempEdge);
420 std::vector<T> origKnots = domainSpline->
knots();
421 std::vector<T> mateKnots;
422 mateKnots.reserve( origKnots.size() );
423 T flipPoint = (*origKnots.begin()) + (*origKnots.rbegin());
424 for(
int i = origKnots.size() - 1; i >= 0; i--)
426 mateKnots.push_back(flipPoint - origKnots[i]);
433 typename gsPlanarDomain<T>::uPtr newDomain =
434 f->surf->domain().split((prevEdgeIdx + 1) % numEdges, nextEdgeIdx, domainSpline, reverseSpline);
435 if(prevEdgeIdx > nextEdgeIdx)
440 f->loop[0] = nextEdge;
449 edge.push_back( newHE );
450 edge.push_back( mate );
452 gsSolidHalfFaceHandle newFace =
new gsSolidHalfFace<T>();
453 newFace->surf = newTS;
454 newFace->setBoundary( newFaceBoundary );
455 face.push_back(newFace);
456 newFace->setId(numHalfFaces++);
457 newFace->vol = f->vol;
458 newFace->vol->face.push_back(newFace);
464 tempEdge->face = newFace;
465 tempEdge = tempEdge->next;
466 }
while(tempEdge != mate);
478 std::vector<gsCurve<T>*> loopv;
479 for (
unsigned i=0;i!=numHalfFaces;i++)
481 loopv = face[i]->surf->domain().outer().curves();
482 for (
unsigned j=0;j!=loopv.size();j++)
494 gsVolumeHandle newVol =
new gsVolumeBlock<T>;
495 volume.push_back(newVol);
496 newVol->setId(numVolumes++);
500 std::queue<gsSolidHalfFaceHandle> unprocessed;
501 unprocessed.push(startingFace);
502 std::set<gsSolidHalfFaceHandle> seen;
503 seen.insert(startingFace);
505 while(!unprocessed.empty())
508 gsSolidHalfFaceHandle nextFace = unprocessed.front();
511 nextFace->vol = newVol;
512 newVol->face.push_back(nextFace);
513 size_t numLoops = nextFace->loop.size();
515 for(
size_t i = 0; i < numLoops; i++)
517 gsSolidHalfEdgeHandle firstEdge = nextFace->loop[i];
518 gsSolidHalfEdgeHandle nextEdge = firstEdge;
521 gsSolidHalfFaceHandle neighbFace = nextEdge->mate->face;
522 if(seen.find(neighbFace) == seen.end())
524 unprocessed.push(neighbFace);
525 seen.insert(neighbFace);
527 nextEdge = nextEdge->next;
528 }
while(nextEdge != firstEdge);
533 unsigned foundFaces = 0;
534 GISMO_ASSERT(numVolumes == volume.size(),
"Number of volumes does not match");
535 for(
size_t idxV = 0; idxV < numVolumes; idxV++)
538 size_t numF = volume[idxV]->face.size();
539 for(
size_t inF = 0; inF < numF; inF++)
541 if(volume[idxV]->face[inF]->vol == volume[idxV])
543 volume[idxV]->face[outF] = volume[idxV]->face[inF];
548 volume[idxV]->face.resize(outF);
550 GISMO_ASSERT(foundFaces == face.size() && foundFaces == numHalfFaces,
551 "Failed to assign a volume for all faces.");
559 size_t numEdges = edge.size();
560 for(
size_t idxE = 0; idxE < numEdges; idxE++)
562 gsSolidHalfEdgeHandle e = edge[idxE];
563 if (e->mate->mate != e)
gsWarn<<
"Inconsistent solid graph.\n";
564 GISMO_ASSERT(e->prev->target() == e->source,
"Inconsistent solid graph");
565 GISMO_ASSERT(e->mate->face->vol == e->face->vol,
"Inconsistent solid graph");
566 GISMO_ASSERT(e->next->face == e->face,
"Inconsistent solid graph");
567 GISMO_ASSERT(e->next->prev == e,
"Inconsistent solid graph");
568 GISMO_ASSERT(e->prev->next == e,
"Inconsistent solid graph");
572 for(
size_t idxF = 0; idxF < numHalfFaces; idxF++)
574 gsSolidHalfFace<T> *f = face[idxF];
576 size_t numLoops = surf->domain().numLoops();
577 GISMO_ASSERT(numLoops == f->loop.size(),
"Number of holes in face does not match corresponding trimmed surface");
578 for(
size_t loopNum = 0; loopNum < numLoops; loopNum++)
580 gsSolidHalfEdge<T> *e = f->loop[loopNum];
582 size_t numCurves = curveLoop.size();
583 for(
size_t curveNum = 0; curveNum < numCurves; curveNum++)
585 gsMatrix<T> surfCoord = surf->vertexCoord(loopNum, curveNum);
587 (surfCoord - e->source->coords).norm() < 0.0001,
"Vertices in surface do not match vertex coordinates");
589 const gsMatrix<T>& thisCurveCoefs = curveLoop.curve(curveNum).coefs();
590 gsMatrix<T> thisCurveEnd = thisCurveCoefs.row(thisCurveCoefs.rows() - 1);
591 const gsMatrix<T>& nextCurveCoefs = curveLoop.curve((curveNum + 1) % numCurves).coefs();
592 gsMatrix<T> nextCurveStart = nextCurveCoefs.row(0);
593 GISMO_ASSERT((thisCurveEnd - nextCurveStart).norm() < 0.0001,
"gsCurveLoop did not close up");
596 GISMO_ASSERT(e == f->loop[loopNum],
"Face's loop did not close up properly");
604 GISMO_ASSERT(verts.size() >= 2,
"Unexpected number of vertices in new face");
607 std::vector<gsSolidHeVertexHandle> reorderedVerts;
608 reorderedVerts.push_back(verts[verts.size() - 1]);
609 for(
size_t iV = 0; iV < verts.size() - 1; iV++)
611 reorderedVerts.push_back(verts[iV]);
614 surf->cleanEndpoints(0.0000001);
618 size_t numLoops = surf->domain().numLoops();
619 for(
size_t loopNum = 0; loopNum < numLoops; loopNum++)
621 size_t numCurves = surf->domain().loop(loopNum).size();
622 for(
size_t curveNum = 0; curveNum < numCurves; curveNum++)
624 gsMatrix<T> surfCoord = surf->vertexCoord(loopNum, curveNum);
625 GISMO_ASSERT((surfCoord - reorderedVerts[curveNum]->coords).norm() < 0.0001,
"Vertices in surface do not match vertex coordinates");
632 gsMatrix<T> &surfRevCoefs = surfReverse->getTP()->coefs();
633 MasterSurface *genGeom =
dynamic_cast<MasterSurface *
>(surfReverse->getTP().get());
634 GISMO_ASSERT(genGeom != NULL,
"This procedure requires a gsGenericGeometry");
635 gsMatrix<T> revSupp = surfReverse->getTP()->support();
636 GISMO_ASSERT(revSupp.cols() == 2,
"Unexpected support");
639 testPt << 0.75 * revSupp(0, 0) + 0.25 * revSupp(0, 1), 0.75 * revSupp(0, 0) + 0.25 * revSupp(0, 1), 0.25 * revSupp(0, 0) + 0.75 * revSupp(0, 1), 0.25 * revSupp(0, 0) + 0.75 * revSupp(0, 1),
640 0.75 * revSupp(1, 0) + 0.25 * revSupp(1, 1), 0.25 * revSupp(1, 0) + 0.75 * revSupp(1, 1), 0.75 * revSupp(1, 0) + 0.25 * revSupp(1, 1), 0.25 * revSupp(1, 0) + 0.75 * revSupp(1, 1);
642 genGeom->eval_into(testPt, testVal1);
644 unsigned totalCPs = surfRevCoefs.rows();
645 unsigned dim = surfRevCoefs.cols();
646 unsigned blockSize = genGeom->basis().component(0).size();
647 for(
unsigned blockStart = 0; blockStart < totalCPs; blockStart += blockSize)
649 surfRevCoefs.block(blockStart, 0, blockSize, dim) =
650 surfRevCoefs.block(blockStart, 0, blockSize, dim).colwise().reverse().eval();
655 testPt << 0.25 * revSupp(0, 0) + 0.75 * revSupp(0, 1), 0.25 * revSupp(0, 0) + 0.75 * revSupp(0, 1), 0.75 * revSupp(0, 0) + 0.25 * revSupp(0, 1), 0.75 * revSupp(0, 0) + 0.25 * revSupp(0, 1),
656 0.75 * revSupp(1, 0) + 0.25 * revSupp(1, 1), 0.25 * revSupp(1, 0) + 0.75 * revSupp(1, 1), 0.75 * revSupp(1, 0) + 0.25 * revSupp(1, 1), 0.25 * revSupp(1, 0) + 0.75 * revSupp(1, 1);
658 genGeom->eval_into(testPt, testVal2);
660 gsMatrix<T> testRevCoefs = surfReverse->getTP()->coefs();
661 GISMO_ASSERT((testVal2 - testVal1).norm() < 0.0001,
"Surface was not correctly reversed");
666 numLoops = surfReverse->domain().numLoops();
667 for(
size_t loopNum = 0; loopNum < numLoops; loopNum++)
669 gsCurveLoop<T> & revCurveLoop = surfReverse->domain().loop(loopNum);
670 size_t numCurves = revCurveLoop.size();
671 for(
size_t curveNum = 0; curveNum < numCurves; curveNum++)
675 curveCoefs = curveCoefs.colwise().reverse().eval();
676 size_t rows = curveCoefs.rows();
677 for(
size_t cpIdx = 0; cpIdx < rows; cpIdx++)
679 curveCoefs(cpIdx, 0) = revSupp(0, 0) + revSupp(0, 1) - curveCoefs(cpIdx, 0);
684 std::reverse( revCurveLoop.curves().begin(), revCurveLoop.curves().end() );
688 for(
size_t loopNum = 0; loopNum < numLoops; loopNum++)
690 const gsCurveLoop<T> & revCurveLoop = surfReverse->domain().loop(loopNum);
691 size_t numCurves = revCurveLoop.size();
692 for(
size_t curveNum = 0; curveNum < numCurves; curveNum++)
695 const gsGeometry<T> & thisCurve = revCurveLoop.curve(curveNum);
696 const gsGeometry<T> & nextCurve = revCurveLoop.curve((curveNum + 1) % numCurves);
701 GISMO_ASSERT((thisEndPt - nextStartPt).norm() < 0.0001,
"Invalid curve loop");
703 gsMatrix<T> thisCoord = surfReverse->vertexCoord(loopNum, curveNum);
704 gsMatrix<T> otherCoord = surf->vertexCoord(loopNum, (numCurves - curveNum) % numCurves);
705 GISMO_ASSERT((otherCoord - thisCoord).norm() < 0.0001,
"Mate faces do not have matching vertices");
706 GISMO_ASSERT((otherCoord - reorderedVerts[(numCurves - curveNum) % numCurves]->coords).norm() < 0.0001,
"Vertices in surface do not match vertex coordinates");
711 gsSolidHalfEdgeHandle startEdge = reorderedVerts[0]->getHalfEdge(reorderedVerts[1]);
713 std::vector<gsSolidHeVertexHandle> newVerts, newVertsReverse;
714 for(
typename std::vector<gsSolidHeVertexHandle>::const_iterator iter = reorderedVerts.begin(); iter != reorderedVerts.end(); iter++)
716 addHeVertex((*iter)->coords(0), (*iter)->coords(1), (*iter)->coords(2));
717 newVerts.push_back(vertex[numVertices - 1]);
720 newVertsReverse.push_back(newVerts[0]);
721 for(
int i = newVerts.size() - 1; i > 0; i--) newVertsReverse.push_back(newVerts[i]);
723 gsSolidHalfFaceHandle frontFace = addFace(reorderedVerts, surf);
725 gsSolidHalfFaceHandle backFace = addFace(newVertsReverse, surfReverse);
726 backFace->vol = NULL;
728 frontFace->mate = backFace;
729 backFace->mate = frontFace;
732 size_t vertNum, numVerts = reorderedVerts.size();
733 for(vertNum = 0; vertNum < numVerts; vertNum++)
735 gsSolidHeVertex<T> *thisVert = reorderedVerts[vertNum];
736 gsSolidHeVertex<T> *nextVert = reorderedVerts[(vertNum + 1) % numVerts];
737 while(thisVert->hed->next->source != nextVert)
739 thisVert->hed = thisVert->hed->mate->next;
740 GISMO_ASSERT(thisVert->hed->source == thisVert,
"Inconsistent solid graph");
742 thisVert->hed = thisVert->hed->mate->next;
743 GISMO_ASSERT(thisVert->hed->source == thisVert,
"Inconsistent solid graph");
746 gsSolidHalfEdge<T> *he = startEdge;
748 gsSolidHalfEdgeHandle newFrontFaceEdge = frontFace->loop[0];
749 while(newFrontFaceEdge->source != reorderedVerts[0]) newFrontFaceEdge = newFrontFaceEdge->next;
750 gsSolidHalfEdgeHandle newBackFaceEdge = backFace->loop[0];
751 while(newBackFaceEdge->source != newVerts[1]) newBackFaceEdge = newBackFaceEdge->next;
755 he->mate->mate = newFrontFaceEdge;
756 newFrontFaceEdge->mate = he->mate;
758 he->mate = newBackFaceEdge;
759 newBackFaceEdge->mate = he;
762 GISMO_ASSERT(backFace->vol == NULL || backFace->vol == he->face->vol,
"Inconsistent solid graph");
763 backFace->vol = he->face->vol;
765 GISMO_ASSERT(newFrontFaceEdge->source == reorderedVerts[vertNum],
"Inconsistent solid graph");
766 GISMO_ASSERT(newBackFaceEdge->source == newVerts[(vertNum + 1) % numVerts],
"Inconsistent solid graph");
770 newFrontFaceEdge = newFrontFaceEdge->next;
771 newBackFaceEdge = newBackFaceEdge->prev;
773 gsSolidHeVertexHandle nextVert = reorderedVerts[(vertNum + 1) % numVerts];
778 GISMO_ASSERT(he->source->hed->source == he->source,
"Inconsistent solid graph");
779 if(he->source->hed == he) he->source->hed = newFrontFaceEdge;
780 he->source = newVerts[vertNum % numVerts];
781 if(he->next->source == nextVert || he == startEdge)
break;
782 GISMO_ASSERT(he->source->hed->source == he->source,
"Inconsistent solid graph");
783 GISMO_ASSERT(he->prev->target() == he->source,
"Inconsistent solid graph");
786 }
while(he != startEdge);
789 GISMO_ASSERT(backFace->vol != NULL,
"Could not find the volume for mate face");
790 backFace->vol->face.push_back(backFace);
793 newVolume(frontFace);
799 gsSolidHalfEdge<T>* he0;
800 he0 = frontFace->loop[0];
802 for (
size_t i=0;i<this->nHalfEdges();i++)
804 he->is_convex =
true;
805 he->mate->is_convex =
true;
806 if (he->target()==he0->source)
break;
810 he0 = frontFace->mate->loop[0];
812 for (
size_t i=0;i<this->nHalfEdges();i++)
814 he->is_convex =
true;
815 he->mate->is_convex =
true;
816 if (he->target()==he0->source)
break;
828 std::vector<gsSolidHeVertexHandle> v0,v1;
829 gsSolidHalfFaceHandle face0 = he->face;
830 gsSolidHalfFaceHandle face1 = he->mate->face;
831 v0 = face0->getVertices();
832 v1 = face1->getVertices();
834 typename std::vector<gsSolidHeVertexHandle>::iterator it,it0,it1;
835 for (it = v0.begin();it!=v0.end();++it)
837 if ( ((*it)==he->source) || ((*it)==he->target()) )
840 v0.erase(it0, it0 + 2);
841 for (it = v1.begin();it!=v1.end();++it)
843 if ( ((*it)==he->source) || ((*it)==he->target()) )
846 v1.erase(it0, it0 + 2);
848 std::vector<gsSolidHalfEdgeHandle> iHE,vHE;
849 typename std::vector<gsSolidHalfEdgeHandle>::iterator ite;
850 for (it0 = v0.begin();it0!=v0.end();++it0)
852 vHE = (*it0)->halfEdges();
853 for (ite = vHE.begin();ite!=vHE.end();++ite)
855 for (it1 = v1.begin();it1!=v1.end();++it1)
857 if ( (*ite)->target()== *it1) iHE.push_back(*ite);
869 gsSolidHalfEdgeHandle hem = he->mate;
870 gsSolidHalfFaceHandle face0,face1;
872 face1 = he->mate->face;
873 size_t nFace = this->nHalfFaces();
874 bool convex = he->is_convex;
875 int heLoopN = he->loopN();
876 int hemLoopN = hem->loopN();
878 size_t he_tCurveID = face0->indexOfEdge(he);
879 size_t hem_tCurveID = face1->indexOfEdge(hem);
880 gsMatrix<T> mid0 = face0->surf->splitCurve(he->loopN(), he_tCurveID);
882 face0->surf->getTP()->eval_into(mid0.transpose(), space0);
884 T nearestParam = face1->surf->nearestPoint(0, hem_tCurveID, 10, 10, space0);
885 gsMatrix<T> mid1 = face1->surf->splitCurve(hem->loopN(), hem_tCurveID, nearestParam);
887 face1->surf->getTP()->eval_into(mid1.transpose(), space1);
892 gsSolidHeVertexHandle s,n,t;
894 n =
new gsSolidHeVertex<T>(
895 0.5 * (space0(0, 0) + space1(0, 0)),
896 0.5 * (space0(1, 0) + space1(1, 0)),
897 0.5 * (space0(2, 0) + space1(2, 0)),
900 (this->vertex).push_back(n);
905 gsSolidHalfEdgeHandle sn =
new gsSolidHalfEdge<T>(s,face0,nFace,convex,heLoopN);
906 gsSolidHalfEdgeHandle nt =
new gsSolidHalfEdge<T>(n,face0,nFace+1,convex,heLoopN);
907 gsSolidHalfEdgeHandle tn =
new gsSolidHalfEdge<T>(t,face1,nFace+2,convex,hemLoopN);
908 gsSolidHalfEdgeHandle ns =
new gsSolidHalfEdge<T>(n,face1,nFace+3,convex,hemLoopN);
917 hem->prev->next = tn;
919 ns->next = hem->next;
920 hem->next->prev = ns;
922 tn->prev = hem->prev;
930 this->edge.push_back(sn);
931 this->edge.push_back(nt);
932 this->edge.push_back(tn);
933 this->edge.push_back(ns);
936 if ((face0->loop).at(he->loopN())==he) (face0->loop).at(he->loopN()) = sn;
937 if ((face1->loop).at(he->mate->loopN())==he->mate) (face1->loop).at(he->mate->loopN()) = tn;
940 if (s->hed == he) s->hed = he->prev->mate;
941 if (t->hed == hem) t->hed = hem->prev->mate;
944 int idmax = he->getId();
945 if (he->mate->getId()>idmax) idmax=he->mate->getId();
946 int idmin = he->getId();
947 if (he->mate->getId()<idmin) idmin=he->mate->getId();
949 for (
size_t i = idmax+1; i < this->nHalfEdges(); i++)
951 this->edge[i]->setId(i-1);
953 this->edge.erase(this->edge.begin() + idmax);
955 for (
size_t i = idmin+1; i < this->nHalfEdges(); i++)
957 this->edge[i]->setId(i-1);
959 this->edge.erase(this->edge.begin() + idmin);
961 this->numVertices = this->nVertices();
962 this->numHalfEdges = this->nHalfEdges();
963 this->numHalfFaces = this->nHalfFaces();
964 this->numVolumes = this->nVolumes();
965 gsDebug<<
"A new vertex is added to the halfedge with source: "<<*he->source<<
966 " and target: "<<*he->target()<<std::endl;
975 typename std::vector<gsSolidHalfEdgeHandle> iHe;
976 iHe=this->impedingEdges(he);
977 typename std::vector<gsSolidHalfEdgeHandle>::const_iterator it;
978 if (iHe.empty()==
false)
980 for (it=iHe.begin();it!=iHe.end();++it)
982 this->insertNewVertex(*it);
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition: gsMultiPatch.hpp:210
Knot vector for B-splines.
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
A fixed-size, statically allocated 3D vector.
Definition: gsVector.h:218
Class for a trim surface.
Definition: gsTrimSurface.h:33
#define gsDebug
Definition: gsDebug.h:61
gsVolumeBlock< T > * newVolume(gsSolidHalfFaceHandle startingFace)
Starting with a specified face, chase round all the faces connected to it and move them to a new volu...
Definition: gsSolid.hpp:491
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition: gsTensorBSpline.h:44
void insertNewVertex(gsSolidHalfEdgeHandle he)
Insert a new vertex to an edge of the volume.
Definition: gsSolid.hpp:866
void handleImpedingEdges(gsSolidHalfEdgeHandle he)
If there are impeding edges that make the solid inseparatable along a given HE he, this routine will create a new vertex on each impeding edges.
Definition: gsSolid.hpp:973
Provides interface of gsTrimSurface class. Represents a trimmed surface (= spline "master surface" in...
Represents a tensor-product B-spline patch.
S give(S &x)
Definition: gsMemory.h:266
gsMatrix< T > eval(const gsMatrix< T > &u) const
Evaluate the function,.
Definition: gsFunctionSet.hpp:120
void checkStructure(bool checkVerts=false) const
sanity checks on the graph structure of the solid
Definition: gsSolid.hpp:556
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
A B-spline function of one argument, with arbitrary target dimension.
Definition: gsBSpline.h:50
gsSolidHalfFaceHandle addFace_PlanarPolygon(std::vector< gsSolidHeVertexHandle > V)
Add a planar face, specified by a list of vertices that should all be in the same plane...
Definition: gsSolid.hpp:180
std::vector< gsSolidHalfEdgeHandle > detectNonConvexEdges(std::vector< int > const &ncEdgeV1, std::vector< int > const &ncEdgeV2)
Define (TODO: detect automatically) nonconvex edges.
Definition: gsSolid.hpp:353
#define gsWarn
Definition: gsDebug.h:50
Provides declaration of the MultiPatch class.
void addHeVertex(scalar_t const &x, scalar_t const &y, scalar_t const &z=0)
add coords to gsHeVertex, not yet pointers to HEs
Definition: gsSolid.hpp:51
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
KnotVectorType & knots(const int i=0)
Returns a reference to the knot vector.
Definition: gsBSpline.h:170
gsSolidHalfFaceHandle splitFace(gsSolidHalfFaceHandle f, gsSolidHeVertexHandle startVertex, gsSolidHeVertexHandle endVertex, gsBSpline< T > *domainSpline)
Definition: gsSolid.hpp:374
void setHeMate()
Assigning mates for each HE.
Definition: gsSolid.hpp:320
gsSolidHalfFaceHandle addFace(std::vector< gsSolidHeVertexHandle > V)
Definition: gsSolid.hpp:82
Represents a B-spline curve/function with one parameter.
static void adjustPolygonToUnitSquare(gsMatrix< T > &corners, T const margin)
Definition: gsCurveLoop.hpp:384
gsMultiPatch< T > plotEdgeGraph()
plot edge graph
Definition: gsSolid.hpp:475
Class representing a Planar domain with an outer boundary and a number of holes.
Definition: gsPlanarDomain.h:43
memory::shared_ptr< gsSurface > Ptr
Shared pointer for gsSurface.
Definition: gsSurface.h:35
gsMatrix< T > support() const
Returns the range of parameters (same as parameterRange())
Definition: gsGeometry.hpp:193
#define GISMO_UNUSED(x)
Definition: gsDebug.h:112
Class for representing a solid made up of vertices, edges, faces, and volumes.
Definition: gsSolid.h:32
Class for representing a knot vector.
Definition: gsKnotVector.h:79
A closed loop given by a collection of curves.
Definition: gsCurveLoop.h:36
virtual std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsSolid.hpp:35
memory::shared_ptr< gsTensorBSpline > Ptr
Shared pointer for gsTensorBSpline.
Definition: gsTensorBSpline.h:59
Interface for gsCurveLoop class, representing a loop of curves, in anticlockwise order.
gsSolidHalfFace< T > * addFaceWithMate(const std::vector< gsSolidHeVertexHandle > &Verts, gsTrimSurface< T > *surf)
Make a face that can be used as the mate of the given face, add both faces and split off a new volume...
Definition: gsSolid.hpp:602
std::vector< gsSolidHalfEdgeHandle > impedingEdges(gsSolidHalfEdgeHandle he) const
Definition: gsSolid.hpp:824
Provides declaration of gsPlanarDomain class. The outer boundary (m_loops[0]) is a loop of curves...
gsMatrix< T > & coefs()
Definition: gsGeometry.h:340