1 //-----------------------------------------------------------------------------
2 // The parametric structure of our sketch, in multiple groups, that generate
3 // geometric entities and surfaces.
4 //
5 // Copyright 2008-2013 Jonathan Westhues.
6 //-----------------------------------------------------------------------------
7 
8 #ifndef __SKETCH_H
9 #define __SKETCH_H
10 
11 class hGroup;
12 class hRequest;
13 class hEntity;
14 class hParam;
15 class hStyle;
16 class hConstraint;
17 class hEquation;
18 
19 class Entity;
20 class Param;
21 class Equation;
22 class Style;
23 
24 
25 // All of the hWhatever handles are a 32-bit ID, that is used to represent
26 // some data structure in the sketch.
27 class hGroup {
28 public:
29     // bits 15: 0   -- group index
30     uint32_t v;
31 
32     inline hEntity entity(int i);
33     inline hParam param(int i);
34     inline hEquation equation(int i);
35 };
36 class hRequest {
37 public:
38     // bits 15: 0   -- request index
39     uint32_t v;
40 
41     inline hEntity entity(int i);
42     inline hParam param(int i);
43 
44     inline bool IsFromReferences(void);
45 };
46 class hEntity {
47 public:
48     // bits 15: 0   -- entity index
49     //      31:16   -- request index
50     uint32_t v;
51 
52     inline bool isFromRequest(void);
53     inline hRequest request(void);
54     inline hGroup group(void);
55     inline hEquation equation(int i);
56 };
57 class hParam {
58 public:
59     // bits 15: 0   -- param index
60     //      31:16   -- request index
61     uint32_t v;
62 
63     inline hRequest request(void);
64 };
65 
66 class hStyle {
67 public:
68     uint32_t v;
69 };
70 
71 
72 class EntityId {
73 public:
74     uint32_t v;     // entity ID, starting from 0
75 };
76 class EntityMap {
77 public:
78     int         tag;
79 
80     EntityId    h;
81     hEntity     input;
82     int         copyNumber;
83     // (input, copyNumber) gets mapped to ((Request)xxx).entity(h.v)
84 
Clear(void)85     void Clear(void) {}
86 };
87 
88 // A set of requests. Every request must have an associated group.
89 class Group {
90 public:
91     static const hGroup     HGROUP_REFERENCES;
92 
93     int         tag;
94     hGroup      h;
95 
96     enum {
97         DRAWING_3D                    = 5000,
98         DRAWING_WORKPLANE             = 5001,
99         EXTRUDE                       = 5100,
100         LATHE                         = 5101,
101         ROTATE                        = 5200,
102         TRANSLATE                     = 5201,
103         LINKED                        = 5300
104     };
105     int type;
106 
107     int order;
108 
109     hGroup      opA;
110     hGroup      opB;
111     bool        visible;
112     bool        suppress;
113     bool        relaxConstraints;
114     bool        allowRedundant;
115     bool        allDimsReference;
116     double      scale;
117 
118     bool        clean;
119     hEntity     activeWorkplane;
120     double      valA;
121     double      valB;
122     double      valC;
123     RgbaColor   color;
124 
125     struct {
126         int                 how;
127         int                 dof;
128         List<hConstraint>   remove;
129     } solved;
130 
131     enum {
132         // For drawings in 2d
133         WORKPLANE_BY_POINT_ORTHO   = 6000,
134         WORKPLANE_BY_LINE_SEGMENTS = 6001,
135         // For extrudes, translates, and rotates
136         ONE_SIDED                  = 7000,
137         TWO_SIDED                  = 7001
138     };
139     int subtype;
140 
141     bool skipFirst; // for step and repeat ops
142 
143     struct {
144         Quaternion  q;
145         hEntity     origin;
146         hEntity     entityB;
147         hEntity     entityC;
148         bool        swapUV;
149         bool        negateU;
150         bool        negateV;
151     } predef;
152 
153     SPolygon                polyLoops;
154     SBezierLoopSetSet       bezierLoops;
155     SBezierList             bezierOpens;
156     enum {
157         POLY_GOOD              = 0,
158         POLY_NOT_CLOSED        = 1,
159         POLY_NOT_COPLANAR      = 2,
160         POLY_SELF_INTERSECTING = 3,
161         POLY_ZERO_LEN_EDGE     = 4
162     };
163     struct {
164         int             how;
165         SEdge           notClosedAt;
166         Vector          errorPointAt;
167     }               polyError;
168 
169     bool            booleanFailed;
170 
171     SShell          thisShell;
172     SShell          runningShell;
173 
174     SMesh           thisMesh;
175     SMesh           runningMesh;
176 
177     bool            displayDirty;
178     SMesh           displayMesh;
179     SEdgeList       displayEdges;
180     SOutlineList    displayOutlines;
181 
182     enum {
183         COMBINE_AS_UNION           = 0,
184         COMBINE_AS_DIFFERENCE      = 1,
185         COMBINE_AS_ASSEMBLE        = 2
186     };
187     int meshCombine;
188 
189     bool forceToMesh;
190 
191     IdList<EntityMap,EntityId> remap;
192     enum { REMAP_PRIME = 19477 };
193     int remapCache[REMAP_PRIME];
194 
195     std::string linkFile;
196     std::string linkFileRel;
197     SMesh       impMesh;
198     SShell      impShell;
199     EntityList  impEntity;
200 
201     std::string     name;
202 
203 
204     void Activate(void);
205     std::string DescriptionString(void);
206     void Clear(void);
207 
208     static void AddParam(ParamList *param, hParam hp, double v);
209     void Generate(EntityList *entity, ParamList *param);
210     bool IsSolvedOkay();
211     void TransformImportedBy(Vector t, Quaternion q);
212     // When a request generates entities from entities, and the source
213     // entities may have come from multiple requests, it's necessary to
214     // remap the entity ID so that it's still unique. We do this with a
215     // mapping list.
216     enum {
217         REMAP_LAST         = 1000,
218         REMAP_TOP          = 1001,
219         REMAP_BOTTOM       = 1002,
220         REMAP_PT_TO_LINE   = 1003,
221         REMAP_LINE_TO_FACE = 1004,
222         REMAP_LATHE_START  = 1006,
223         REMAP_LATHE_END    = 1007,
224         REMAP_PT_TO_ARC    = 1008,
225         REMAP_PT_TO_NORMAL = 1009,
226     };
227     hEntity Remap(hEntity in, int copyNumber);
228     void MakeExtrusionLines(EntityList *el, hEntity in);
229     void MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *param, hEntity in, Vector pt, Vector axis, int ai);
230     void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt);
231     void CopyEntity(EntityList *el,
232                     Entity *ep, int timesApplied, int remap,
233                     hParam dx, hParam dy, hParam dz,
234                     hParam qw, hParam qvx, hParam qvy, hParam qvz,
235                     bool asTrans, bool asAxisAngle);
236 
237     void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index);
238     void GenerateEquations(IdList<Equation,hEquation> *l);
239     bool IsVisible(void);
240     int GetNumConstraints();
241     Vector ExtrusionGetVector();
242     void ExtrusionForceVectorTo(const Vector &v);
243 
244     // Assembling the curves into loops, and into a piecewise linear polygon
245     // at the same time.
246     void AssembleLoops(bool *allClosed, bool *allCoplanar, bool *allNonZeroLen);
247     void GenerateLoops(void);
248     // And the mesh stuff
249     Group *PreviousGroup(void);
250     Group *RunningMeshGroup(void);
251     bool IsMeshGroup();
252     void GenerateShellAndMesh(void);
253     template<class T> void GenerateForStepAndRepeat(T *steps, T *outs);
254     template<class T> void GenerateForBoolean(T *a, T *b, T *o, int how);
255     void GenerateDisplayItems(void);
256     void DrawDisplayItems(int t);
257     void Draw(void);
258     RgbaColor GetLoopSetFillColor(SBezierLoopSet *sbls,
259                                  bool *allSame, Vector *errorAt);
260     void FillLoopSetAsPolygon(SBezierLoopSet *sbls);
261     void DrawFilledPaths(void);
262 
263     SPolygon GetPolygon(void);
264 
265     static void MenuGroup(int id);
266 };
267 
268 // A user request for some primitive or derived operation; for example a
269 // line, or a step and repeat.
270 class Request {
271 public:
272     // Some predefined requests, that are present in every sketch.
273     static const hRequest   HREQUEST_REFERENCE_XY;
274     static const hRequest   HREQUEST_REFERENCE_YZ;
275     static const hRequest   HREQUEST_REFERENCE_ZX;
276 
277     int         tag;
278     hRequest    h;
279 
280     // Types of requests
281     enum {
282         WORKPLANE              = 100,
283         DATUM_POINT            = 101,
284         LINE_SEGMENT           = 200,
285         CUBIC                  = 300,
286         CUBIC_PERIODIC         = 301,
287         CIRCLE                 = 400,
288         ARC_OF_CIRCLE          = 500,
289         TTF_TEXT               = 600
290     };
291 
292     int         type;
293     int         extraPoints;
294 
295     hEntity     workplane; // or Entity::FREE_IN_3D
296     hGroup      group;
297     hStyle      style;
298 
299     bool        construction;
300     std::string str;
301     std::string font;
302 
303     static hParam AddParam(ParamList *param, hParam hp);
304     void Generate(EntityList *entity, ParamList *param);
305 
306     std::string DescriptionString(void);
307     int IndexOfPoint(hEntity he);
308 
Clear(void)309     void Clear(void) {}
310 };
311 
312 #define MAX_POINTS_IN_ENTITY (12)
313 class EntityBase {
314 public:
315     int         tag;
316     hEntity     h;
317 
318     static const hEntity    FREE_IN_3D;
319     static const hEntity    NO_ENTITY;
320 
321     enum {
322         POINT_IN_3D            =  2000,
323         POINT_IN_2D            =  2001,
324         POINT_N_TRANS          =  2010,
325         POINT_N_ROT_TRANS      =  2011,
326         POINT_N_COPY           =  2012,
327         POINT_N_ROT_AA         =  2013,
328 
329         NORMAL_IN_3D           =  3000,
330         NORMAL_IN_2D           =  3001,
331         NORMAL_N_COPY          =  3010,
332         NORMAL_N_ROT           =  3011,
333         NORMAL_N_ROT_AA        =  3012,
334 
335         DISTANCE               =  4000,
336         DISTANCE_N_COPY        =  4001,
337 
338         FACE_NORMAL_PT         =  5000,
339         FACE_XPROD             =  5001,
340         FACE_N_ROT_TRANS       =  5002,
341         FACE_N_TRANS           =  5003,
342         FACE_N_ROT_AA          =  5004,
343 
344 
345         WORKPLANE              = 10000,
346         LINE_SEGMENT           = 11000,
347         CUBIC                  = 12000,
348         CUBIC_PERIODIC         = 12001,
349         CIRCLE                 = 13000,
350         ARC_OF_CIRCLE          = 14000,
351         TTF_TEXT               = 15000
352     };
353 
354     int         type;
355 
356     hGroup      group;
357     hEntity     workplane;   // or Entity::FREE_IN_3D
358 
359     // When it comes time to draw an entity, we look here to get the
360     // defining variables.
361     hEntity     point[MAX_POINTS_IN_ENTITY];
362     int         extraPoints;
363     hEntity     normal;
364     hEntity     distance;
365     // The only types that have their own params are points, normals,
366     // and directions.
367     hParam      param[7];
368 
369     // Transformed points/normals/distances have their numerical base
370     Vector      numPoint;
371     Quaternion  numNormal;
372     double      numDistance;
373 
374     std::string str;
375     std::string font;
376 
377     // For entities that are derived by a transformation, the number of
378     // times to apply the transformation.
379     int timesApplied;
380 
381     Quaternion GetAxisAngleQuaternion(int param0);
382     ExprQuaternion GetAxisAngleQuaternionExprs(int param0);
383 
384     bool IsCircle(void);
385     Expr *CircleGetRadiusExpr(void);
386     double CircleGetRadiusNum(void);
387     void ArcGetAngles(double *thetaa, double *thetab, double *dtheta);
388 
389     bool HasVector(void);
390     ExprVector VectorGetExprs(void);
391     Vector VectorGetNum(void);
392     Vector VectorGetRefPoint(void);
393     Vector VectorGetStartPoint(void);
394 
395     // For distances
396     bool IsDistance(void);
397     double DistanceGetNum(void);
398     Expr *DistanceGetExpr(void);
399     void DistanceForceTo(double v);
400 
401     bool IsWorkplane(void);
402     // The plane is points P such that P dot (xn, yn, zn) - d = 0
403     void WorkplaneGetPlaneExprs(ExprVector *n, Expr **d);
404     ExprVector WorkplaneGetOffsetExprs(void);
405     Vector WorkplaneGetOffset(void);
406     EntityBase *Normal(void);
407 
408     bool IsFace(void);
409     ExprVector FaceGetNormalExprs(void);
410     Vector FaceGetNormalNum(void);
411     ExprVector FaceGetPointExprs(void);
412     Vector FaceGetPointNum(void);
413 
414     bool IsPoint(void);
415     // Applies for any of the point types
416     Vector PointGetNum(void);
417     ExprVector PointGetExprs(void);
418     void PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v);
419     void PointForceTo(Vector v);
420     // These apply only the POINT_N_ROT_TRANS, which has an assoc rotation
421     Quaternion PointGetQuaternion(void);
422     void PointForceQuaternionTo(Quaternion q);
423 
424     bool IsNormal(void);
425     // Applies for any of the normal types
426     Quaternion NormalGetNum(void);
427     ExprQuaternion NormalGetExprs(void);
428     void NormalForceTo(Quaternion q);
429 
430     Vector NormalU(void);
431     Vector NormalV(void);
432     Vector NormalN(void);
433     ExprVector NormalExprsU(void);
434     ExprVector NormalExprsV(void);
435     ExprVector NormalExprsN(void);
436 
437     Vector CubicGetStartNum(void);
438     Vector CubicGetFinishNum(void);
439     ExprVector CubicGetStartTangentExprs(void);
440     ExprVector CubicGetFinishTangentExprs(void);
441     Vector CubicGetStartTangentNum(void);
442     Vector CubicGetFinishTangentNum(void);
443 
444     bool HasEndpoints(void);
445     Vector EndpointStart();
446     Vector EndpointFinish();
447 
448     void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index);
449     void GenerateEquations(IdList<Equation,hEquation> *l);
450 
Clear(void)451     void Clear(void) {}
452 };
453 
454 class Entity : public EntityBase {
455 public:
456     // Necessary for Entity e = {} to zero-initialize, since
457     // classes with base classes are not aggregates and
458     // the default constructor does not initialize members.
459     //
460     // Note EntityBase({}); without explicitly value-initializing
461     // the base class, MSVC2013 will default-initialize it, leaving
462     // POD members with indeterminate value.
Entity()463     Entity() : EntityBase({}), forceHidden(), actPoint(), actNormal(),
464         actDistance(), actVisible(), style(), construction(),
465         beziers(), edges(), edgesChordTol(), screenBBox(), screenBBoxValid(),
466         dogd() {};
467 
468     // A linked entity that was hidden in the source file ends up hidden
469     // here too.
470     bool        forceHidden;
471 
472     // All points/normals/distances have their numerical value; this is
473     // a convenience, to simplify the link/assembly code, so that the
474     // part is entirely described by the entities.
475     Vector      actPoint;
476     Quaternion  actNormal;
477     double      actDistance;
478     // and the shown state also gets saved here, for later import
479     bool        actVisible;
480 
481     hStyle      style;
482     bool        construction;
483 
484     SBezierList beziers;
485     SEdgeList   edges;
486     double      edgesChordTol;
487     BBox        screenBBox;
488     bool        screenBBoxValid;
489 
490     // Routines to draw and hit-test the representation of the entity
491     // on-screen.
492     struct {
493         bool        drawing;
494         Point2d     mp;
495         double      dmin;
496         Vector      refp;
497         double      lineWidth;
498         double      stippleScale;
499         int         stippleType;
500         int         data;
501     } dogd; // state for drawing or getting distance (for hit testing)
502     void LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat=false, int userData = -1);
503     void DrawOrGetDistance(void);
504 
505     bool IsStylable();
506     bool IsVisible(void);
507     bool PointIsFromReferences(void);
508 
509     void ComputeInterpolatingSpline(SBezierList *sbl, bool periodic);
510     void GenerateBezierCurves(SBezierList *sbl);
511     void GenerateEdges(SEdgeList *el, bool includingConstruction=false);
512 
513     static void DrawAll(bool drawAsHidden);
514     void Draw(bool drawAsHidden);
515     double GetDistance(Point2d mp);
516     Vector GetReferencePos(void);
517 
518     void CalculateNumerical(bool forExport);
519 
520     std::string DescriptionString(void);
521 
522     SBezierList *GetOrGenerateBezierCurves();
523     SEdgeList *GetOrGenerateEdges();
524     BBox GetOrGenerateScreenBBox(bool *hasBBox);
525 
Clear()526     void Clear() {
527         beziers.l.Clear();
528         edges.l.Clear();
529     }
530 };
531 
532 class EntReqTable {
533 public:
534     typedef struct {
535         int         reqType;
536         int         entType;
537         int         points;
538         bool        useExtraPoints;
539         bool        hasNormal;
540         bool        hasDistance;
541         const char *description;
542     } TableEntry;
543 
544     static const TableEntry Table[];
545 
546     static const char *DescriptionForRequest(int req);
547     static void CopyEntityInfo(const TableEntry *te, int extraPoints,
548             int *ent, int *req, int *pts, bool *hasNormal, bool *hasDistance);
549     static bool GetRequestInfo(int req, int extraPoints,
550                     int *ent, int *pts, bool *hasNormal, bool *hasDistance);
551     static bool GetEntityInfo(int ent, int extraPoints,
552                     int *req, int *pts, bool *hasNormal, bool *hasDistance);
553     static int GetRequestForEntity(int ent);
554 };
555 
556 class Param {
557 public:
558     int         tag;
559     hParam      h;
560 
561     double      val;
562     bool        known;
563     bool        free;
564 
565     // Used only in the solver
566     hParam      substd;
567 
568     static const hParam NO_PARAM;
569 
Clear(void)570     void Clear(void) {}
571 };
572 
573 
574 class hConstraint {
575 public:
576     uint32_t v;
577 
578     inline hEquation equation(int i);
579 };
580 
581 class ConstraintBase {
582 public:
583     int         tag;
584     hConstraint h;
585 
586     static const hConstraint NO_CONSTRAINT;
587 
588     enum {
589         POINTS_COINCIDENT      =  20,
590         PT_PT_DISTANCE         =  30,
591         PT_PLANE_DISTANCE      =  31,
592         PT_LINE_DISTANCE       =  32,
593         PT_FACE_DISTANCE       =  33,
594         PROJ_PT_DISTANCE       =  34,
595         PT_IN_PLANE            =  41,
596         PT_ON_LINE             =  42,
597         PT_ON_FACE             =  43,
598         EQUAL_LENGTH_LINES     =  50,
599         LENGTH_RATIO           =  51,
600         EQ_LEN_PT_LINE_D       =  52,
601         EQ_PT_LN_DISTANCES     =  53,
602         EQUAL_ANGLE            =  54,
603         EQUAL_LINE_ARC_LEN     =  55,
604         LENGTH_DIFFERENCE      =  56,
605         SYMMETRIC              =  60,
606         SYMMETRIC_HORIZ        =  61,
607         SYMMETRIC_VERT         =  62,
608         SYMMETRIC_LINE         =  63,
609         AT_MIDPOINT            =  70,
610         HORIZONTAL             =  80,
611         VERTICAL               =  81,
612         DIAMETER               =  90,
613         PT_ON_CIRCLE           = 100,
614         SAME_ORIENTATION       = 110,
615         ANGLE                  = 120,
616         PARALLEL               = 121,
617         PERPENDICULAR          = 122,
618         ARC_LINE_TANGENT       = 123,
619         CUBIC_LINE_TANGENT     = 124,
620         CURVE_CURVE_TANGENT    = 125,
621         EQUAL_RADIUS           = 130,
622         WHERE_DRAGGED          = 200,
623 
624         COMMENT                = 1000
625     };
626 
627     int         type;
628 
629     hGroup      group;
630     hEntity     workplane;
631 
632     // These are the parameters for the constraint.
633     double      valA;
634     hEntity     ptA;
635     hEntity     ptB;
636     hEntity     entityA;
637     hEntity     entityB;
638     hEntity     entityC;
639     hEntity     entityD;
640     bool        other;
641     bool        other2;
642 
643     bool        reference;  // a ref dimension, that generates no eqs
644     std::string comment;    // since comments are represented as constraints
645 
646     bool HasLabel(void);
647 
648     void Generate(IdList<Equation,hEquation> *l);
649     void GenerateReal(IdList<Equation,hEquation> *l);
650     // Some helpers when generating symbolic constraint equations
651     void ModifyToSatisfy(void);
652     void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index);
653     static Expr *DirectionCosine(hEntity wrkpl, ExprVector ae, ExprVector be);
654     static Expr *Distance(hEntity workplane, hEntity pa, hEntity pb);
655     static Expr *PointLineDistance(hEntity workplane, hEntity pt, hEntity ln);
656     static Expr *PointPlaneDistance(ExprVector p, hEntity plane);
657     static Expr *VectorsParallel(int eq, ExprVector a, ExprVector b);
658     static ExprVector PointInThreeSpace(hEntity workplane, Expr *u, Expr *v);
659 
Clear(void)660     void Clear(void) {}
661 };
662 
663 class Constraint : public ConstraintBase {
664 public:
665     // See Entity::Entity().
Constraint()666     Constraint() : ConstraintBase({}), disp(), dogd() {}
667 
668     // These define how the constraint is drawn on-screen.
669     struct {
670         Vector      offset;
671         hStyle      style;
672     } disp;
673 
674     // State for drawing or getting distance (for hit testing).
675     struct {
676         bool        drawing;
677         Point2d     mp;
678         double      dmin;
679         Vector      refp;
680         SEdgeList   *sel;
681     } dogd;
682 
683     double GetDistance(Point2d mp);
684     Vector GetLabelPos(void);
685     Vector GetReferencePos(void);
686     void Draw(void);
687     void GetEdges(SEdgeList *sel);
688     bool IsStylable();
689     hStyle GetStyle() const;
690     bool HasLabel();
691 
692     void LineDrawOrGetDistance(Vector a, Vector b);
693     bool IsVisible() const;
694     void DrawOrGetDistance(Vector *labelPos);
695     std::string Label(void);
696     bool DoLineExtend(Vector p0, Vector p1, Vector pt, double salient);
697     void DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
698                         Vector offset, Vector *ref, bool trim);
699     void DoArrow(Vector p, Vector dir, Vector n, double width, double angle, double da);
700     void DoLineWithArrows(Vector ref, Vector a, Vector b, bool onlyOneExt);
701     int DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b, bool extend, Vector gr, Vector gu, double swidth, double sheight);
702     int DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b, bool extend = true);
703     void DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu);
704     void StippledLine(Vector a, Vector b);
705     void DoProjectedPoint(Vector *p);
706     void DoEqualLenTicks(Vector a, Vector b, Vector gn);
707     void DoEqualRadiusTicks(hEntity he);
708 
709     std::string DescriptionString(void);
710 
711     static hConstraint AddConstraint(Constraint *c, bool rememberForUndo);
712     static hConstraint AddConstraint(Constraint *c);
713     static void MenuConstrain(int id);
714     static void DeleteAllConstraintsFor(int type, hEntity entityA, hEntity ptA);
715 
716     static hConstraint ConstrainCoincident(hEntity ptA, hEntity ptB);
717     static hConstraint Constrain(int type, hEntity ptA, hEntity ptB, hEntity entityA);
718     static hConstraint Constrain(int type, hEntity ptA, hEntity ptB,
719                                     hEntity entityA, hEntity entityB,
720                                     bool other, bool other2);
721 };
722 
723 class hEquation {
724 public:
725     uint32_t v;
726 
727     inline bool isFromConstraint(void);
728     inline hConstraint constraint(void);
729 };
730 
731 class Equation {
732 public:
733     int         tag;
734     hEquation   h;
735 
736     Expr        *e;
737 
Clear(void)738     void Clear(void) {}
739 };
740 
741 
742 class Style {
743 public:
744     int         tag;
745     hStyle      h;
746 
747     enum {
748         STIPPLE_CONTINUOUS     = 0,
749         STIPPLE_DASH           = 1,
750         STIPPLE_LONG_DASH      = 2,
751         STIPPLE_DASH_DOT       = 3,
752         STIPPLE_DASH_DOT_DOT   = 4,
753         STIPPLE_DOT            = 5,
754         STIPPLE_FREEHAND       = 6,
755         STIPPLE_ZIGZAG         = 7,
756 
757         LAST_STIPPLE           = STIPPLE_ZIGZAG
758     };
759 
760     enum {
761         // If an entity has no style, then it will be colored according to
762         // whether the group that it's in is active or not, whether it's
763         // construction or not, and so on.
764         NO_STYLE       = 0,
765 
766         ACTIVE_GRP     = 1,
767         CONSTRUCTION   = 2,
768         INACTIVE_GRP   = 3,
769         DATUM          = 4,
770         SOLID_EDGE     = 5,
771         CONSTRAINT     = 6,
772         SELECTED       = 7,
773         HOVERED        = 8,
774         CONTOUR_FILL   = 9,
775         NORMALS        = 10,
776         ANALYZE        = 11,
777         DRAW_ERROR     = 12,
778         DIM_SOLID      = 13,
779         HIDDEN_EDGE    = 14,
780         OUTLINE        = 15,
781 
782         FIRST_CUSTOM   = 0x100
783     };
784 
785     std::string name;
786 
787     enum {
788         UNITS_AS_PIXELS   = 0,
789         UNITS_AS_MM       = 1
790     };
791     double      width;
792     int         widthAs;
793     double      textHeight;
794     int         textHeightAs;
795     enum {
796         ORIGIN_LEFT       = 0x01,
797         ORIGIN_RIGHT      = 0x02,
798         ORIGIN_BOT        = 0x04,
799         ORIGIN_TOP        = 0x08
800     };
801     int         textOrigin;
802     double      textAngle;
803     RgbaColor   color;
804     bool        filled;
805     RgbaColor   fillColor;
806     bool        visible;
807     bool        exportable;
808     int         stippleType;
809     double      stippleScale;
810     int         zIndex;
811 
812     // The default styles, for entities that don't have a style assigned yet,
813     // and for datums and such.
814     typedef struct {
815         hStyle      h;
816         const char *cnfPrefix;
817         RgbaColor   color;
818         double      width;
819         int         zIndex;
820     } Default;
821     static const Default Defaults[];
822 
823     static std::string CnfColor(const std::string &prefix);
824     static std::string CnfWidth(const std::string &prefix);
825     static std::string CnfTextHeight(const std::string &prefix);
826     static std::string CnfPrefixToName(const std::string &prefix);
827 
828     static void CreateAllDefaultStyles(void);
829     static void CreateDefaultStyle(hStyle h);
830     static void FillDefaultStyle(Style *s, const Default *d = NULL, bool factory = false);
831     static void FreezeDefaultStyles(void);
832     static void LoadFactoryDefaults(void);
833 
834     static void AssignSelectionToStyle(uint32_t v);
835     static uint32_t CreateCustomStyle(bool rememberForUndo = true);
836 
837     static RgbaColor RewriteColor(RgbaColor rgb);
838 
839     static Style *Get(hStyle hs);
840     static RgbaColor Color(hStyle hs, bool forExport=false);
841     static RgbaColor FillColor(hStyle hs, bool forExport=false);
842     static float Width(hStyle hs);
843     static RgbaColor Color(int hs, bool forExport=false);
844     static float Width(int hs);
845     static double WidthMm(int hs);
846     static double TextHeight(hStyle hs);
847     static double DefaultTextHeight();
848     static bool Exportable(int hs);
849     static hStyle ForEntity(hEntity he);
850     static int PatternType(hStyle hs);
851     static double StippleScaleMm(hStyle hs);
852 
853     std::string DescriptionString(void);
854 
Clear(void)855     void Clear(void) {}
856 };
857 
858 
entity(int i)859 inline hEntity hGroup::entity(int i)
860     { hEntity r; r.v = 0x80000000 | (v << 16) | (uint32_t)i; return r; }
param(int i)861 inline hParam hGroup::param(int i)
862     { hParam r; r.v = 0x80000000 | (v << 16) | (uint32_t)i; return r; }
equation(int i)863 inline hEquation hGroup::equation(int i)
864     { hEquation r; r.v = (v << 16) | 0x80000000 | (uint32_t)i; return r; }
865 
IsFromReferences(void)866 inline bool hRequest::IsFromReferences(void) {
867     if(v == Request::HREQUEST_REFERENCE_XY.v) return true;
868     if(v == Request::HREQUEST_REFERENCE_YZ.v) return true;
869     if(v == Request::HREQUEST_REFERENCE_ZX.v) return true;
870     return false;
871 }
entity(int i)872 inline hEntity hRequest::entity(int i)
873     { hEntity r; r.v = (v << 16) | (uint32_t)i; return r; }
param(int i)874 inline hParam hRequest::param(int i)
875     { hParam r; r.v = (v << 16) | (uint32_t)i; return r; }
876 
isFromRequest(void)877 inline bool hEntity::isFromRequest(void)
878     { if(v & 0x80000000) return false; else return true; }
request(void)879 inline hRequest hEntity::request(void)
880     { hRequest r; r.v = (v >> 16); return r; }
group(void)881 inline hGroup hEntity::group(void)
882     { hGroup r; r.v = (v >> 16) & 0x3fff; return r; }
equation(int i)883 inline hEquation hEntity::equation(int i)
884     { if(i != 0) oops(); hEquation r; r.v = v | 0x40000000; return r; }
885 
request(void)886 inline hRequest hParam::request(void)
887     { hRequest r; r.v = (v >> 16); return r; }
888 
889 
equation(int i)890 inline hEquation hConstraint::equation(int i)
891     { hEquation r; r.v = (v << 16) | (uint32_t)i; return r; }
892 
isFromConstraint(void)893 inline bool hEquation::isFromConstraint(void)
894     { if(v & 0xc0000000) return false; else return true; }
constraint(void)895 inline hConstraint hEquation::constraint(void)
896     { hConstraint r; r.v = (v >> 16); return r; }
897 
898 // The format for entities stored on the clipboard.
899 class ClipboardRequest {
900 public:
901     int         type;
902     int         extraPoints;
903     hStyle      style;
904     std::string str;
905     std::string font;
906     bool        construction;
907 
908     Vector      point[MAX_POINTS_IN_ENTITY];
909     double      distance;
910 
911     hEntity     oldEnt;
912     hEntity     oldPointEnt[MAX_POINTS_IN_ENTITY];
913     hRequest    newReq;
914 };
915 
916 #endif
917