wxArt2D
canobj3d.cpp
Go to the documentation of this file.
1 /*! \file canextobj/src/canobj3d.cpp
2  \author Klaas Holwerda
3 
4  Copyright: 2000-2004 (c) Klaas Holwerda
5 
6  Licence: wxWidgets Licence
7 
8  RCS-ID: $Id: canobj3d.cpp,v 1.31 2008/07/19 18:29:43 titato Exp $
9 */
10 
11 #include "a2dprec.h"
12 
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16 
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19 #endif
20 
21 #include <wx/wfstream.h>
22 #include <math.h>
23 
24 #include "wx/canextobj/canobj3d.h"
25 
26 #include "wx/editor/candoc.h"
27 #include "wx/canvas/polygon.h"
28 #include "wx/canvas/drawer.h"
29 
30 //----------------------------------------------------------------------------
31 // globals
32 //----------------------------------------------------------------------------
33 
34 IMPLEMENT_CLASS( a2d3DShape, a2dCanvasObject )
35 
36 #define CIRCLE_STEPS 128
37 
38 //----------------------------------------------------------------------------
39 // a2d3DShape
40 //----------------------------------------------------------------------------
41 
42 a2d3DShape::a2d3DShape( a2dCanvasObject* toshadow, double depth, double angle ): a2dCanvasObject()
43 {
44  m_shape = toshadow;
45 
46  SetFill( *a2dBLACK_FILL );
47  SetStroke( *a2dBLACK_STROKE );
48  m_depth = depth;
49  m_angle3d = wxDegToRad( angle );
50 }
51 
52 a2d3DShape::~a2d3DShape()
53 {
54 }
55 
56 a2d3DShape::a2d3DShape( const a2d3DShape& other, CloneOptions options, a2dRefMap* refs )
57  : a2dCanvasObject( other, options, refs )
58 {
59  m_depth = other.m_depth;
60  m_angle3d = other.m_angle3d;
61  m_shape = other.m_shape;
62 }
63 
65 {
66  return new a2d3DShape( *this, options, refs );
67 };
68 
69 void a2d3DShape::SetExtrudeFillFromShape()
70 {
71  SetFill( m_shape->GetFill() );
72  SetPending( true );
73 }
74 void a2d3DShape::SetExtrudeStrokeFromShape()
75 {
76  SetStroke( m_shape->GetStroke() );
77  SetPending( true );
78 }
79 
80 void a2d3DShape::DoWalker( wxObject* parent, a2dWalkerIOHandler& handler )
81 {
82  a2dCanvasObject::DoWalker( parent, handler );
83  if ( m_shape )
84  m_shape->Walker( this, handler );
85 }
86 
87 bool a2d3DShape::DoUpdate( UpdateMode mode, const a2dBoundingBox& childbox, const a2dBoundingBox& clipbox, const a2dBoundingBox& propbox )
88 {
89  bool calc = false;
90  //the object does not have to be part of a group
91  //calculate boundingbox here AND in group
92  //since we do not know which one is reached first
93  if ( m_shape->GetRoot() == m_root ) //only if part of this root
94  {
95  calc = m_shape->Update( mode );
96  if ( ( mode & updatemask_force ) || calc || !m_bbox.GetValid() )
97  {
98  m_bbox.SetValid( false );
99  m_bbox.Expand( m_shape->GetMappedBbox( m_lworld ) );
100 
101  a2dAffineMatrix tworld = m_lworld;
102  tworld.Translate( cos( m_angle3d )*m_depth, sin( m_angle3d )*m_depth );
103  m_bbox.Expand( m_shape->GetMappedBbox( tworld ) );
104 
105  calc = true;
106  }
107  }
108 
109  return calc;
110 }
111 
112 void a2d3DShape::DoRender( a2dIterC& ic, OVERLAP WXUNUSED( clipparent ) )
113 {
114  a2dAffineMatrix inverse = m_lworld;
115  inverse.Invert();
116 
117  a2dAffineMatrix tworld = ic.GetTransform();
118  tworld *= inverse;
119 
120  a2dRectC* rec = wxDynamicCast( m_shape.Get(), a2dRectC );
121  if ( rec )
122  {
123  a2dVertexArray* cpoints = new a2dVertexArray;
124  a2dAffineMatrix tworld = ic.GetTransform();
125  tworld *= m_shape->GetTransformMatrix();
126 
127  //here the Drawer gets a new relative transform
128  //Every call for drawing something on it, will use it.
129  ic.GetDrawer2D()->SetTransform( tworld );
130 
131  if ( m_angle3d > 0 )
132  {
133  cpoints->push_back( new a2dLineSegment( -rec->GetWidth() / 2, rec->GetHeight() / 2 ) );
134  cpoints->push_back( new a2dLineSegment( -rec->GetWidth() / 2 + cos( m_angle3d - wxPI / 30 )*m_depth, rec->GetHeight() / 2 + sin( m_angle3d - wxPI / 30 )*m_depth ) );
135  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2 + cos( m_angle3d )*m_depth, rec->GetHeight() / 2 + sin( m_angle3d - wxPI / 30 )*m_depth ) );
136  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, rec->GetHeight() / 2 ) );
137 
138  ic.GetDrawer2D()->DrawPolygon( cpoints, false, wxWINDING_RULE );
139  cpoints->clear();
140  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, rec->GetHeight() / 2 ) );
141  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2 + cos( m_angle3d )*m_depth, rec->GetHeight() / 2 + sin( m_angle3d - wxPI / 30 )*m_depth ) );
142  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2 + cos( m_angle3d )*m_depth, -rec->GetHeight() / 2 + sin( m_angle3d )*m_depth ) );
143  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, -rec->GetHeight() / 2 ) );
144 
145  ic.GetDrawer2D()->DrawPolygon( cpoints, false, wxWINDING_RULE );
146  }
147  else// (m_angle3d <= 0)
148  {
149  //set up a polygon in world coordinates that represents the cubicle
150  cpoints->push_back( new a2dLineSegment( -rec->GetWidth() / 2, -rec->GetHeight() / 2 ) );
151  cpoints->push_back( new a2dLineSegment( -rec->GetWidth() / 2 + cos( m_angle3d + wxPI / 30 )*m_depth, -rec->GetHeight() / 2 + sin( m_angle3d + wxPI / 30 )*m_depth ) );
152  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2 + cos( m_angle3d )*m_depth, -rec->GetHeight() / 2 + sin( m_angle3d + wxPI / 30 )*m_depth ) );
153  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, -rec->GetHeight() / 2 ) );
154 
155  ic.GetDrawer2D()->DrawPolygon( cpoints, false, wxWINDING_RULE );
156  cpoints->clear();
157  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, rec->GetHeight() / 2 ) );
158  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2 + cos( m_angle3d )*m_depth, rec->GetHeight() / 2 + sin( m_angle3d )*m_depth ) );
159  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2 + cos( m_angle3d )*m_depth, -rec->GetHeight() / 2 + sin( m_angle3d + wxPI / 30 )*m_depth ) );
160  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, -rec->GetHeight() / 2 ) );
161 
162  ic.GetDrawer2D()->DrawPolygon( cpoints, false, wxWINDING_RULE );
163  }
164 
165  cpoints->push_back( new a2dLineSegment( -rec->GetWidth() / 2, -rec->GetHeight() / 2 ) );
166  cpoints->push_back( new a2dLineSegment( -rec->GetWidth() / 2, rec->GetHeight() / 2 ) );
167  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, rec->GetHeight() / 2 ) );
168  cpoints->push_back( new a2dLineSegment( rec->GetWidth() / 2, -rec->GetHeight() / 2 ) );
169 
170  ic.GetDrawer2D()->DrawPolygon( cpoints, false, wxWINDING_RULE );
171 
172  cpoints->clear();
173 
174  delete cpoints;
175  }
176 }
177 
178 #if wxART2D_USE_CVGIO
179 void a2d3DShape::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut& out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
180 {
181  a2dCanvasObject::DoSave( parent, out, xmlparts, towrite );
182  if ( xmlparts == a2dXmlSer_attrib )
183  {
184  }
185  else
186  {
187  //only write the referenced object once
188  if ( m_shape->GetRoot() == m_root )
189  {
190  m_shape->Save( this, out, towrite );
191  }
192  }
193 }
194 
195 void a2d3DShape::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
196 {
197  a2dCanvasObject::DoLoad( parent, parser, xmlparts );
198 }
199 
200 #endif //wxART2D_USE_CVGIO
201 
202 bool a2d3DShape::DoIsHitWorld( a2dIterC& WXUNUSED( ic ), a2dHitEvent& hitEvent )
203 {
204  hitEvent.m_how = a2dHit::stock_fill;
205  return true;
206  //TODO
207  //return (m_shape->IsHitWorld( cworld, x, y, total, distance, margin, layer, mask ));
208 }
209 
a2dHit m_how
return in which way the object was hit (stroke, fill, ...)
Definition: canobj.h:301
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Definition: gen.h:75
virtual void SetTransform(const a2dAffineMatrix &userToWorld)
set user-to-world transform matrix.
Definition: drawer2d.cpp:446
void DoRender(a2dIterC &ic, OVERLAP clipparent)
render derived object
Definition: canobj3d.cpp:112
double GetWidth() const
return width
Definition: canprim.h:147
const a2dStroke * a2dBLACK_STROKE
global a2dStroke stock object for BLACK stroking
const a2dAffineMatrix & GetTransformMatrix() const
get the matrix used to position the object
Definition: canobj.h:500
class to map references to objects stored in XML, in order to make the connection later on...
Definition: gen.h:3462
a2dDrawing * m_root
root group for rendering and accessing the canvas&#39;s also contains layer settings
Definition: canobj.h:2525
void SetValid(bool)
Definition: bbox.cpp:364
const a2dFill * a2dBLACK_FILL
global a2dFill stock object for BLACK filling
Ref Counted base object.
Definition: gen.h:1045
bool DoUpdate(UpdateMode mode, const a2dBoundingBox &childbox, const a2dBoundingBox &clipbox, const a2dBoundingBox &propbox)
Update derived Object specific things ( mainly boundingbox)
Definition: canobj3d.cpp:87
a2dDrawing * GetRoot() const
get a2dCanvasDocument of the object.
Definition: canobj.h:952
double wxDegToRad(double deg)
conversion from degrees to radians
Definition: artglob.cpp:30
virtual bool Update(UpdateMode mode)
Update the state of the object according to its current position etc.
Definition: canobj.cpp:5149
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:819
virtual void DrawPolygon(a2dVertexArray *points, bool spline=false, wxPolygonFillMode fillStyle=wxODDEVEN_RULE)
Draw polygon in world coordinates using pointarray.
Definition: drawer2d.cpp:1889
UpdateMode
Various mode flags for Update.
Definition: canobj.h:1091
virtual a2dObject * DoClone(CloneOptions options, a2dRefMap *refs) const
Clone this object and return a pointer to the new object.
Definition: canobj3d.cpp:64
virtual void SetPending(bool pending)
set this object pending for update
Definition: canobj.cpp:2585
OVERLAP
Result of a a2dBoundingBox intersection or hittest.
Definition: bbox.h:24
a2dRectC is a centered rectangle
Definition: canprim.h:99
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
load object specific CVG data
Definition: canobj.cpp:5728
vertex array of line and arc segments.
Definition: polyver.h:494
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
void DoWalker(wxObject *parent, a2dWalkerIOHandler &handler)
iterate over this object and its children
Definition: canobj3d.cpp:80
a2dAffineMatrix m_lworld
used for positioning the object (x,y,ang,scale etc.)
Definition: canobj.h:2559
Io handler to iterate through a a2dDocument.
Definition: gen.h:3911
bool GetValid() const
returns true if boundingbox is calculated properly and therefore its valid flag is set...
Definition: bbox.cpp:299
void Expand(const a2dPoint2D &, const a2dPoint2D &)
expand boundingbox width two points
Definition: bbox.cpp:155
void Walker(wxObject *parent, a2dWalkerIOHandler &handler)
This is used to recursively walk through an object tree.
Definition: gen.cpp:1473
a2dDrawer2D * GetDrawer2D() const
get current a2dDrawer2D
Definition: canobj.cpp:636
Normal straight line segment in a2dVertexList and a2dVertexArray.
Definition: polyver.h:163
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
write object specific CVGL data
Definition: canobj.cpp:5569
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:862
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
write object specific CVGL data
Definition: canobj3d.cpp:179
while iterating a a2dCanvasDocument, this holds the context.
Definition: canobj.h:3212
All updates of these modes force an update (e.g. update non-pending valid bounding boxes) ...
Definition: canobj.h:1107
a2dBoundingBox GetMappedBbox(a2dIterC &ic, bool withExtend=true)
first translate boundingbox with cworld and recalculate at new position
Definition: canobj.cpp:3256
void SetStroke(const wxColour &strokecolor, double width=0, a2dStrokeStyle style=a2dSTROKE_SOLID)
Set a stroke for the object which will be used instead of the layer stroke.
Definition: canobj.cpp:2924
bool DoIsHitWorld(a2dIterC &ic, a2dHitEvent &hitEvent)
Does hit test on the object (exclusif child objects)
Definition: canobj3d.cpp:202
bool Translate(double x, double y)
Translate by dx, dy:
Definition: afmatrix.cpp:420
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
bool Invert(void)
Invert matrix.
Definition: afmatrix.cpp:197
static a2dHit stock_fill
Stock object for a fill hit.
Definition: polyver.h:137
all polygon and polyline a2dCanvasObject are here.
the a2dDrawingPart is a a2dView specially designed for displaying parts of a a2dDrawing. It uses a a2dDrawer2D to actually redraw things from the document, by giving that a2dDrawer2D as drawing context to the document, and telling the document to redraw a certain rectangular area. At that last is what this class is for. It optimizes the areas to be redrawn after object in the document were changed. To do that it combines redraw areas to a minimal set of redrawing areas. All the administration for this and the way things will be redrawn is from this view.
virtual void Save(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dObjectList *towrite)
write all needed to an XML type of file called the CVG format
Definition: gen.cpp:1343
void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
load object specific CVG data
Definition: canobj3d.cpp:195
a2dBoundingBox m_bbox
boundingbox in world coordinates
Definition: canobj.h:2539
const a2dAffineMatrix & GetTransform() const
Get the accumulated transform up to and including m_lworld of the current object. ...
Definition: canobj.cpp:663
list of a2dObject&#39;s
Definition: gen.h:3157
double GetHeight() const
return height
Definition: canprim.h:149
CloneOptions
options for cloning
Definition: gen.h:1200
structure to give as parameter to member functions of a2dCanvasObject
Definition: canobj.h:252
const double wxPI
defines PI
Definition: artglob.cpp:28
to make object having a shadow behind it OR to extrude them in 3D
Definition: canobj3d.h:33
void SetFill(const a2dFill &fill)
Set a fill for the object which will be used instead of the layer fill.
Definition: canobj.cpp:2874
virtual void DoWalker(wxObject *parent, a2dWalkerIOHandler &handler)
iterate over this object and its children
Definition: canobj.cpp:5504
canobj3d.cpp Source File -- Sun Oct 12 2014 17:04:14 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation