1 /*******************************************************************************
2  *  Project: libopencad
3  *  Purpose: OpenSource CAD formats support library
4  *  Author: Alexandr Borzykh, mush3d at gmail.com
5  *  Author: Dmitry Baryshnikov, bishop.dev@gmail.com
6  *  Language: C++
7  *******************************************************************************
8  *  The MIT License (MIT)
9  *
10  *  Copyright (c) 2016 Alexandr Borzykh
11  *  Copyright (c) 2016 NextGIS, <info@nextgis.com>
12  *
13  *  Permission is hereby granted, free of charge, to any person obtaining a copy
14  *  of this software and associated documentation files (the "Software"), to deal
15  *  in the Software without restriction, including without limitation the rights
16  *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17  *  copies of the Software, and to permit persons to whom the Software is
18  *  furnished to do so, subject to the following conditions:
19  *
20  *  The above copyright notice and this permission notice shall be included in all
21  *  copies or substantial portions of the Software.
22  *
23  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28  *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29  *  SOFTWARE.
30  *******************************************************************************/
31 #ifndef CADGEOMETRIES_H
32 #define CADGEOMETRIES_H
33 
34 #include "cadobjects.h"
35 #include "cadcolors.h"
36 
37 #include <array>
38 
39 class CADAttdef;
40 class CADAttrib;
41 
42 /**
43  * @brief The Matrix class
44  */
45 class Matrix
46 {
47 public:
48               Matrix();
49     void      translate( const CADVector& vector );
50     void      rotate( double rotation );
51     void      scale( const CADVector& vector );
52     CADVector multiply( const CADVector& vector ) const;
53 protected:
54     std::array<double, 9> matrix;
55 };
56 
57 /**
58  * @brief Base CAD geometry class
59  */
60 class OCAD_EXTERN CADGeometry
61 {
62 public:
63     CADGeometry();
64     virtual ~CADGeometry();
65     /**
66      * @brief The CAD geometry types enum
67      */
68     enum GeometryType
69     {
70         UNDEFINED = 0,
71         POINT,
72         CIRCLE,
73         LWPOLYLINE,
74         ELLIPSE,
75         LINE,
76         POLYLINE3D,
77         TEXT,
78         ARC,
79         SPLINE,
80         SOLID,
81         RAY,
82         HATCH, // NOT IMPLEMENTED
83         IMAGE,
84         MTEXT,
85         MLINE,
86         XLINE,
87         FACE3D,
88         POLYLINE_PFACE,
89         ATTRIB,
90         ATTDEF
91     };
92 
93     enum GeometryType getType() const;
94     double            getThickness() const;
95     void              setThickness( double thickness );
96     RGBColor          getColor() const;
97     void              setColor( RGBColor color ); // TODO: In 2004+ ACI is not the only way to set the color.
98 
99     std::vector<CADAttrib> getBlockAttributes() const;
100     void              setBlockAttributes( const std::vector<CADAttrib>& value );
101 
102     std::vector<std::string> getEED() const;
103     void setEED( const std::vector<std::string>& eed );
104 
105     virtual void print() const                     = 0;
106     virtual void transform( const Matrix& matrix ) = 0;
107 protected:
108     std::vector<CADAttrib> blockAttributes; // Attributes of block reference this geometry is attached to.
109 
110     std::vector<std::string>    asEED;
111     enum GeometryType geometryType;
112     double            m_thickness;
113     RGBColor          geometry_color;
114 };
115 
116 /**
117  * @brief Geometry class which represents Unhandled geometry (means that library can't read it yet)
118  */
119 class CADUnknown : public CADGeometry
120 {
121 public:
122     CADUnknown();
~CADUnknown()123     virtual ~CADUnknown(){}
124 
125     virtual void print() const override;
126     void         transform( const Matrix& matrix ) override;
127 };
128 
129 /**
130  * @brief Geometry class which a single Point
131  */
132 class OCAD_EXTERN CADPoint3D : public CADGeometry
133 {
134 public:
135     CADPoint3D();
136     CADPoint3D( const CADVector& positionIn, double thicknessIn );
~CADPoint3D()137     virtual ~CADPoint3D(){}
138     CADVector getPosition() const;
139     void      setPosition( const CADVector& value );
140 
141     CADVector getExtrusion() const;
142     void      setExtrusion( const CADVector& value );
143 
144     double getXAxisAng() const;
145     void   setXAxisAng( double value );
146 
147     virtual void print() const override;
148     virtual void transform( const Matrix& matrix ) override;
149 protected:
150     CADVector position;
151     CADVector extrusion;
152     double    xAxisAng;
153 };
154 
155 /**
156  * @brief Geometry class which represents a simple Line
157  */
158 class OCAD_EXTERN CADLine : public CADGeometry
159 {
160 public:
161     CADLine();
162     CADLine( const CADPoint3D& startIn, const CADPoint3D& endIn );
~CADLine()163     virtual ~CADLine(){}
164     CADPoint3D getStart() const;
165     void       setStart( const CADPoint3D& value );
166 
167     CADPoint3D getEnd() const;
168     void       setEnd( const CADPoint3D& value );
169 
170     virtual void print() const override;
171     virtual void transform( const Matrix& matrix ) override;
172 protected:
173     CADPoint3D start;
174     CADPoint3D end;
175 };
176 
177 /**
178  * @brief Geometry class which represents Polyline 3D
179  */
180 class OCAD_EXTERN CADPolyline3D : public CADGeometry
181 {
182 public:
183     CADPolyline3D();
~CADPolyline3D()184     virtual ~CADPolyline3D(){}
185     void   addVertex( const CADVector& vertex );
186     size_t getVertexCount() const;
187     CADVector& getVertex( size_t index );
188 
189     virtual void print() const override;
190     virtual void transform( const Matrix& matrix ) override;
191 protected:
192     std::vector<CADVector> vertices;
193 };
194 
195 /**
196  * @brief Geometry class which represents LWPolyline
197  */
198 
199 class OCAD_EXTERN CADLWPolyline : public CADPolyline3D
200 {
201 public:
202     CADLWPolyline();
~CADLWPolyline()203     virtual ~CADLWPolyline(){}
204 
205     double getConstWidth() const;
206     void   setConstWidth( double value );
207 
208     double getElevation() const;
209     void   setElevation( double value );
210 
211     CADVector getVectExtrusion() const;
212     void      setVectExtrusion( const CADVector& value );
213 
214     std::vector<std::pair<double, double> > getWidths() const;
215     void  setWidths( const std::vector<std::pair<double, double> >& value );
216 
217     std::vector<double> getBulges() const;
218     void           setBulges( const std::vector<double>& value );
219 
220     bool isClosed() const;
221     void setClosed( bool state );
222 
223     virtual void print() const override;
224 protected:
225     bool                          bClosed;
226     double                        constWidth;
227     double                        elevation;
228     CADVector                     vectExtrusion;
229     std::vector<double>                bulges;
230     std::vector<std::pair<double, double> > widths; // Start & end.
231 };
232 
233 /**
234  * @brief Geometry class which represents Circle
235  */
236 class OCAD_EXTERN CADCircle : public CADPoint3D
237 {
238 public:
239     CADCircle();
~CADCircle()240     virtual ~CADCircle(){}
241 
242     double getRadius() const;
243     void   setRadius( double value );
244 
245     virtual void print() const override;
246 protected:
247     double radius;
248 };
249 
250 /**
251  * @brief Geometry class which represents Text
252  */
253 class OCAD_EXTERN CADText : public CADPoint3D
254 {
255 public:
256     CADText();
~CADText()257     virtual ~CADText(){}
258 
259     std::string getTextValue() const;
260     void   setTextValue( const std::string& value );
261 
262     double getHeight() const;
263     void   setHeight( double value );
264 
265     double getRotationAngle() const;
266     void   setRotationAngle( double value );
267 
268     double getObliqueAngle() const;
269     void   setObliqueAngle( double value );
270 
271     virtual void print() const override;
272 protected:
273     double obliqueAngle;
274     double rotationAngle;
275     double height;
276     std::string textValue;
277 };
278 
279 /**
280  * @brief Geometry class which represents Arc
281  */
282 class OCAD_EXTERN CADArc : public CADCircle
283 {
284 public:
285     CADArc();
~CADArc()286     virtual ~CADArc(){}
287 
288     double getStartingAngle() const;
289     void   setStartingAngle( double value );
290 
291     double getEndingAngle() const;
292     void   setEndingAngle( double value );
293 
294     virtual void print() const override;
295 protected:
296     double startingAngle;
297     double endingAngle;
298 };
299 
300 /**
301  * @brief Geometry class which represents Ellipse
302  */
303 class OCAD_EXTERN CADEllipse : public CADArc
304 {
305 public:
306     CADEllipse();
~CADEllipse()307     virtual ~CADEllipse(){}
308 
309     double getAxisRatio() const;
310     void   setAxisRatio( double value );
311 
312     CADVector getSMAxis();
313     void      setSMAxis( const CADVector& vectSMA );
314 
315     virtual void print() const override;
316 protected:
317     CADVector vectSMAxis;
318     double    axisRatio;
319 };
320 
321 /**
322  * @brief Geometry class which represents Spline
323  */
324 class OCAD_EXTERN CADSpline : public CADGeometry
325 {
326 public:
327     CADSpline();
~CADSpline()328     virtual ~CADSpline(){}
329 
330     long getScenario() const;
331     void setScenario( long value );
332 
333     bool isRational() const;
334     void setRational( bool value );
335 
336     bool isClosed() const;
337     void setClosed( bool value );
338 
339     std::vector<CADVector>& getControlPoints();
340     std::vector<CADVector>& getFitPoints();
341     std::vector<double>   & getControlPointsWeights();
342 
343     void addControlPointsWeight( double p_weight );
344     void addControlPoint( const CADVector& point );
345     void addFitPoint( const CADVector& point );
346 
347     bool getWeight() const;
348     void setWeight( bool value );
349 
350     double getFitTolerance() const;
351     void   setFitTolerance( double value );
352 
353     long getDegree() const;
354     void setDegree( long value );
355 
356     virtual void print() const override;
357     virtual void transform( const Matrix& matrix ) override;
358 protected:
359     long   scenario;
360     bool   rational;
361     bool   closed;
362     bool   weight;
363     double fitTolerance;
364     long   degree;
365 
366     std::vector<double>    ctrlPointsWeight;
367     std::vector<CADVector> avertCtrlPoints;
368     std::vector<CADVector> averFitPoints;
369 };
370 
371 /**
372  * @brief Geometry class which represents Solid
373  */
374 class OCAD_EXTERN CADSolid : public CADPoint3D
375 {
376 public:
377     CADSolid();
~CADSolid()378     virtual ~CADSolid(){}
379 
380     double getElevation() const;
381     void   setElevation( double value );
382     void   addCorner( const CADVector& corner );
383     std::vector<CADVector> getCorners();
384 
385     virtual void print() const override;
386     virtual void transform( const Matrix& matrix ) override;
387 protected:
388     double            elevation;
389     std::vector<CADVector> avertCorners;
390 };
391 
392 /**
393  * @brief Geometry class which represents Ray
394  */
395 class OCAD_EXTERN CADRay : public CADPoint3D
396 {
397 public:
398     CADRay();
~CADRay()399     virtual ~CADRay(){}
400 
401     CADVector getVectVector() const;
402     void      setVectVector( const CADVector& value );
403 
404     virtual void print() const override;
405 };
406 
407 /**
408  * @brief Geometry class which represents Hatch
409  */
410 class OCAD_EXTERN CADHatch : public CADGeometry
411 {
412 public:
413     CADHatch();
~CADHatch()414     virtual ~CADHatch(){}
415 };
416 
417 /**
418  * @brief Geometry class which represents Image (Raster Image)
419  */
420 class OCAD_EXTERN CADImage : public CADGeometry
421 {
422 public:
423     /**
424      * @brief enum which describes in which units Image resolutions is present
425      */
426     enum ResolutionUnit
427     {
428         NONE = 0, CENTIMETER = 2, INCH = 5
429     };
430 
431     CADImage();
~CADImage()432     virtual ~CADImage(){}
433 
434     CADVector getVertInsertionPoint() const;
435     void      setVertInsertionPoint( const CADVector& value );
436 
437     CADVector getImageSize() const;
438     void      setImageSize( const CADVector& value );
439 
440     CADVector getImageSizeInPx() const;
441     void      setImageSizeInPx( const CADVector& value );
442 
443     CADVector getPixelSizeInACADUnits() const;
444     void      setPixelSizeInACADUnits( const CADVector& value );
445 
446     short getClippingBoundaryType() const;
447     void  setClippingBoundaryType( short value );
448 
449     enum ResolutionUnit getResolutionUnits() const;
450     void                setResolutionUnits( enum ResolutionUnit value );
451 
452     std::string getFilePath() const;
453     void   setFilePath( const std::string& value );
454 
455     void setOptions( bool transparency, bool clip, unsigned char brightness,
456                      unsigned char contrast );
457 
458     void addClippingPoint( const CADVector& pt );
459 
460     virtual void print() const override;
461     virtual void transform( const Matrix& matrix ) override;
462 protected:
463     CADVector     vertInsertionPoint;
464     //CADVector vectUDirection;
465     //CADVector vectVDirection;
466     CADVector     imageSize;
467     //bool bShow;
468     //bool bShowWhenNotAlignedWithScreen;
469     //bool bUseClippingBoundary;
470     bool          bTransparency;
471     bool          bClipping;
472     unsigned char dBrightness;
473     unsigned char dContrast;
474     //char dFade;
475 
476     CADVector           imageSizeInPx;
477     std::string         filePath;
478     //bool bIsLoaded;
479     enum ResolutionUnit resolutionUnits;
480     //unsigned char       resolutionUnit; // 0 == none, 2 == centimeters, 5 == inches;
481     CADVector           pixelSizeInACADUnits;
482 
483     short clippingBoundaryType; // 1 == rect, 2 == polygon
484     std::vector<CADVector> avertClippingPolygon;
485 };
486 
487 /**
488  * @brief Geometry class which represents MText
489  */
490 class OCAD_EXTERN CADMText : public CADText
491 {
492 public:
493     CADMText();
~CADMText()494     virtual ~CADMText(){}
495 
496     double getRectWidth() const;
497     void   setRectWidth( double value );
498 
499     double getExtents() const;
500     void   setExtents( double value );
501 
502     double getExtentsWidth() const;
503     void   setExtentsWidth( double value );
504 
505     virtual void print() const override;
506 protected:
507     double rectWidth;
508     double extents;
509     double extentsWidth;
510     // TODO: do we need this here?
511     //short dDrawingDir;
512     //short dLineSpacingStyle;
513     //short dLineSpacingFactor;
514     //long dBackgroundFlags; // R2004+
515     //long dBackgroundScaleFactor;
516     //short dBackgroundColor;
517     //long dBackgroundTransparency;
518 };
519 
520 /**
521  * @brief Geometry class which represents 3DFace
522  */
523 class OCAD_EXTERN CADFace3D : public CADGeometry
524 {
525 public:
526     CADFace3D();
~CADFace3D()527     virtual ~CADFace3D(){}
528 
529     void      addCorner( const CADVector& corner );
530     CADVector getCorner( size_t index );
531 
532     short getInvisFlags() const;
533     void  setInvisFlags( short value );
534 
535     virtual void print() const override;
536     virtual void transform( const Matrix& matrix ) override;
537 protected:
538     std::vector<CADVector> avertCorners;
539     short             invisFlags;
540 };
541 
542 /**
543  * @brief Geometry class which represents Polyline (PFace)
544  */
545 class OCAD_EXTERN CADPolylinePFace : public CADGeometry
546 {
547 public:
548     CADPolylinePFace();
~CADPolylinePFace()549     virtual ~CADPolylinePFace(){}
550 
551     void addVertex( const CADVector& vertex );
552 
553     virtual void print() const override;
554     virtual void transform( const Matrix& matrix ) override;
555 protected:
556     std::vector<CADVector> vertices;
557 };
558 
559 /**
560  * @brief Geometry class which represents XLine
561  */
562 class OCAD_EXTERN CADXLine : public CADRay
563 {
564 public:
565     CADXLine();
~CADXLine()566     virtual ~CADXLine(){}
567 
568     virtual void print() const override;
569 };
570 
571 /**
572  * @brief Geometry class which represents MLine
573  */
574 class OCAD_EXTERN CADMLine : public CADPoint3D
575 {
576 public:
577     CADMLine();
~CADMLine()578     virtual ~CADMLine(){}
579 
580     double getScale() const;
581     void   setScale( double value );
582 
583     bool isOpened() const;
584     void setOpened( bool value );
585 
586     void addVertex( const CADVector& vertex );
587 
588     virtual void print() const override;
589     virtual void transform( const Matrix& matrix ) override;
590 protected:
591     double            scale;
592     //char dJust;
593     bool              opened; // 1 == open, 0 == close
594     // TODO: do we need more properties here?
595     std::vector<CADVector> avertVertices;
596 };
597 
598 /**
599  * @brief Geometry class which represents Attribute
600  */
601 class OCAD_EXTERN CADAttrib : public CADText
602 {
603 public:
604     CADAttrib();
~CADAttrib()605     virtual ~CADAttrib(){}
606 
607     double getElevation() const;
608     void   setElevation( double );
609 
610     std::string getTag() const;
611     void   setTag( const std::string& );
612 
613     CADVector getAlignmentPoint() const;
614     void      setAlignmentPoint( const CADVector& );
615 
616     bool isPositionLocked() const;
617     void setPositionLocked( bool );
618 
619     virtual void print() const override;
620     virtual void transform( const Matrix& matrix ) override;
621 protected:
622     CADVector vertAlignmentPoint;
623     double    dfElevation;
624     std::string    sTag;
625     bool      bLockPosition;
626 };
627 
628 /**
629  * @brief Geometry class which represents Attribute definition
630  */
631 class OCAD_EXTERN CADAttdef : public CADAttrib
632 {
633 public:
634     CADAttdef();
~CADAttdef()635     virtual ~CADAttdef(){}
636 
637     std::string getPrompt() const;
638     void   setPrompt( const std::string& );
639 
640     virtual void print() const override;
641 protected:
642     std::string sPrompt;
643 };
644 
645 //class EXTERN LineType
646 //{
647 //public:
648 //    std::string sEntryName;
649 //    std::string sDescription;
650 //    double dfPatternLen;
651 //    char dAlignment;
652 //    char nNumDashes;
653 //    struct Dash
654 //    {
655 //        double dfLength;
656 //        short dComplexShapecode;
657 //        double dfXOffset;
658 //        double dfYOffset;
659 //        double dfScale;
660 //        double dfRotation;
661 //        short dShapeflag;
662 //    };
663 //    std::vector < char > abyTextArea; // TODO: what is it?
664 //    std::vector < CADHandle > hShapefiles; // TODO: one for each dash?
665 //};
666 
667 //class EXTERN Block
668 //{
669 //public:
670 //    Block(CADFile * pCADFile)
671 //    {
672 //        pstCADFile_m = pCADFile;
673 //    }
674 //
675 //    std::string sBlockName;
676 //
677 //    CADFile * pstCADFile_m;
678 //
679 //    std::vector < std::pair < long long, short > > astAttachedGeometries;
680 //};
681 
682 
683 #endif // CADGEOMETRIES_H
684