std::string gmshEdge::getAdditionalInfoString() { if(List_Nbr(c->Control_Points) > 0){ std::ostringstream sstream; sstream << "{"; for(int i = 0; i < List_Nbr(c->Control_Points); i++){ if(i) sstream << " "; Vertex *v; List_Read(c->Control_Points, i, &v); sstream << v->Num; } sstream << "}"; if(meshAttributes.method == MESH_TRANSFINITE){ sstream << " transfinite (" << meshAttributes.nbPointsTransfinite; int type = meshAttributes.typeTransfinite; if(std::abs(type) == 1) sstream << ", progression " << sign(type) * meshAttributes.coeffTransfinite; else if(std::abs(type) == 2) sstream << ", bump " << meshAttributes.coeffTransfinite; sstream << ")"; } if(meshAttributes.extrude) sstream << " extruded"; if(meshAttributes.reverseMesh) sstream << " reversed"; return sstream.str(); } else return GEdge::getAdditionalInfoString(); }
// Bezier static Vertex InterpolateBezier(Curve *Curve, double u, int derivee) { int NbCurves = (List_Nbr(Curve->Control_Points) - 1) / 3; int iCurve = (int)floor(u * (double)NbCurves); if(iCurve >= NbCurves) iCurve = NbCurves - 1; // u = 1 if(iCurve <= 0) iCurve = 0; double t1 = (double)(iCurve) / (double)(NbCurves); double t2 = (double)(iCurve+1) / (double)(NbCurves); double t = (u - t1) / (t2 - t1); Vertex *v[4]; for(int i = 0; i < 4; i++) { List_Read(Curve->Control_Points, iCurve * 3 + i , &v[i]); } if(Curve->geometry){ SPoint2 pp = InterpolateCubicSpline(v, t, Curve->mat, t1, t2, Curve->geometry,derivee); SPoint3 pt = Curve->geometry->point(pp); Vertex V; V.Pos.X = pt.x(); V.Pos.Y = pt.y(); V.Pos.Z = pt.z(); return V; } else return InterpolateCubicSpline(v, t, Curve->mat, derivee, t1, t2); }
bool gmshFace::containsPoint(const SPoint3 &pt) const { if(s->Typ == MSH_SURF_PLAN){ // OK to use the normal from the mean plane here: we compensate // for the (possibly wrong) orientation at the end double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c}; norme(n); double angle = 0.; double v[3] = {pt.x(), pt.y(), pt.z()}; for(int i = 0; i < List_Nbr(s->Generatrices); i++) { Curve *c; List_Read(s->Generatrices, i, &c); int N = (c->Typ == MSH_SEGM_LINE) ? 1 : 10; for(int j = 0; j < N; j++) { double u1 = (double)j / (double)N; double u2 = (double)(j + 1) / (double)N; Vertex p1 = InterpolateCurve(c, u1, 0); Vertex p2 = InterpolateCurve(c, u2, 0); double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z}; double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z}; angle += angle_plan(v, v1, v2, n); } } // we're inside if angle equals 2 * pi if(fabs(angle) > 2 * M_PI - 0.5 && fabs(angle) < 2 * M_PI + 0.5) return true; return false; } return false; }
bool iSRuledSurfaceASphere(Surface *s, SPoint3 ¢er, double &radius) { if(s->Typ != MSH_SURF_REGL && s->Typ != MSH_SURF_TRIC) return false; bool isSphere = true; Vertex *O = 0; Curve *C[4] = {0, 0, 0, 0}; for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) List_Read(s->Generatrices, i, &C[i]); if(List_Nbr(s->InSphereCenter)) { // it's on a sphere: get the center List_Read(s->InSphereCenter, 0, &O); } else{ // try to be intelligent (hum) for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) { if(C[i]->Typ != MSH_SEGM_CIRC && C[i]->Typ != MSH_SEGM_CIRC_INV){ isSphere = false; } else if(isSphere){ if(!i){ List_Read(C[i]->Control_Points, 1, &O); ((double *)center)[0] = O->Pos.X; ((double *)center)[1] = O->Pos.Y; ((double *)center)[2] = O->Pos.Z; } else{ Vertex *tmp; List_Read(C[i]->Control_Points, 1, &tmp); if(compareVertex(&O, &tmp)) isSphere = false; } } } } if (isSphere && C[0]){ Vertex *p = C[0]->beg; radius = sqrt ((p->Pos.X - center.x())+ (p->Pos.Y - center.y())+ (p->Pos.Z - center.z())); } return isSphere; }
int gmshEdge::minimumDrawSegments () const { int n = List_Nbr(c->Control_Points) - 1; if(!n) n = GEdge::minimumDrawSegments(); if(geomType() == Line && !c->geometry) return n; else return CTX::instance()->geom.numSubEdges * n; }
SVector3 gmshFace::normal(const SPoint2 ¶m) const { if(s->Typ != MSH_SURF_PLAN){ Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1); Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2); Vertex n = vu % vv; n.norme(); return SVector3(n.Pos.X, n.Pos.Y, n.Pos.Z); } else{ // We cannot use InterpolateSurface() for plane surfaces since it // relies on the mean plane, which does not respect the // orientation // FIXME: move this test at the end of the MeanPlane computation // routine--and store the correct normal, damn it! double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c}; norme(n); GPoint pt = point(param.x(), param.y()); double v[3] = {pt.x(), pt.y(), pt.z()}; int NP = 10, tries = 0; while(1){ tries++; double angle = 0.; for(int i = 0; i < List_Nbr(s->Generatrices); i++) { Curve *c; List_Read(s->Generatrices, i, &c); int N = (c->Typ == MSH_SEGM_LINE) ? 1 : NP; for(int j = 0; j < N; j++) { double u1 = (double)j / (double)N; double u2 = (double)(j + 1) / (double)N; Vertex p1 = InterpolateCurve(c, u1, 0); Vertex p2 = InterpolateCurve(c, u2, 0); double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z}; double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z}; angle += angle_plan(v, v1, v2, n); } } if(fabs(angle) < 0.5){ // we're outside NP *= 2; Msg::Debug("Could not compute normal of surface %d - retrying with %d points", tag(), NP); if(tries > 10){ Msg::Warning("Could not orient normal of surface %d", tag()); return SVector3(n[0], n[1], n[2]); } } else if(angle > 0) return SVector3(n[0], n[1], n[2]); else return SVector3(-n[0], -n[1], -n[2]); } } }
gmshRegion::gmshRegion(GModel *m, ::Volume *volume) : GRegion(m, volume->Num), v(volume) { for(int i = 0; i < List_Nbr(v->Surfaces); i++){ Surface *s; List_Read(v->Surfaces, i, &s); int ori; List_Read(v->SurfacesOrientations, i, &ori); GFace *f = m->getFaceByTag(abs(s->Num)); if(f){ l_faces.push_back(f); l_dirs.push_back(ori); f->addRegion(this); } else Msg::Error("Unknown surface %d", s->Num); } for(int i = 0; i < List_Nbr(v->SurfacesByTag); i++){ int is; List_Read(v->SurfacesByTag, i, &is); GFace *f = m->getFaceByTag(abs(is)); if(f){ l_faces.push_back(f); l_dirs.push_back(sign(is)); f->addRegion(this); } else Msg::Error("Unknown surface %d", is); } if(v->EmbeddedSurfaces){ for(int i = 0; i < List_Nbr(v->EmbeddedSurfaces); i++){ Surface *s; List_Read(v->EmbeddedSurfaces, i, &s); GFace *gf = m->getFaceByTag(abs(s->Num)); if(gf) addEmbeddedFace(gf); else Msg::Error("Unknown surface %d", s->Num); } } resetMeshAttributes(); }
static std::string list2string(List_T *list) { std::ostringstream sstream; for(int i = 0; i < List_Nbr(list); i++){ int num; List_Read(list, i, &num); if(i) sstream << ", "; sstream << num; } return sstream.str(); }
static Vertex InterpolateNurbs(Curve *Curve, double u, int derivee) { double Nb[1000]; int span = findSpan(u, Curve->degre, List_Nbr(Curve->Control_Points), Curve->k); basisFuns(u, span, Curve->degre, Curve->k, Nb); Vertex p; p.Pos.X = p.Pos.Y = p.Pos.Z = p.w = p.lc = 0.0; for(int i = Curve->degre; i >= 0; --i) { Vertex *v; List_Read(Curve->Control_Points, span - Curve->degre + i, &v); p.Pos.X += Nb[i] * v->Pos.X; p.Pos.Y += Nb[i] * v->Pos.Y; p.Pos.Z += Nb[i] * v->Pos.Z; p.w += Nb[i] * v->w; p.lc += Nb[i] * v->lc; } return p; }
void gmshRegion::resetMeshAttributes() { meshAttributes.recombine3D = v->Recombine3D; meshAttributes.method = v->Method; meshAttributes.QuadTri = v->QuadTri; meshAttributes.extrude = v->Extrude; if(meshAttributes.method == MESH_TRANSFINITE){ meshAttributes.corners.clear(); for(int i = 0; i < List_Nbr(v->TrsfPoints); i++){ Vertex *corn; List_Read(v->TrsfPoints, i, &corn); GVertex *gv = model()->getVertexByTag(corn->Num); if(gv) meshAttributes.corners.push_back(gv); else Msg::Error("Unknown vertex %d in transfinite attributes", corn->Num); } } }
void gmshFace::resetMeshAttributes() { meshAttributes.recombine = s->Recombine; meshAttributes.recombineAngle = s->RecombineAngle; meshAttributes.method = s->Method; meshAttributes.extrude = s->Extrude; if(meshAttributes.method == MESH_TRANSFINITE){ meshAttributes.transfiniteArrangement = s->Recombine_Dir; meshAttributes.transfiniteSmoothing = s->TransfiniteSmoothing; meshAttributes.corners.clear(); for(int i = 0; i < List_Nbr(s->TrsfPoints); i++){ Vertex *corn; List_Read(s->TrsfPoints, i, &corn); GVertex *gv = model()->getVertexByTag(corn->Num); if(gv) meshAttributes.corners.push_back(gv); else Msg::Error("Unknown vertex %d in transfinite attributes", corn->Num); } } meshAttributes.reverseMesh = s->ReverseMesh; }
static Vertex InterpolateExtrudedSurface(Surface *s, double u, double v) { Curve *c = FindCurve(s->Extrude->geo.Source); // find position of c in the list of generatrices int num = -1; for(int i = 0; i < List_Nbr(s->Generatrices); i++){ if(c == *(Curve**)List_Pointer(s->Generatrices, i)){ num = i; break; } } Vertex T; if(num < 0){ Msg::Error("Unknown curve in extruded surface"); return T; } switch(num){ case 0: T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * u, 0); s->Extrude->Extrude(v, T.Pos.X, T.Pos.Y, T.Pos.Z); return T; case 1: T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * v, 0); s->Extrude->Extrude(1. - u, T.Pos.X, T.Pos.Y, T.Pos.Z); return T; case 2: T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * (1. - u), 0); s->Extrude->Extrude(1. - v, T.Pos.X, T.Pos.Y, T.Pos.Z); return T; default: T = InterpolateCurve(c, c->ubeg + (c->uend - c->ubeg) * (1. - v), 0); s->Extrude->Extrude(u, T.Pos.X, T.Pos.Y, T.Pos.Z); return T; } }
// Uniform BSplines static Vertex InterpolateUBS(Curve *Curve, double u, int derivee) { bool periodic = (Curve->end == Curve->beg); int NbControlPoints = List_Nbr(Curve->Control_Points); int NbCurves = NbControlPoints + (periodic ? -1 : 1); int iCurve = (int)floor(u * (double)NbCurves); if(iCurve == NbCurves) iCurve -= 1; // u = 1 double t1 = (double)(iCurve) / (double)(NbCurves); double t2 = (double)(iCurve+1) / (double)(NbCurves); double t = (u - t1) / (t2 - t1); Vertex *v[4]; for(int i = 0; i < 4; i++) { int k; if (periodic) { k = (iCurve - 1 + i) % (NbControlPoints - 1); if (k < 0) k += NbControlPoints - 1; } else { k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints -1)); } List_Read(Curve->Control_Points, k , &v[i]); } if(Curve->geometry){ SPoint2 pp = InterpolateCubicSpline(v, t, Curve->mat, t1, t2, Curve->geometry,derivee); SPoint3 pt = Curve->geometry->point(pp); Vertex V; V.Pos.X = pt.x(); V.Pos.Y = pt.y(); V.Pos.Z = pt.z(); return V; } else return InterpolateCubicSpline(v, t, Curve->mat, derivee, t1, t2); }
int GModel::exportDiscreteGEOInternals() { if(_geo_internals) delete _geo_internals; _geo_internals = new GEO_Internals; for(viter it = firstVertex(); it != lastVertex(); it++){ Vertex *v = Create_Vertex((*it)->tag(), (*it)->x(), (*it)->y(), (*it)->z(), (*it)->prescribedMeshSizeAtVertex(), 1.0); Tree_Add(this->getGEOInternals()->Points, &v); } for(eiter it = firstEdge(); it != lastEdge(); it++){ if((*it)->geomType() == GEntity::DiscreteCurve){ Curve *c = Create_Curve((*it)->tag(), MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.); List_T *points = Tree2List(_geo_internals->Points); GVertex *gvb = (*it)->getBeginVertex(); GVertex *gve = (*it)->getEndVertex(); int nb = 2 ; c->Control_Points = List_Create(nb, 1, sizeof(Vertex *)); for(int i = 0; i < List_Nbr(points); i++) { Vertex *v; List_Read(points, i, &v); if (v->Num == gvb->tag()) { List_Add(c->Control_Points, &v); c->beg = v; } if (v->Num == gve->tag()) { List_Add(c->Control_Points, &v); c->end = v; } } End_Curve(c); Tree_Add(this->getGEOInternals()->Curves, &c); CreateReversedCurve(c); List_Delete(points); } } for(fiter it = firstFace(); it != lastFace(); it++){ if((*it)->geomType() == GEntity::DiscreteSurface){ Surface *s = Create_Surface((*it)->tag(), MSH_SURF_DISCRETE); std::list<GEdge*> edges = (*it)->edges(); s->Generatrices = List_Create(edges.size(), 1, sizeof(Curve *)); List_T *curves = Tree2List(_geo_internals->Curves); Curve *c; for(std::list<GEdge*>::iterator ite = edges.begin(); ite != edges.end(); ite++){ for(int i = 0; i < List_Nbr(curves); i++) { List_Read(curves, i, &c); if (c->Num == (*ite)->tag()) { List_Add(s->Generatrices, &c); } } } Tree_Add(this->getGEOInternals()->Surfaces, &s); List_Delete(curves); } } // TODO: create Volumes from discreteRegions Msg::Debug("Geo internal model has:"); Msg::Debug("%d Vertices", Tree_Nbr(_geo_internals->Points)); Msg::Debug("%d Edges", Tree_Nbr(_geo_internals->Curves)); Msg::Debug("%d Faces", Tree_Nbr(_geo_internals->Surfaces)); return 1; }
int GModel::importGEOInternals() { if(Tree_Nbr(_geo_internals->Points)) { List_T *points = Tree2List(_geo_internals->Points); for(int i = 0; i < List_Nbr(points); i++){ Vertex *p; List_Read(points, i, &p); GVertex *v = getVertexByTag(p->Num); if(!v){ v = new gmshVertex(this, p); add(v); } if(!p->Visible) v->setVisibility(0); } List_Delete(points); } if(Tree_Nbr(_geo_internals->Curves)) { List_T *curves = Tree2List(_geo_internals->Curves); for(int i = 0; i < List_Nbr(curves); i++){ Curve *c; List_Read(curves, i, &c); if(c->Num >= 0){ GEdge *e = getEdgeByTag(c->Num); if(!e && c->Typ == MSH_SEGM_COMPOUND){ std::vector<GEdge*> comp; for(unsigned int j = 0; j < c->compound.size(); j++){ GEdge *ge = getEdgeByTag(c->compound[j]); if(ge) comp.push_back(ge); } e = new GEdgeCompound(this, c->Num, comp); e->meshAttributes.method = c->Method; e->meshAttributes.nbPointsTransfinite = c->nbPointsTransfinite; e->meshAttributes.typeTransfinite = c->typeTransfinite; e->meshAttributes.coeffTransfinite = c->coeffTransfinite; e->meshAttributes.extrude = c->Extrude; e->meshAttributes.reverseMesh = c->ReverseMesh; add(e); } else if(!e && c->beg && c->end){ e = new gmshEdge(this, c, getVertexByTag(c->beg->Num), getVertexByTag(c->end->Num)); add(e); } else if(!e){ e = new gmshEdge(this, c, 0, 0); add(e); } if(!c->Visible) e->setVisibility(0); if(c->Color.type) e->setColor(c->Color.mesh); if(c->degenerated) { e->setTooSmall(true); } } } List_Delete(curves); } if(Tree_Nbr(_geo_internals->Surfaces)) { List_T *surfaces = Tree2List(_geo_internals->Surfaces); for(int i = 0; i < List_Nbr(surfaces); i++){ Surface *s; List_Read(surfaces, i, &s); GFace *f = getFaceByTag(s->Num); if(!f && s->Typ == MSH_SURF_COMPOUND){ std::list<GFace*> comp; for(unsigned int j = 0; j < s->compound.size(); j++){ GFace *gf = getFaceByTag(s->compound[j]); if(gf) comp.push_back(gf); } std::list<GEdge*> b[4]; for(int j = 0; j < 4; j++){ for(unsigned int k = 0; k < s->compoundBoundary[j].size(); k++){ GEdge *ge = getEdgeByTag(s->compoundBoundary[j][k]); if(ge) b[j].push_back(ge); } } int param = CTX::instance()->mesh.remeshParam; GFaceCompound::typeOfCompound typ = GFaceCompound::HARMONIC_CIRCLE; if (param == 1) typ = GFaceCompound::CONFORMAL_SPECTRAL; if (param == 2) typ = GFaceCompound::RADIAL_BASIS; if (param == 3) typ = GFaceCompound::HARMONIC_PLANE; if (param == 4) typ = GFaceCompound::CONVEX_CIRCLE; if (param == 5) typ = GFaceCompound::CONVEX_PLANE; if (param == 6) typ = GFaceCompound::HARMONIC_SQUARE; if (param == 7) typ = GFaceCompound::CONFORMAL_FE; int algo = CTX::instance()->mesh.remeshAlgo; f = new GFaceCompound(this, s->Num, comp, b[0], b[1], b[2], b[3], typ, algo); f->meshAttributes.recombine = s->Recombine; f->meshAttributes.recombineAngle = s->RecombineAngle; f->meshAttributes.method = s->Method; f->meshAttributes.extrude = s->Extrude; // transfinite import Added by Trevor Strickler. This helps when experimenting // to create compounds from transfinite surfs. Not having it does not break // anything Gmsh *officially* does right now, but maybe it was left out by mistake??? and could // cause problems later? f->meshAttributes.transfiniteArrangement = s->Recombine_Dir; f->meshAttributes.corners.clear(); for(int i = 0; i < List_Nbr(s->TrsfPoints); i++){ Vertex *corn; List_Read(s->TrsfPoints, i, &corn); GVertex *gv = f->model()->getVertexByTag(corn->Num); if(gv) f->meshAttributes.corners.push_back(gv); else Msg::Error("Unknown vertex %d in transfinite attributes", corn->Num); } add(f); if(s->EmbeddedCurves){ for(int i = 0; i < List_Nbr(s->EmbeddedCurves); i++){ Curve *c; List_Read(s->EmbeddedCurves, i, &c); GEdge *e = getEdgeByTag(abs(c->Num)); if(e) f->addEmbeddedEdge(e); else Msg::Error("Unknown curve %d", c->Num); } } if(s->EmbeddedPoints){ for(int i = 0; i < List_Nbr(s->EmbeddedPoints); i++){ Vertex *v; List_Read(s->EmbeddedPoints, i, &v); GVertex *gv = getVertexByTag(v->Num); if(gv) f->addEmbeddedVertex(gv); else Msg::Error("Unknown point %d", v->Num); } } } else if(!f){ f = new gmshFace(this, s); add(f); } else f->resetMeshAttributes(); if(!s->Visible) f->setVisibility(0); if(s->Color.type) f->setColor(s->Color.mesh); } List_Delete(surfaces); } if(Tree_Nbr(_geo_internals->Volumes)) { List_T *volumes = Tree2List(_geo_internals->Volumes); for(int i = 0; i < List_Nbr(volumes); i++){ Volume *v; List_Read(volumes, i, &v); GRegion *r = getRegionByTag(v->Num); if(!r && v->Typ == MSH_VOLUME_COMPOUND){ std::vector<GRegion*> comp; for(unsigned int j = 0; j < v->compound.size(); j++){ GRegion *gr = getRegionByTag(v->compound[j]); if(gr) comp.push_back(gr); } r = new GRegionCompound(this, v->Num, comp); if(v->EmbeddedSurfaces){ for(int i = 0; i < List_Nbr(v->EmbeddedSurfaces); i++){ Surface *s; List_Read(v->EmbeddedSurfaces, i, &s); GFace *gf = getFaceByTag(abs(s->Num)); if(gf) r->addEmbeddedFace(gf); else Msg::Error("Unknown surface %d", s->Num); } } add(r); } else if(!r){ r = new gmshRegion(this, v); add(r); } else r->resetMeshAttributes(); if(!v->Visible) r->setVisibility(0); if(v->Color.type) r->setColor(v->Color.mesh); } List_Delete(volumes); } for(int i = 0; i < List_Nbr(_geo_internals->PhysicalGroups); i++){ PhysicalGroup *p; List_Read(_geo_internals->PhysicalGroups, i, &p); for(int j = 0; j < List_Nbr(p->Entities); j++){ int num; List_Read(p->Entities, j, &num); GEntity *ge = 0; int tag = CTX::instance()->geom.orientedPhysicals ? abs(num) : num; switch(p->Typ){ case MSH_PHYSICAL_POINT: ge = getVertexByTag(tag); break; case MSH_PHYSICAL_LINE: ge = getEdgeByTag(tag); break; case MSH_PHYSICAL_SURFACE: ge = getFaceByTag(tag); break; case MSH_PHYSICAL_VOLUME: ge = getRegionByTag(tag); break; } int pnum = CTX::instance()->geom.orientedPhysicals ? (sign(num) * p->Num) : p->Num; if(ge && std::find(ge->physicals.begin(), ge->physicals.end(), pnum) == ge->physicals.end()) ge->physicals.push_back(pnum); } } // create periodic mesh relationships for (std::map<int,int>::iterator it = _geo_internals->periodicEdges.begin(); it != _geo_internals->periodicEdges.end(); ++it){ GEdge *ge = getEdgeByTag(abs(it->first)); if (ge){ int MASTER = it->second * (it->first > 0 ? 1 : -1); ge->setMeshMaster(MASTER); } } for (std::map<int,int>::iterator it = _geo_internals->periodicFaces.begin(); it != _geo_internals->periodicFaces.end(); ++it){ GFace *gf = getFaceByTag(abs(it->first)); if (gf)gf->setMeshMaster(it->second * (it->first > 0 ? 1 : -1)); } for (eiter it = firstEdge() ; it != lastEdge() ; ++it){ int meshMaster = (*it)->meshMaster(); if (meshMaster != (*it)->tag()){ GEdge *ge_master = getEdgeByTag(abs(meshMaster)); if(ge_master)(*it)->getBeginVertex()->setMeshMaster ( (meshMaster > 0) ? ge_master->getBeginVertex()->tag() : ge_master->getEndVertex()->tag()); if(ge_master)(*it)->getEndVertex()->setMeshMaster ( (meshMaster < 0) ? ge_master->getBeginVertex()->tag() : ge_master->getEndVertex()->tag()); } } Msg::Debug("Gmsh model (GModel) imported:"); Msg::Debug("%d Vertices", vertices.size()); Msg::Debug("%d Edges", edges.size()); Msg::Debug("%d Faces", faces.size()); Msg::Debug("%d Regions", regions.size()); return 1; }
gmshFace::gmshFace(GModel *m, Surface *face) : GFace(m, face->Num), s(face), isSphere(false), radius(0.) { resetMeshAttributes(); // edgeCounterparts = s->edgeCounterparts; // affineTransform = s->affineTransform; std::vector<GEdge*> eds; std::vector<int> nums; for(int i = 0; i < List_Nbr(s->Generatrices); i++){ Curve *c; List_Read(s->Generatrices, i, &c); GEdge *e = m->getEdgeByTag(abs(c->Num)); if(e){ eds.push_back(e); nums.push_back(c->Num); } else Msg::Error("Unknown curve %d", c->Num); } for(int i = 0; i < List_Nbr(s->GeneratricesByTag); i++){ int j; List_Read(s->GeneratricesByTag, i, &j); GEdge *e = m->getEdgeByTag(abs(j)); if(e){ eds.push_back(e); nums.push_back(j); } else Msg::Error("Unknown curve %d", j); } std::list<GEdge*> l_wire; GVertex *first = 0; for(unsigned int i = 0; i < eds.size(); i++){ GEdge *e = eds[i]; int num = nums[i]; GVertex *start = (num > 0) ? e->getBeginVertex() : e->getEndVertex(); GVertex *next = (num > 0) ? e->getEndVertex() : e->getBeginVertex(); if (!first) first = start; l_wire.push_back(e); if (next == first){ edgeLoops.push_back(GEdgeLoop(l_wire)); l_wire.clear(); first = 0; } l_edges.push_back(e); e->addFace(this); l_dirs.push_back((num > 0) ? 1 : -1); if (List_Nbr(s->Generatrices) == 2){ e->meshAttributes.minimumMeshSegments = std::max(e->meshAttributes.minimumMeshSegments, 2); } } // always compute and store the mean plane for plane surfaces (using // the bounding vertices) if(s->Typ == MSH_SURF_PLAN) computeMeanPlane(); if(s->EmbeddedCurves){ for(int i = 0; i < List_Nbr(s->EmbeddedCurves); i++){ Curve *c; List_Read(s->EmbeddedCurves, i, &c); GEdge *e = m->getEdgeByTag(abs(c->Num)); if(e) addEmbeddedEdge(e); else Msg::Error("Unknown curve %d", c->Num); } } if(s->EmbeddedPoints){ for(int i = 0; i < List_Nbr(s->EmbeddedPoints); i++){ Vertex *v; List_Read(s->EmbeddedPoints, i, &v); GVertex *gv = m->getVertexByTag(v->Num); if(gv) embedded_vertices.push_back(gv); else Msg::Error("Unknown point %d", v->Num); } } isSphere = iSRuledSurfaceASphere(s, center, radius); }
void gmshEdge::discretize(double tol, std::vector<SPoint3> &pts, std::vector<double> &ts) { switch(c->Typ) { case MSH_SEGM_LINE : { int NPt = List_Nbr(c->Control_Points); pts.resize(NPt); ts.resize(NPt); for (int i = 0; i < NPt; ++i) { pts[i]= curveGetPoint(c, i); ts[i] = i / (double) (NPt - 1); } return; } case MSH_SEGM_BEZIER : { int NbCurves = (List_Nbr(c->Control_Points) - 1) / 3; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); SPoint3 pt[4]; for(int i = 0; i < 4; i++) { pt[i] = curveGetPoint(c, iCurve * 3 + i); } std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, pt[0], pt[1], pt[2], pt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } case MSH_SEGM_BSPLN: { bool periodic = (c->end == c->beg); int NbControlPoints = List_Nbr(c->Control_Points); int NbCurves = NbControlPoints + (periodic ? -1 : 1); SPoint3 pt[4]; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); for(int i = 0; i < 4; i++) { int k; if (periodic) { k = (iCurve - 1 + i) % (NbControlPoints - 1); if (k < 0) k += NbControlPoints - 1; } else { k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints -1)); } pt[i] = curveGetPoint(c, k); } SPoint3 bpt[4] = { (pt[0] + pt[1] * 4 + pt[2]) * (1./6.), (pt[1] * 2 + pt[2]) * (1./3.), (pt[1] + pt[2] * 2) * (1./3.), (pt[1] + pt[2] * 4 + pt[3]) * (1./6.) }; std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } case MSH_SEGM_SPLN: { int NbCurves = List_Nbr(c->Control_Points) - 1; SPoint3 pt[4]; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); pt[1] = curveGetPoint(c, iCurve); pt[2] = curveGetPoint(c, iCurve + 1); if(iCurve == 0) { if(c->beg == c->end) pt[0] = curveGetPoint(c, NbCurves - 1); else pt[0] = SPoint3(pt[1] * 2 - pt[2]); } else pt[0] = curveGetPoint(c, iCurve - 1); if(iCurve == NbCurves - 1) { if(c->beg == c->end) pt[3] = curveGetPoint(c, 1); else pt[3] = SPoint3(2 * pt[2] - pt[1]); } else pt[3] = curveGetPoint(c, iCurve + 2); SPoint3 bpt[4] = { pt[1], (pt[1] * 6 + pt[2] - pt[0]) * (1./6.), (pt[2] * 6 - pt[3] + pt[1]) * (1./6.), pt[2] }; std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } default : GEdge::discretize(tol, pts, ts); } }
void gmshEdge::writeGEO(FILE *fp) { if(!c || c->Num < 0 || c->Typ == MSH_SEGM_DISCRETE) return; switch (c->Typ) { case MSH_SEGM_LINE: fprintf(fp, "Line(%d) = ", c->Num); break; case MSH_SEGM_CIRC: case MSH_SEGM_CIRC_INV: fprintf(fp, "Circle(%d) = ", c->Num); break; case MSH_SEGM_ELLI: case MSH_SEGM_ELLI_INV: fprintf(fp, "Ellipse(%d) = ", c->Num); break; case MSH_SEGM_NURBS: fprintf(fp, "Nurbs(%d) = {", c->Num); for(int i = 0; i < List_Nbr(c->Control_Points); i++) { Vertex *v; List_Read(c->Control_Points, i, &v); if(!i) fprintf(fp, "%d", v->Num); else fprintf(fp, ", %d", v->Num); if(i % 8 == 7 && i != List_Nbr(c->Control_Points) - 1) fprintf(fp, "\n"); } fprintf(fp, "}\n"); fprintf(fp, " Knots {"); for(int j = 0; j < List_Nbr(c->Control_Points) + c->degre + 1; j++) { if(!j) fprintf(fp, "%.16g", c->k[j]); else fprintf(fp, ", %.16g", c->k[j]); if(j % 5 == 4 && j != List_Nbr(c->Control_Points) + c->degre) fprintf(fp, "\n "); } fprintf(fp, "}\n"); fprintf(fp, " Order %d;\n", c->degre); return; case MSH_SEGM_SPLN: fprintf(fp, "Spline(%d) = ", c->Num); break; case MSH_SEGM_BSPLN: fprintf(fp, "BSpline(%d) = ", c->Num); break; case MSH_SEGM_BEZIER: fprintf(fp, "Bezier(%d) = ", c->Num); break; default: Msg::Error("Unknown curve type %d", c->Typ); return; } for(int i = 0; i < List_Nbr(c->Control_Points); i++) { Vertex *v; List_Read(c->Control_Points, i, &v); if(i) fprintf(fp, ", %d", v->Num); else fprintf(fp, "{%d", v->Num); if(i % 6 == 7) fprintf(fp, "\n"); } fprintf(fp, "};\n"); if(meshAttributes.method == MESH_TRANSFINITE){ fprintf(fp, "Transfinite Line {%d} = %d", tag() * (meshAttributes.typeTransfinite > 0 ? 1 : -1), meshAttributes.nbPointsTransfinite); if(meshAttributes.typeTransfinite){ if(std::abs(meshAttributes.typeTransfinite) == 1) fprintf(fp, "Using Progression "); else if(std::abs(meshAttributes.typeTransfinite) == 2) fprintf(fp, "Using Bump "); fprintf(fp, "%g", meshAttributes.coeffTransfinite); } fprintf(fp, ";\n"); } if(meshAttributes.reverseMesh) fprintf(fp, "Reverse Line {%d};\n", tag()); }
SPoint2 gmshEdge::reparamOnFace(const GFace *face, double epar,int dir) const { Surface *s = (Surface*) face->getNativePtr(); bool periodic = (c->end == c->beg); if(s->geometry){ switch (c->Typ) { case MSH_SEGM_LINE: { Vertex *v[3]; List_Read(c->Control_Points, 0, &v[1]); List_Read(c->Control_Points, 1, &v[2]); SPoint2 p = v[1]->pntOnGeometry + (v[2]->pntOnGeometry - v[1]->pntOnGeometry) * epar; return p; } case MSH_SEGM_BSPLN: case MSH_SEGM_BEZIER: { int NbControlPoints = List_Nbr(c->Control_Points); int NbCurves = NbControlPoints + (periodic ? -1 : 1); int iCurve = (int)floor(epar * (double)NbCurves); if(iCurve >= NbCurves) iCurve = NbCurves - 1; else if (iCurve < 0) // ? does it happen ? iCurve = 0; double t1 = (double)(iCurve) / (double)(NbCurves); double t2 = (double)(iCurve+1) / (double)(NbCurves); double t = (epar - t1) / (t2 - t1); Vertex *v[4]; for(int j = 0; j < 4; j ++ ){ int k = iCurve - (periodic ? 1 : 2) + j; if(k < 0) k = periodic ? k + NbControlPoints - 1 : 0; if(k >= NbControlPoints) k = periodic ? k - NbControlPoints + 1: NbControlPoints - 1; List_Read(c->Control_Points, k, &v[j]); } return InterpolateCubicSpline(v, t, c->mat, t1, t2, c->geometry,0); } case MSH_SEGM_SPLN : { Vertex temp1, temp2; int N = List_Nbr(c->Control_Points); int i = (int)((double)(N - 1) * epar); if(i < 0) i = 0; if(i >= N - 1) i = N - 2; double t1 = (double)(i) / (double)(N - 1); double t2 = (double)(i + 1) / (double)(N - 1); double t = (epar - t1) / (t2 - t1); Vertex *v[4]; List_Read(c->Control_Points, i, &v[1]); List_Read(c->Control_Points, i + 1, &v[2]); if(!i) { if(c->beg == c->end){ List_Read(c->Control_Points,N-2,&v[0]); } else{ v[0] = &temp1; v[0]->pntOnGeometry = v[1]->pntOnGeometry * 2. - v[2]->pntOnGeometry; } } else{ List_Read(c->Control_Points, i - 1, &v[0]); } if(i == N - 2) { if(c->beg == c->end){ List_Read(c->Control_Points,1,&v[3]); } else{ v[3] = &temp2; v[3]->pntOnGeometry = v[2]->pntOnGeometry * 2. - v[1]->pntOnGeometry; } } else{ List_Read(c->Control_Points, i + 2, &v[3]); } return InterpolateCubicSpline(v, t, c->mat, t1, t2, c->geometry,0); } default: Msg::Error("Unknown edge type in reparamOnFace"); return SPoint2(); } } if(s->Typ == MSH_SURF_REGL){ Curve *C[4]; for(int i = 0; i < 4; i++) List_Read(s->Generatrices, i, &C[i]); double U, V; if (C[0]->Num == c->Num) { U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ; V = 0; } else if (C[0]->Num == -c->Num) { U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ; V = 0; } else if (C[1]->Num == c->Num) { V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ; U = 1; } else if (C[1]->Num == -c->Num) { V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ; U = 1; } else if (C[2]->Num == c->Num) { U = 1 - (epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ; V = 1; } else if (C[2]->Num == -c->Num) { U = 1 - ( C[2]->uend -epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ; V = 1; } else if (C[3]->Num == c->Num) { V = 1-(epar - C[3]->ubeg) / (C[3]->uend - C[3]->ubeg) ; U = 0; } else if (C[3]->Num == -c->Num) { V = 1-(C[3]->uend - epar - C[3]->ubeg) / (C[3]->uend - C[3]->ubeg) ; U = 0; } else{ Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num); return GEdge::reparamOnFace(face, epar, dir); } return SPoint2(U, V); } else if (s->Typ == MSH_SURF_TRIC){ Curve *C[3]; for(int i = 0; i < 3; i++) List_Read(s->Generatrices, i, &C[i]); double U, V; if(CTX::instance()->geom.oldRuledSurface){ if (C[0]->Num == c->Num) { U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ; V = 0; } else if (C[0]->Num == -c->Num) { U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ; V = 0; } else if (C[1]->Num == c->Num) { V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ; U = 1; } else if (C[1]->Num == -c->Num) { V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ; U = 1; } else if (C[2]->Num == c->Num) { U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ; V = 1; } else if (C[2]->Num == -c->Num) { U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ; V = 1; } else{ Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num); return GEdge::reparamOnFace(face, epar, dir); } } else{ // FIXME: workaround for exact extrusions bool hack = false; if(CTX::instance()->geom.exactExtrusion && s->Extrude && s->Extrude->geo.Mode == EXTRUDED_ENTITY && s->Typ != MSH_SURF_PLAN) hack = true; if (C[0]->Num == c->Num) { U = (epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ; V = 0; } else if (C[0]->Num == -c->Num) { U = (C[0]->uend - epar - C[0]->ubeg) / (C[0]->uend - C[0]->ubeg) ; V = 0; } else if (C[1]->Num == c->Num) { V = (epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ; U = 1; } else if (C[1]->Num == -c->Num) { V = (C[1]->uend - epar - C[1]->ubeg) / (C[1]->uend - C[1]->ubeg) ; U = 1; } else if (C[2]->Num == c->Num) { U = 1-(epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ; V = hack ? 1 : U; } else if (C[2]->Num == -c->Num) { U = 1-(C[2]->uend - epar - C[2]->ubeg) / (C[2]->uend - C[2]->ubeg) ; V = hack ? 1 : U; } else{ Msg::Info("Reparameterizing edge %d on face %d", c->Num, s->Num); return GEdge::reparamOnFace(face, epar, dir); } } return SPoint2(U, V); } else{ return GEdge::reparamOnFace(face, epar, dir); } }
static Vertex InterpolateRuledSurface(Surface *s, double u, double v) { Curve *C[4] = {0, 0, 0, 0}; for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) List_Read(s->Generatrices, i, &C[i]); Vertex *O = 0; bool isSphere = true; // Ugly hack: "fix" transfinite interpolation if we have a sphere // patch if(List_Nbr(s->InSphereCenter)) { // it's on a sphere: get the center List_Read(s->InSphereCenter, 0, &O); } else{ // try to be intelligent (hum) for(int i = 0; i < std::min(List_Nbr(s->Generatrices), 4); i++) { if(C[i]->Typ != MSH_SEGM_CIRC && C[i]->Typ != MSH_SEGM_CIRC_INV){ isSphere = false; } else if(isSphere){ if(!i){ List_Read(C[i]->Control_Points, 1, &O); } else{ Vertex *tmp; List_Read(C[i]->Control_Points, 1, &tmp); if(compareVertex(&O, &tmp)) isSphere = false; } } } if(isSphere){ double n[3] = {C[0]->Circle.invmat[0][2], C[0]->Circle.invmat[1][2], C[0]->Circle.invmat[2][2]}; bool isPlane = true; for(int i = 1; i < std::min(List_Nbr(s->Generatrices), 4); i++) isPlane &= (n[0] == C[i]->Circle.invmat[0][2] && n[1] == C[i]->Circle.invmat[1][2] && n[2] == C[i]->Circle.invmat[2][2]); if(isPlane) isSphere = false; } } Vertex *S[4], V[4],VB[3], T; if(s->Typ == MSH_SURF_REGL && List_Nbr(s->Generatrices) >= 4){ S[0] = C[0]->beg; S[1] = C[1]->beg; S[2] = C[2]->beg; S[3] = C[3]->beg; V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0); V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0); V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0); V[3] = InterpolateCurve(C[3], C[3]->ubeg + (C[3]->uend - C[3]->ubeg) * (1. - v), 0); /* #if defined(HAVE_BFGS) printf("----- u %f v %f %g %g\n", u, v,C[1]->ubeg,C[1]->uend); printf("S[0] %f %f %f\n", S[0]->Pos.X, S[0]->Pos.Y,S[0]->Pos.Z); printf("S[1] %f %f %f\n", S[1]->Pos.X, S[1]->Pos.Y,S[1]->Pos.Z); printf("S[2] %f %f %f\n", S[2]->Pos.X, S[2]->Pos.Y,S[2]->Pos.Z); printf("S[3] %f %f %f\n", S[3]->Pos.X, S[3]->Pos.Y,S[3]->Pos.Z); printf("V[0] %f %f %f\n", V[0].Pos.X, V[0].Pos.Y,V[0].Pos.Z); printf("V[1] %f %f %f\n", V[1].Pos.X, V[1].Pos.Y,V[1].Pos.Z); printf("V[2] %f %f %f\n", V[2].Pos.X, V[2].Pos.Y,V[2].Pos.Z); printf("V[3] %f %f %f\n", V[3].Pos.X, V[3].Pos.Y,V[3].Pos.Z); #endif */ T = TransfiniteQua(V[0], V[1], V[2], V[3], *S[0], *S[1], *S[2], *S[3], u, v); if(isSphere) TransfiniteSph(*S[0], *O, &T); } else if(List_Nbr(s->Generatrices) >= 3){ S[0] = C[0]->beg; S[1] = C[1]->beg; S[2] = C[2]->beg; if(CTX::instance()->geom.oldRuledSurface){ V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0); V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0); V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0); T = TransfiniteTri(V[0], V[1], V[2], *S[0], *S[1], *S[2], u, v); } else{ V[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * (u-v), 0); V[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * v, 0); V[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - u), 0); VB[0] = InterpolateCurve(C[0], C[0]->ubeg + (C[0]->uend - C[0]->ubeg) * u, 0); VB[1] = InterpolateCurve(C[1], C[1]->ubeg + (C[1]->uend - C[1]->ubeg) * (1-u+v), 0); VB[2] = InterpolateCurve(C[2], C[2]->ubeg + (C[2]->uend - C[2]->ubeg) * (1. - v), 0); T = TransfiniteTriB(V[0],VB[0], V[1],VB[1], V[2],VB[2], *S[0], *S[1], *S[2], u, v); } if(isSphere) { TransfiniteSph(*S[0], *O, &T); } } return T; }
Vertex InterpolateCurve(Curve *c, double u, int derivee) { if(c->Num < 0) { Curve *C0 = FindCurve(-c->Num); if(!C0){ Msg::Error("Unknown curve %d", -c->Num); return Vertex(0., 0., 0.); } return InterpolateCurve(C0, C0->ubeg + (C0->uend - C0->ubeg) * (1. - u), derivee); } Vertex V; if(derivee==1) { // switch (c->Typ) { // case MSH_SEGM_BSPLN: // case MSH_SEGM_BEZIER: // V = InterpolateUBS(c, u, 1); // V.u = u; // break; // default : double eps1 = (u == 0) ? 0 : 1.e-5; double eps2 = (u == 1) ? 0 : 1.e-5; Vertex D[2]; D[0] = InterpolateCurve(c, u - eps1, 0); D[1] = InterpolateCurve(c, u + eps2, 0); V.Pos.X = (D[1].Pos.X - D[0].Pos.X) / (eps1 + eps2); V.Pos.Y = (D[1].Pos.Y - D[0].Pos.Y) / (eps1 + eps2); V.Pos.Z = (D[1].Pos.Z - D[0].Pos.Z) / (eps1 + eps2); V.u = u; // break; // } return V; } if(derivee==2) { switch (c->Typ) { case MSH_SEGM_BSPLN: V = InterpolateUBS(c, u, 2); V.u = u; break; case MSH_SEGM_BEZIER: V = InterpolateBezier(c, u, 2); V.u = u; break; default : double eps1 = (u == 0) ? 0 : 1.e-5; double eps2 = (u == 1) ? 0 : 1.e-5; Vertex D[2]; D[0] = InterpolateCurve(c, u - eps1, 1); D[1] = InterpolateCurve(c, u + eps2, 1); V.Pos.X = (D[1].Pos.X - D[0].Pos.X) / (eps1 + eps2); V.Pos.Y = (D[1].Pos.Y - D[0].Pos.Y) / (eps1 + eps2); V.Pos.Z = (D[1].Pos.Z - D[0].Pos.Z) / (eps1 + eps2); V.u = u; break; } return V; } int N, i; Vertex *v[5]; double theta, t1, t2, t; Vertex temp1, temp2; switch (c->Typ) { case MSH_SEGM_LINE: #if defined(HAVE_BFGS) // printf("MSH_SEGM_LINE\n"); #endif N = List_Nbr(c->Control_Points); i = (int)((double)(N - 1) * u); while(i >= N - 1) i--; while(i < 0) i++; t1 = (double)(i) / (double)(N - 1); t2 = (double)(i + 1) / (double)(N - 1); t = (u - t1) / (t2 - t1); List_Read(c->Control_Points, i, &v[1]); List_Read(c->Control_Points, i + 1, &v[2]); if(!c->geometry){ V.Pos.X = v[1]->Pos.X + t * (v[2]->Pos.X - v[1]->Pos.X); V.Pos.Y = v[1]->Pos.Y + t * (v[2]->Pos.Y - v[1]->Pos.Y); V.Pos.Z = v[1]->Pos.Z + t * (v[2]->Pos.Z - v[1]->Pos.Z); V.w = (1. - t) * v[1]->w + t * v[2]->w; V.lc = (1. - t) * v[1]->lc + t * v[2]->lc; } else{ SPoint2 p = v[1]->pntOnGeometry + (v[2]->pntOnGeometry - v[1]->pntOnGeometry) * t; SPoint3 pp = c->geometry->point(p); V.Pos.X = pp.x(); V.Pos.Y = pp.y(); V.Pos.Z = pp.z(); } break; case MSH_SEGM_CIRC: case MSH_SEGM_CIRC_INV: case MSH_SEGM_ELLI: case MSH_SEGM_ELLI_INV: if(c->Typ == MSH_SEGM_CIRC_INV || c->Typ == MSH_SEGM_ELLI_INV) { V.u = 1. - u; u = V.u; } theta = c->Circle.t1 - (c->Circle.t1 - c->Circle.t2) * u; theta -= c->Circle.incl; // for ellipses V.Pos.X = c->Circle.f1 * cos(theta) * cos(c->Circle.incl) - c->Circle.f2 * sin(theta) * sin(c->Circle.incl); V.Pos.Y = c->Circle.f1 * cos(theta) * sin(c->Circle.incl) + c->Circle.f2 * sin(theta) * cos(c->Circle.incl); V.Pos.Z = 0.0; Projette(&V, c->Circle.invmat); List_Read(c->Control_Points, 1, &v[0]); V.Pos.X += v[0]->Pos.X; V.Pos.Y += v[0]->Pos.Y; V.Pos.Z += v[0]->Pos.Z; V.w = (1. - u) * c->beg->w + u * c->end->w; V.lc = (1. - u) * c->beg->lc + u * c->end->lc; break; case MSH_SEGM_BSPLN: V = InterpolateUBS(c, u, 0); break; case MSH_SEGM_BEZIER: V = InterpolateBezier(c, u, 0); break; case MSH_SEGM_NURBS: V = InterpolateNurbs(c, u, 0); break; case MSH_SEGM_SPLN: N = List_Nbr(c->Control_Points); i = (int)((double)(N - 1) * u); if(i < 0) i = 0; if(i >= N - 1) i = N - 2; t1 = (double)(i) / (double)(N - 1); t2 = (double)(i + 1) / (double)(N - 1); t = (u - t1) / (t2 - t1); List_Read(c->Control_Points, i, &v[1]); List_Read(c->Control_Points, i + 1, &v[2]); if(!i) { if(c->beg == c->end){ List_Read(c->Control_Points, N - 2, &v[0]); } else{ v[0] = &temp1; v[0]->Pos.X = 2. * v[1]->Pos.X - v[2]->Pos.X; v[0]->Pos.Y = 2. * v[1]->Pos.Y - v[2]->Pos.Y; v[0]->Pos.Z = 2. * v[1]->Pos.Z - v[2]->Pos.Z; v[0]->pntOnGeometry = v[1]->pntOnGeometry * 2. - v[2]->pntOnGeometry; } } else { List_Read(c->Control_Points, i - 1, &v[0]); } if(i == N - 2) { if(c->beg == c->end){ List_Read(c->Control_Points, 1, &v[3]); } else{ v[3] = &temp2; v[3]->Pos.X = 2. * v[2]->Pos.X - v[1]->Pos.X; v[3]->Pos.Y = 2. * v[2]->Pos.Y - v[1]->Pos.Y; v[3]->Pos.Z = 2. * v[2]->Pos.Z - v[1]->Pos.Z; v[3]->pntOnGeometry = v[2]->pntOnGeometry * 2. - v[1]->pntOnGeometry; } } else { List_Read(c->Control_Points, i + 2, &v[3]); } if(c->geometry){ SPoint2 pp = InterpolateCubicSpline(v, t, c->mat, t1, t2,c->geometry,0); SPoint3 pt = c->geometry->point(pp); V.Pos.X = pt.x(); V.Pos.Y = pt.y(); V.Pos.Z = pt.z(); } else V = InterpolateCubicSpline(v, t, c->mat, 0, t1, t2); break; case MSH_SEGM_BND_LAYER: Msg::Debug("Cannot interpolate boundary layer curve"); break; case MSH_SEGM_DISCRETE: Msg::Debug("Cannot interpolate discrete curve"); break; case MSH_SEGM_COMPOUND: Msg::Debug("Cannot interpolate compound curve"); break; default: Msg::Error("Unknown curve type in interpolation"); break; } V.u = u; return V; }