Add a warning when zero-length edges appear in the sketch, since

those screw a lot of things up. And add data structure for
clipboard entities, though no code yet.

[git-p4: depot-paths = "//depot/solvespace/": change = 2082]
This commit is contained in:
Jonathan Westhues 2009-12-03 11:14:34 -08:00
parent 48b79b912c
commit 8e484beec1
2 changed files with 50 additions and 9 deletions

View File

@ -2,7 +2,10 @@
#define gs (SS.GW.gs) #define gs (SS.GW.gs)
void Group::AssembleLoops(bool *allClosed, bool *allCoplanar) { void Group::AssembleLoops(bool *allClosed,
bool *allCoplanar,
bool *allNonZeroLen)
{
SBezierList sbl; SBezierList sbl;
ZERO(&sbl); ZERO(&sbl);
@ -16,6 +19,22 @@ void Group::AssembleLoops(bool *allClosed, bool *allCoplanar) {
e->GenerateBezierCurves(&sbl); e->GenerateBezierCurves(&sbl);
} }
SBezier *sb;
*allNonZeroLen = true;
for(sb = sbl.l.First(); sb; sb = sbl.l.NextAfter(sb)) {
for(i = 1; i <= sb->deg; i++) {
if(!(sb->ctrl[i]).Equals(sb->ctrl[0])) {
break;
}
}
if(i > sb->deg) {
// This is a zero-length edge.
*allNonZeroLen = false;
polyError.errorPointAt = sb->ctrl[0];
return;
}
}
// Try to assemble all these Beziers into loops. The closed loops go into // Try to assemble all these Beziers into loops. The closed loops go into
// bezierLoops, with the outer loops grouped with their holes. The // bezierLoops, with the outer loops grouped with their holes. The
// leftovers, if any, go in bezierOpens. // leftovers, if any, go in bezierOpens.
@ -35,12 +54,14 @@ void Group::GenerateLoops(void) {
if(type == DRAWING_3D || type == DRAWING_WORKPLANE || if(type == DRAWING_3D || type == DRAWING_WORKPLANE ||
type == ROTATE || type == TRANSLATE || type == IMPORTED) type == ROTATE || type == TRANSLATE || type == IMPORTED)
{ {
bool allClosed, allCoplanar; bool allClosed, allCoplanar, allNonZeroLen;
AssembleLoops(&allClosed, &allCoplanar); AssembleLoops(&allClosed, &allCoplanar, &allNonZeroLen);
if(!allCoplanar) { if(!allCoplanar) {
polyError.how = POLY_NOT_COPLANAR; polyError.how = POLY_NOT_COPLANAR;
} else if(!allClosed) { } else if(!allClosed) {
polyError.how = POLY_NOT_CLOSED; polyError.how = POLY_NOT_CLOSED;
} else if(!allNonZeroLen) {
polyError.how = POLY_ZERO_LEN_EDGE;
} else { } else {
polyError.how = POLY_GOOD; polyError.how = POLY_GOOD;
// The self-intersecting check is kind of slow, so don't run it // The self-intersecting check is kind of slow, so don't run it
@ -474,15 +495,21 @@ void Group::Draw(void) {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
} }
} else if(polyError.how == POLY_NOT_COPLANAR || } else if(polyError.how == POLY_NOT_COPLANAR ||
polyError.how == POLY_SELF_INTERSECTING) polyError.how == POLY_SELF_INTERSECTING ||
polyError.how == POLY_ZERO_LEN_EDGE)
{ {
// These errors occur at points, not lines // These errors occur at points, not lines
if(type == DRAWING_WORKPLANE) { if(type == DRAWING_WORKPLANE) {
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glxColorRGB(Style::Color(Style::DRAW_ERROR)); glxColorRGB(Style::Color(Style::DRAW_ERROR));
char *msg = (polyError.how == POLY_NOT_COPLANAR) ? char *msg;
"points not all coplanar!" : if(polyError.how == POLY_NOT_COPLANAR) {
"contour is self-intersecting!"; msg = "points not all coplanar!";
} else if(polyError.how == POLY_SELF_INTERSECTING) {
msg = "contour is self-intersecting!";
} else {
msg = "zero-length edge!";
}
glxWriteText(msg, DEFAULT_TEXT_HEIGHT, glxWriteText(msg, DEFAULT_TEXT_HEIGHT,
polyError.errorPointAt, SS.GW.projRight, SS.GW.projUp, polyError.errorPointAt, SS.GW.projRight, SS.GW.projUp,
NULL, NULL); NULL, NULL);

View File

@ -148,6 +148,7 @@ public:
static const int POLY_NOT_CLOSED = 1; static const int POLY_NOT_CLOSED = 1;
static const int POLY_NOT_COPLANAR = 2; static const int POLY_NOT_COPLANAR = 2;
static const int POLY_SELF_INTERSECTING = 3; static const int POLY_SELF_INTERSECTING = 3;
static const int POLY_ZERO_LEN_EDGE = 4;
struct { struct {
int how; int how;
SEdge notClosedAt; SEdge notClosedAt;
@ -216,7 +217,7 @@ public:
// Assembling the curves into loops, and into a piecewise linear polygon // Assembling the curves into loops, and into a piecewise linear polygon
// at the same time. // at the same time.
void AssembleLoops(bool *allClosed, bool *allCoplanar); void AssembleLoops(bool *allClosed, bool *allCoplanar, bool *allNonZeroLen);
void GenerateLoops(void); void GenerateLoops(void);
// And the mesh stuff // And the mesh stuff
Group *PreviousGroup(void); Group *PreviousGroup(void);
@ -276,6 +277,7 @@ public:
char *DescriptionString(void); char *DescriptionString(void);
}; };
#define MAX_POINTS_IN_ENTITY (12)
class EntityBase { class EntityBase {
public: public:
int tag; int tag;
@ -322,7 +324,7 @@ public:
// When it comes time to draw an entity, we look here to get the // When it comes time to draw an entity, we look here to get the
// defining variables. // defining variables.
hEntity point[12]; hEntity point[MAX_POINTS_IN_ENTITY];
int extraPoints; int extraPoints;
hEntity normal; hEntity normal;
hEntity distance; hEntity distance;
@ -764,5 +766,17 @@ inline bool hEquation::isFromConstraint(void)
inline hConstraint hEquation::constraint(void) inline hConstraint hEquation::constraint(void)
{ hConstraint r; r.v = (v >> 16); return r; } { hConstraint r; r.v = (v >> 16); return r; }
// The format for entities stored on the clipboard.
class ClipboardEntity {
public:
int type;
Vector point[MAX_POINTS_IN_ENTITY];
int extraPoints;
hStyle style;
NameStr str;
NameStr font;
bool construction;
};
#endif #endif