Add sin and cos to the expression entry (for dimensions etc.), with
the same precedence as sqrt. Add the code to find naked edges, and draw them highlighted on the model. And make the direction of trim curves consistent, always ccw with normal toward viewer; so there's no need to fix the directions before triangulating. [git-p4: depot-paths = "//depot/solvespace/": change = 1903]solver
parent
bb4b767e99
commit
2e4ec6dd04
11
draw.cpp
11
draw.cpp
|
@ -1021,6 +1021,17 @@ void GraphicsWindow::Paint(int w, int h) {
|
|||
}
|
||||
glEnd();
|
||||
|
||||
// And the naked edges, if the user did Analyze -> Show Naked Edges.
|
||||
glLineWidth(7);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple(4, 0x5555);
|
||||
glColor3d(1, 0, 0);
|
||||
glxDrawEdges(&(SS.nakedEdges));
|
||||
glLineStipple(4, 0xaaaa);
|
||||
glColor3d(0, 0, 0);
|
||||
glxDrawEdges(&(SS.nakedEdges));
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
|
||||
// Then redraw whatever the mouse is hovering over, highlighted.
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glxLockColorTo(1, 1, 0);
|
||||
|
|
|
@ -88,7 +88,7 @@ void SolveSpace::ExportSectionTo(char *filename) {
|
|||
SKdNode *root = SKdNode::From(&m);
|
||||
SEdgeList el;
|
||||
ZERO(&el);
|
||||
root->MakeCertainEdgesInto(&el, false);
|
||||
root->MakeNakedEdgesInto(&el);
|
||||
// Assemble those edges into a polygon, and clear the edge list
|
||||
el.AssemblePolygon(&sp, NULL);
|
||||
el.Clear();
|
||||
|
|
12
expr.cpp
12
expr.cpp
|
@ -598,7 +598,9 @@ int Expr::Precedence(Expr *e) {
|
|||
if(e->op != BINARY_OP && e->op != UNARY_OP) oops();
|
||||
|
||||
switch(e->x.c) {
|
||||
case 'q':
|
||||
case 's':
|
||||
case 'c':
|
||||
case 'n': return 30;
|
||||
|
||||
case '*':
|
||||
|
@ -629,7 +631,9 @@ c:
|
|||
break;
|
||||
|
||||
case 'n': n = PopOperand()->Negate(); break;
|
||||
case 's': n = PopOperand()->Sqrt(); break;
|
||||
case 'q': n = PopOperand()->Sqrt(); break;
|
||||
case 's': n = (PopOperand()->Times(Expr::From(PI/180)))->Sin(); break;
|
||||
case 'c': n = (PopOperand()->Times(Expr::From(PI/180)))->Cos(); break;
|
||||
|
||||
default: oops();
|
||||
}
|
||||
|
@ -721,6 +725,12 @@ void Expr::Lex(char *in) {
|
|||
|
||||
Expr *e = AllocExpr();
|
||||
if(strcmp(name, "sqrt")==0) {
|
||||
e->op = UNARY_OP;
|
||||
e->x.c = 'q';
|
||||
} else if(strcmp(name, "cos")==0) {
|
||||
e->op = UNARY_OP;
|
||||
e->x.c = 'c';
|
||||
} else if(strcmp(name, "sin")==0) {
|
||||
e->op = UNARY_OP;
|
||||
e->x.c = 's';
|
||||
} else {
|
||||
|
|
|
@ -295,14 +295,9 @@ void glxDebugPolygon(SPolygon *p)
|
|||
|
||||
void glxDrawEdges(SEdgeList *el)
|
||||
{
|
||||
int i;
|
||||
glLineWidth(1);
|
||||
glxDepthRangeOffset(2);
|
||||
glxColor3d(REDf(SS.edgeColor), GREENf(SS.edgeColor), BLUEf(SS.edgeColor));
|
||||
|
||||
SEdge *se;
|
||||
glBegin(GL_LINES);
|
||||
for(i = 0; i < el->l.n; i++) {
|
||||
SEdge *se = &(el->l.elem[i]);
|
||||
for(se = el->l.First(); se; se = el->l.NextAfter(se)) {
|
||||
glxVertex3v(se->a);
|
||||
glxVertex3v(se->b);
|
||||
}
|
||||
|
|
|
@ -558,6 +558,7 @@ void GraphicsWindow::MenuEdit(int id) {
|
|||
}
|
||||
SS.GW.ClearSuper();
|
||||
HideTextEditControl();
|
||||
SS.nakedEdges.Clear();
|
||||
break;
|
||||
|
||||
case MNU_DELETE: {
|
||||
|
|
|
@ -87,7 +87,6 @@ void Group::GenerateShellForStepAndRepeat(void) {
|
|||
|
||||
void Group::GenerateShellAndMesh(void) {
|
||||
thisShell.Clear();
|
||||
STriMeta meta = { 0, color };
|
||||
|
||||
if(type == TRANSLATE || type == ROTATE) {
|
||||
GenerateShellForStepAndRepeat();
|
||||
|
@ -105,7 +104,7 @@ void Group::GenerateShellAndMesh(void) {
|
|||
tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1);
|
||||
}
|
||||
|
||||
thisShell.MakeFromExtrusionOf(&(src->bezierLoopSet), tbot, ttop);
|
||||
thisShell.MakeFromExtrusionOf(&(src->bezierLoopSet), tbot, ttop, color);
|
||||
} else if(type == LATHE) {
|
||||
Group *src = SS.GetGroup(opA);
|
||||
|
||||
|
@ -223,6 +222,11 @@ void Group::Draw(void) {
|
|||
glxFillMesh(specColor, &runningMesh, mh, ms1, ms2);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glLineWidth(1);
|
||||
glxDepthRangeOffset(2);
|
||||
glxColor3d(REDf (SS.edgeColor),
|
||||
GREENf(SS.edgeColor),
|
||||
BLUEf (SS.edgeColor));
|
||||
glxDrawEdges(&emphEdges);
|
||||
}
|
||||
|
||||
|
|
56
mesh.cpp
56
mesh.cpp
|
@ -476,21 +476,19 @@ void SKdNode::MakeMeshInto(SMesh *m) {
|
|||
}
|
||||
}
|
||||
|
||||
void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int *nOther,
|
||||
STriMeta m, int cnt)
|
||||
{
|
||||
void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt) {
|
||||
if(gt && lt) {
|
||||
double ac = a.Element(which),
|
||||
bc = b.Element(which);
|
||||
if(ac < c + KDTREE_EPS ||
|
||||
bc < c + KDTREE_EPS)
|
||||
{
|
||||
lt->FindEdgeOn(a, b, n, nOther, m, cnt);
|
||||
lt->FindEdgeOn(a, b, n, cnt);
|
||||
}
|
||||
if(ac > c - KDTREE_EPS ||
|
||||
bc > c - KDTREE_EPS)
|
||||
{
|
||||
gt->FindEdgeOn(a, b, n, nOther, m, cnt);
|
||||
gt->FindEdgeOn(a, b, n, cnt);
|
||||
}
|
||||
} else {
|
||||
STriangleLl *ll;
|
||||
|
@ -499,43 +497,20 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int *nOther,
|
|||
|
||||
if(tr->tag == cnt) continue;
|
||||
|
||||
if((a.Equals(tr->b, KDTREE_EPS) && b.Equals(tr->a, KDTREE_EPS)) ||
|
||||
(a.Equals(tr->c, KDTREE_EPS) && b.Equals(tr->b, KDTREE_EPS)) ||
|
||||
(a.Equals(tr->a, KDTREE_EPS) && b.Equals(tr->c, KDTREE_EPS)))
|
||||
if((a.Equals(tr->b) && b.Equals(tr->a)) ||
|
||||
(a.Equals(tr->c) && b.Equals(tr->b)) ||
|
||||
(a.Equals(tr->a) && b.Equals(tr->c)))
|
||||
{
|
||||
(*n)++;
|
||||
if(tr->meta.face != m.face) {
|
||||
if(tr->meta.color == m.color &&
|
||||
tr->meta.face != 0 && m.face != 0)
|
||||
{
|
||||
hEntity hf0 = { tr->meta.face },
|
||||
hf1 = { m.face };
|
||||
Entity *f0 = SS.GetEntity(hf0),
|
||||
*f1 = SS.GetEntity(hf1);
|
||||
|
||||
Vector n0 = f0->FaceGetNormalNum().WithMagnitude(1),
|
||||
n1 = f1->FaceGetNormalNum().WithMagnitude(1);
|
||||
|
||||
if(n0.Equals(n1) || n0.Equals(n1.ScaledBy(-1))) {
|
||||
// faces are coincident, skip
|
||||
// (If the planes are parallel, and the edge
|
||||
// lies in both planes, then they're also
|
||||
// coincident.)
|
||||
} else {
|
||||
(*nOther)++;
|
||||
}
|
||||
} else {
|
||||
(*nOther)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that we don't count this triangle twice if it appears
|
||||
// in two buckets of the kd tree.
|
||||
tr->tag = cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, bool emphasized) {
|
||||
void SKdNode::MakeNakedEdgesInto(SEdgeList *sel) {
|
||||
SMesh m;
|
||||
ZERO(&m);
|
||||
ClearTags();
|
||||
|
@ -551,20 +526,11 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, bool emphasized) {
|
|||
Vector b = (j == 0) ? tr->b : ((j == 1) ? tr->c : tr->a);
|
||||
|
||||
int n = 0, nOther = 0;
|
||||
FindEdgeOn(a, b, &n, &nOther, tr->meta, cnt++);
|
||||
FindEdgeOn(a, b, &n, cnt);
|
||||
if(n != 1) {
|
||||
if(!emphasized) {
|
||||
if(n == 0 && (a.Minus(b).Magnitude()) > KDTREE_EPS) {
|
||||
sel->AddEdge(a, b);
|
||||
}
|
||||
} else {
|
||||
// dbp("hanging: n=%d (%.3f %.3f %.3f) (%.3f %.3f %.3f)",
|
||||
// n, CO(a), CO(b));
|
||||
}
|
||||
}
|
||||
if(nOther > 0) {
|
||||
if(emphasized) sel->AddEdge(a, b);
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
polygon.cpp
14
polygon.cpp
|
@ -68,8 +68,8 @@ void SEdgeList::AddEdge(Vector a, Vector b) {
|
|||
l.Add(&e);
|
||||
}
|
||||
|
||||
bool SEdgeList::AssembleContour(Vector first, Vector last,
|
||||
SContour *dest, SEdge *errorAt)
|
||||
bool SEdgeList::AssembleContour(Vector first, Vector last, SContour *dest,
|
||||
SEdge *errorAt, bool keepDir)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -87,7 +87,8 @@ bool SEdgeList::AssembleContour(Vector first, Vector last,
|
|||
se->tag = 1;
|
||||
break;
|
||||
}
|
||||
if(se->b.Equals(last)) {
|
||||
// Don't allow backwards edges if keepDir is true.
|
||||
if(!keepDir && se->b.Equals(last)) {
|
||||
dest->AddPoint(se->a);
|
||||
last = se->a;
|
||||
se->tag = 1;
|
||||
|
@ -108,7 +109,7 @@ bool SEdgeList::AssembleContour(Vector first, Vector last,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt) {
|
||||
bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir) {
|
||||
dest->Clear();
|
||||
|
||||
bool allClosed = true;
|
||||
|
@ -130,8 +131,11 @@ bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt) {
|
|||
// Create a new empty contour in our polygon, and finish assembling
|
||||
// into that contour.
|
||||
dest->AddEmptyContour();
|
||||
if(!AssembleContour(first, last, &(dest->l.elem[dest->l.n-1]), errorAt))
|
||||
if(!AssembleContour(first, last, &(dest->l.elem[dest->l.n-1]),
|
||||
errorAt, keepDir))
|
||||
{
|
||||
allClosed = false;
|
||||
}
|
||||
// But continue assembling, even if some of the contours are open
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ public:
|
|||
|
||||
void Clear(void);
|
||||
void AddEdge(Vector a, Vector b);
|
||||
bool AssemblePolygon(SPolygon *dest, SEdge *errorAt);
|
||||
bool AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir=false);
|
||||
bool AssembleContour(Vector first, Vector last, SContour *dest,
|
||||
SEdge *errorAt);
|
||||
SEdge *errorAt, bool keepDir);
|
||||
int AnyEdgeCrossings(Vector a, Vector b, Vector *pi=NULL);
|
||||
};
|
||||
|
||||
|
@ -218,9 +218,8 @@ public:
|
|||
void MakeMeshInto(SMesh *m);
|
||||
void ClearTags(void);
|
||||
|
||||
void FindEdgeOn(Vector a, Vector b, int *n, int *nOther,
|
||||
STriMeta m, int cnt);
|
||||
void MakeCertainEdgesInto(SEdgeList *sel, bool emphasized);
|
||||
void FindEdgeOn(Vector a, Vector b, int *n, int cnt);
|
||||
void MakeNakedEdgesInto(SEdgeList *sel);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -183,6 +183,8 @@ void SolveSpace::AfterNewFile(void) {
|
|||
// Clear out the traced point, which is no longer valid
|
||||
traced.point = Entity::NO_ENTITY;
|
||||
traced.path.l.Clear();
|
||||
// and the naked edges
|
||||
nakedEdges.Clear();
|
||||
|
||||
ReloadAllImported();
|
||||
GenerateAll(-1, -1);
|
||||
|
@ -400,6 +402,20 @@ void SolveSpace::MenuAnalyze(int id) {
|
|||
break;
|
||||
|
||||
case GraphicsWindow::MNU_NAKED_EDGES: {
|
||||
SS.nakedEdges.Clear();
|
||||
|
||||
SMesh *m = &(SS.GetGroup(SS.GW.activeGroup)->runningMesh);
|
||||
SKdNode *root = SKdNode::From(m);
|
||||
root->MakeNakedEdgesInto(&(SS.nakedEdges));
|
||||
InvalidateGraphics();
|
||||
|
||||
if(SS.nakedEdges.l.n == 0) {
|
||||
Error("Zero naked edges; the model is watertight. "
|
||||
"An exported STL file will be valid.");
|
||||
} else {
|
||||
Error("Found %d naked edges, now highlighted.",
|
||||
SS.nakedEdges.l.n);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -471,6 +471,7 @@ public:
|
|||
SContour path;
|
||||
hEntity point;
|
||||
} traced;
|
||||
SEdgeList nakedEdges;
|
||||
|
||||
void MarkGroupDirty(hGroup hg);
|
||||
void MarkGroupDirtyByEntity(hEntity he);
|
||||
|
|
|
@ -320,13 +320,21 @@ void SCurve::Clear(void) {
|
|||
pts.Clear();
|
||||
}
|
||||
|
||||
STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc) {
|
||||
STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc, bool backwards) {
|
||||
STrimBy stb;
|
||||
ZERO(&stb);
|
||||
stb.curve = hsc;
|
||||
SCurve *sc = shell->curve.FindById(hsc);
|
||||
|
||||
if(backwards) {
|
||||
stb.finish = sc->pts.elem[0];
|
||||
stb.start = sc->pts.elem[sc->pts.n - 1];
|
||||
stb.backwards = true;
|
||||
} else {
|
||||
stb.start = sc->pts.elem[0];
|
||||
stb.finish = sc->pts.elem[sc->pts.n - 1];
|
||||
stb.backwards = false;
|
||||
}
|
||||
|
||||
return stb;
|
||||
}
|
||||
|
@ -377,6 +385,8 @@ SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q,
|
|||
ZERO(&ret);
|
||||
|
||||
ret.h = a->h;
|
||||
ret.color = a->color;
|
||||
ret.face = a->face;
|
||||
|
||||
ret.degm = a->degm;
|
||||
ret.degn = a->degn;
|
||||
|
@ -511,9 +521,20 @@ void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, bool asUv) {
|
|||
|
||||
Vector prev, prevuv, ptuv;
|
||||
bool inCurve = false;
|
||||
Vector *pt;
|
||||
double u = 0, v = 0;
|
||||
for(pt = sc->pts.First(); pt; pt = sc->pts.NextAfter(pt)) {
|
||||
|
||||
int i, first, last, increment;
|
||||
if(stb->backwards) {
|
||||
first = sc->pts.n - 1;
|
||||
last = 0;
|
||||
increment = -1;
|
||||
} else {
|
||||
first = 0;
|
||||
last = sc->pts.n - 1;
|
||||
increment = 1;
|
||||
}
|
||||
for(i = first; i != (last + increment); i += increment) {
|
||||
Vector *pt = &(sc->pts.elem[i]);
|
||||
if(asUv) {
|
||||
ClosestPointTo(*pt, &u, &v);
|
||||
ptuv = Vector::From(u, v, 0);
|
||||
|
@ -542,14 +563,14 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
|
|||
|
||||
SPolygon poly;
|
||||
ZERO(&poly);
|
||||
if(!el.AssemblePolygon(&poly, NULL)) {
|
||||
if(!el.AssemblePolygon(&poly, NULL, true)) {
|
||||
dbp("failed to assemble polygon to trim nurbs surface in uv space");
|
||||
}
|
||||
|
||||
int i, start = sm->l.n;
|
||||
poly.UvTriangulateInto(sm);
|
||||
|
||||
STriMeta meta = { 0, 0x888888 };
|
||||
STriMeta meta = { face, color };
|
||||
for(i = start; i < sm->l.n; i++) {
|
||||
STriangle *st = &(sm->l.elem[i]);
|
||||
st->meta = meta;
|
||||
|
@ -559,11 +580,10 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
|
|||
st->a = PointAt(st->a.x, st->a.y);
|
||||
st->b = PointAt(st->b.x, st->b.y);
|
||||
st->c = PointAt(st->c.x, st->c.y);
|
||||
if((st->Normal()).Dot(st->an) < 0) {
|
||||
// Have to get the vertices in the right order
|
||||
// Works out that my chosen contour direction is inconsistent with
|
||||
// the triangle direction, sigh.
|
||||
st->FlipNormal();
|
||||
}
|
||||
}
|
||||
|
||||
el.Clear();
|
||||
poly.Clear();
|
||||
|
@ -573,7 +593,9 @@ void SSurface::Clear(void) {
|
|||
trim.Clear();
|
||||
}
|
||||
|
||||
void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1) {
|
||||
void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
||||
int color)
|
||||
{
|
||||
ZERO(this);
|
||||
|
||||
// Make the extrusion direction consistent with respect to the normal
|
||||
|
@ -586,7 +608,9 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1) {
|
|||
// planes.
|
||||
SSurface s0, s1;
|
||||
s0 = SSurface::FromPlane(sbls->point.Plus(t0), sbls->normal.ScaledBy(-1));
|
||||
s0.color = color;
|
||||
s1 = SSurface::FromPlane(sbls->point.Plus(t1), sbls->normal.ScaledBy( 1));
|
||||
s1.color = color;
|
||||
hSSurface hs0 = surface.AddAndAssignId(&s0),
|
||||
hs1 = surface.AddAndAssignId(&s1);
|
||||
|
||||
|
@ -598,7 +622,7 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1) {
|
|||
SBezier *sb;
|
||||
|
||||
typedef struct {
|
||||
STrimBy trim;
|
||||
hSCurve hc;
|
||||
hSSurface hs;
|
||||
} TrimLine;
|
||||
List<TrimLine> trimLines;
|
||||
|
@ -608,6 +632,7 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1) {
|
|||
// Generate the surface of extrusion of this curve, and add
|
||||
// it to the list
|
||||
SSurface ss = SSurface::FromExtrusionOf(sb, t0, t1);
|
||||
ss.color = color;
|
||||
hSSurface hsext = surface.AddAndAssignId(&ss);
|
||||
|
||||
// Translate the curve by t0 and t1 to produce two trim curves
|
||||
|
@ -615,19 +640,21 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1) {
|
|||
ZERO(&sc);
|
||||
sb->MakePwlInto(&(sc.pts), t0);
|
||||
hSCurve hc0 = curve.AddAndAssignId(&sc);
|
||||
STrimBy stb0 = STrimBy::EntireCurve(this, hc0);
|
||||
STrimBy stb0 = STrimBy::EntireCurve(this, hc0, false);
|
||||
|
||||
ZERO(&sc);
|
||||
sb->MakePwlInto(&(sc.pts), t1);
|
||||
hSCurve hc1 = curve.AddAndAssignId(&sc);
|
||||
STrimBy stb1 = STrimBy::EntireCurve(this, hc1);
|
||||
STrimBy stb1 = STrimBy::EntireCurve(this, hc1, true);
|
||||
|
||||
// The translated curves trim the flat top and bottom surfaces.
|
||||
(surface.FindById(hs0))->trim.Add(&stb0);
|
||||
(surface.FindById(hs1))->trim.Add(&stb1);
|
||||
|
||||
// The translated curves also trim the surface of extrusion.
|
||||
stb0 = STrimBy::EntireCurve(this, hc0, true);
|
||||
(surface.FindById(hsext))->trim.Add(&stb0);
|
||||
stb1 = STrimBy::EntireCurve(this, hc1, false);
|
||||
(surface.FindById(hsext))->trim.Add(&stb1);
|
||||
|
||||
// And form the trim line
|
||||
|
@ -639,7 +666,7 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1) {
|
|||
hSCurve hl = curve.AddAndAssignId(&sc);
|
||||
// save this for later
|
||||
TrimLine tl;
|
||||
tl.trim = STrimBy::EntireCurve(this, hl);
|
||||
tl.hc = hl;
|
||||
tl.hs = hsext;
|
||||
trimLines.Add(&tl);
|
||||
}
|
||||
|
@ -651,8 +678,11 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1) {
|
|||
|
||||
TrimLine *tlp = &(trimLines.elem[WRAP(i-1, trimLines.n)]);
|
||||
|
||||
ss->trim.Add(&(tl->trim));
|
||||
ss->trim.Add(&(tlp->trim));
|
||||
STrimBy stb;
|
||||
stb = STrimBy::EntireCurve(this, tl->hc, true);
|
||||
ss->trim.Add(&stb);
|
||||
stb = STrimBy::EntireCurve(this, tlp->hc, false);
|
||||
ss->trim.Add(&stb);
|
||||
}
|
||||
trimLines.Clear();
|
||||
}
|
||||
|
|
|
@ -97,11 +97,14 @@ public:
|
|||
class STrimBy {
|
||||
public:
|
||||
hSCurve curve;
|
||||
bool backwards;
|
||||
// If a trim runs backwards, then start and finish still correspond to
|
||||
// the actual start and finish, but they appear in reverse order in
|
||||
// the referenced curve.
|
||||
Vector start;
|
||||
Vector finish;
|
||||
Vector out;
|
||||
|
||||
static STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc);
|
||||
static STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc, bool bkwds);
|
||||
};
|
||||
|
||||
// A rational polynomial surface in Bezier form.
|
||||
|
@ -109,6 +112,9 @@ class SSurface {
|
|||
public:
|
||||
hSSurface h;
|
||||
|
||||
int color;
|
||||
DWORD face;
|
||||
|
||||
int degm, degn;
|
||||
Vector ctrl[4][4];
|
||||
double weight[4][4];
|
||||
|
@ -136,7 +142,8 @@ public:
|
|||
IdList<SCurve,hSCurve> curve;
|
||||
IdList<SSurface,hSSurface> surface;
|
||||
|
||||
void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1);
|
||||
void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
||||
int color);
|
||||
void MakeFromUnionOf(SShell *a, SShell *b);
|
||||
void MakeFromDifferenceOf(SShell *a, SShell *b);
|
||||
void MakeFromCopyOf(SShell *a);
|
||||
|
|
|
@ -51,7 +51,7 @@ void SPolygon::UvTriangulateInto(SMesh *m) {
|
|||
}
|
||||
}
|
||||
|
||||
dbp("finished finding holes: %d ms", GetMilliseconds() - in);
|
||||
// dbp("finished finding holes: %d ms", GetMilliseconds() - in);
|
||||
for(;;) {
|
||||
double xmin = 1e10;
|
||||
SContour *scmin = NULL;
|
||||
|
@ -70,13 +70,13 @@ void SPolygon::UvTriangulateInto(SMesh *m) {
|
|||
dbp("couldn't merge our hole");
|
||||
return;
|
||||
}
|
||||
dbp(" bridged to contour: %d ms", GetMilliseconds() - in);
|
||||
// dbp(" bridged to contour: %d ms", GetMilliseconds() - in);
|
||||
scmin->tag = 3;
|
||||
}
|
||||
dbp("finished merging holes: %d ms", GetMilliseconds() - in);
|
||||
// dbp("finished merging holes: %d ms", GetMilliseconds() - in);
|
||||
|
||||
merged.UvTriangulateInto(m);
|
||||
dbp("finished ear clippping: %d ms", GetMilliseconds() - in);
|
||||
// dbp("finished ear clippping: %d ms", GetMilliseconds() - in);
|
||||
merged.l.Clear();
|
||||
el.Clear();
|
||||
vl.Clear();
|
||||
|
|
Loading…
Reference in New Issue