00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "a2dprec.h"
00012
00013 #ifdef __BORLANDC__
00014 #pragma hdrstop
00015 #endif
00016
00017 #ifndef WX_PRECOMP
00018 #include "wx/wx.h"
00019 #endif
00020
00021 #include "a2dprivate.h"
00022
00023 #if wxART2D_USE_KBOOL
00024
00025 #include "wx/canvas/canmod.h"
00026 #include "wx/canvas/booloper.h"
00027
00028 const long a2dBooleanWalkerHandler::Boolean_NON = wxGenNewId();
00029 const long a2dBooleanWalkerHandler::Boolean_OR = wxGenNewId();
00030 const long a2dBooleanWalkerHandler::Boolean_AND = wxGenNewId();
00031 const long a2dBooleanWalkerHandler::Boolean_EXOR = wxGenNewId();
00032 const long a2dBooleanWalkerHandler::Boolean_A_SUB_B = wxGenNewId();
00033 const long a2dBooleanWalkerHandler::Boolean_B_SUB_A = wxGenNewId();
00034 const long a2dBooleanWalkerHandler::Boolean_CORRECTION = wxGenNewId();
00035 const long a2dBooleanWalkerHandler::Boolean_SMOOTHEN = wxGenNewId();
00036 const long a2dBooleanWalkerHandler::Boolean_MAKERING = wxGenNewId();
00037 const long a2dBooleanWalkerHandler::Boolean_Polygon2Surface = wxGenNewId();
00038 const long a2dBooleanWalkerHandler::Boolean_Surface2Polygon = wxGenNewId();
00039
00040
00041
00042 a2dBooleanWalkerHandler::a2dBooleanWalkerHandler( a2dCanvasObjectFlagsMask mask )
00043 :a2dWalker_LayerCanvasObjects( mask )
00044 {
00045 Initialize();
00046 m_mask = mask;
00047 }
00048
00049 a2dBooleanWalkerHandler::~a2dBooleanWalkerHandler()
00050 {
00051 delete m_booleng;
00052 }
00053
00054 void a2dBooleanWalkerHandler::Initialize()
00055 {
00056 a2dWalker_FilterCanvasObjects::Initialize();
00057
00058 m_useCheck = true;
00059 m_depthFirst = true;
00060 m_clearTarget = true;
00061 m_resultOnSameLayer = false;
00062 m_releaseOrignals = false;
00063 m_firstLevelChild = false;
00064
00065 m_resultStroke = *a2dNullSTROKE;
00066 m_resultFill = *a2dNullFILL;
00067 m_useFirstChildStyle = false;
00068
00069 m_booleng = new Bool_Engine();
00070
00071
00072 double DGRID = 0.01;
00073 double MARGE = 0.1;
00074
00075
00076
00077 double CORRECTIONFACTOR = 500.0;
00078 double CORRECTIONABER = 1.0;
00079 double ROUNDFACTOR = 1.5;
00080 double SMOOTHABER = 0.001;
00081 double MAXLINEMERGE = 1000.0;
00082
00083 if (MARGE <= DGRID)
00084 {
00085 MARGE = DGRID*10;
00086 }
00087
00088
00089
00090
00091
00092 if ( DGRID < 1 )
00093 DGRID = 1/DGRID;
00094 else
00095 DGRID = 1;
00096
00097
00098
00099 int GRID =100;
00100
00101 m_booleng->SetMarge( MARGE );
00102 m_booleng->SetGrid( GRID );
00103 m_booleng->SetDGrid( DGRID );
00104
00105
00106
00107
00108
00109 m_booleng->SetCorrectionFactor( CORRECTIONFACTOR );
00110 m_booleng->SetCorrectionAber( CORRECTIONABER );
00111 m_booleng->SetSmoothAber( SMOOTHABER );
00112 m_booleng->SetMaxlinemerge( MAXLINEMERGE );
00113 m_booleng->SetRoundfactor( ROUNDFACTOR );
00114 m_booleng->SetOrientationEntryMode( false );
00115 }
00116
00117 bool a2dBooleanWalkerHandler::Start( a2dCanvasObject* object )
00118 {
00119 m_lastdepth = 0;
00120
00121 a2dWalker_SetBoolProperty setp( PROPID_Check, false );
00122 setp.Start( object );
00123 a2dWalker_SetSpecificFlagsCanvasObjects setflags( a2dCanvasOFlags::BIN | a2dCanvasOFlags::BIN2 );
00124 setflags.Start( object, false );
00125
00126 try
00127 {
00128 object->Walker( NULL, *this );
00129 }
00130 catch ( Bool_Engine_Error & error )
00131 {
00132 wxString str( error.GetErrorMessage().data(),wxConvUTF8, error.GetErrorMessage().size() );
00133 a2dDocviewGlobals->ReportErrorF( a2dError_CommandError, str );
00134 }
00135 catch ( ... )
00136 {
00137 a2dDocviewGlobals->ReportErrorF( a2dError_CommandError, _("Problem performing boolean operation") );
00138 return false;
00139 }
00140 return true;
00141 }
00142
00143 bool a2dBooleanWalkerHandler::WalkTask( wxObject* parent, wxObject* object, a2dWalkEvent event )
00144 {
00145
00146 if ( m_currentDepth > m_depth || event == a2dWalker_a2dPropObjectStart )
00147 SetStopWalking( true );
00148
00149 if ( event == a2dWalker_a2dObjectStart )
00150 {
00151
00152
00153 a2dCanvasObject* obj = wxDynamicCast( object, a2dCanvasObject );
00154 if ( obj && m_currentDepth == 2 && ObjectOke( obj ) && !obj->GetCheck() )
00155 {
00156 if ( !m_selectedOnlyA || (m_selectedOnlyA && obj->GetSelected()) )
00157 m_firstLevelChild = true;
00158 if ( !m_selectedOnlyB || (m_selectedOnlyB && obj->GetSelected()) )
00159 m_firstLevelChild = true;
00160 obj->SetCheck( true );
00161 }
00162 }
00163
00164
00165
00166 if ( event == a2dWalker_a2dCanvasObjectStart )
00167 {
00168 m_lastdepth = m_currentDepth;
00169
00170 a2dCanvasObject* canobj = (a2dCanvasObject*) object;
00171
00172
00173
00174 if ( canobj && parent && !canobj->GetBin() && !canobj->GetIgnoreLayer() && m_firstLevelChild )
00175 {
00176
00177 bool hasLayer = false;
00178 forEachIn( a2dLayerGroup, &m_groupA )
00179 {
00180 wxUint16 layer = *iter;
00181
00182 if ( wxLAYER_ALL == layer )
00183 {
00184 hasLayer = true;
00185 break;
00186 }
00187 if ( canobj->GetLayer() == layer )
00188 hasLayer = true;
00189 }
00190
00191
00192 if ( hasLayer )
00193 m_foundA.push_back( canobj );
00194
00195 {
00196 hasLayer = false;
00197 forEachIn( a2dLayerGroup, &m_groupB )
00198 {
00199 wxUint16 layer = *iter;
00200
00201 if ( wxLAYER_ALL == layer )
00202 {
00203 hasLayer = true;
00204 break;
00205 }
00206 if ( canobj->GetLayer() == layer )
00207 hasLayer = true;
00208 }
00209
00210
00211 if ( hasLayer )
00212 m_foundB.push_back( canobj );
00213 }
00214 }
00215
00216
00217 if ( ( !m_foundA.empty() || !m_foundB.empty() ) &&
00218 ( m_operation == Boolean_Polygon2Surface || m_operation == Boolean_Surface2Polygon ) )
00219 {
00220 a2dCanvasObject* canobjToAddTo = (a2dCanvasObject*) parent;
00221 CallEngine( canobjToAddTo );
00222 }
00223 }
00224
00225 if ( !m_foundA.empty() || !m_foundB.empty() )
00226 {
00227 if ( event == a2dWalker_a2dCanvasObjectEnd && m_lastdepth > m_currentDepth )
00228 {
00229 a2dCanvasObject* canobj = (a2dCanvasObject*) object;
00230 #if defined(_DEBUG)
00231 wxString name = canobj->GetName();
00232 #endif
00233
00234 CallEngine( canobj );
00235
00236
00237 if ( m_clearTarget )
00238 {
00239 forEachIn( a2dCanvasObjectList, canobj->GetChildObjectList() )
00240 {
00241 a2dCanvasObject *obj = (*iter);
00242 if ( !obj->GetBin2() && obj->GetLayer() == m_target && !obj->GetIgnoreLayer() )
00243 obj->SetRelease( true );
00244 }
00245 }
00246 }
00247 }
00248 else if ( m_clearTarget &&
00249 ( m_operation == Boolean_Polygon2Surface || m_operation == Boolean_Surface2Polygon ) )
00250 {
00251 if ( event == a2dWalker_a2dCanvasObjectEnd && m_lastdepth > m_currentDepth )
00252 {
00253 a2dCanvasObject* canobj = (a2dCanvasObject*) object;
00254 forEachIn( a2dCanvasObjectList, canobj->GetChildObjectList() )
00255 {
00256 a2dCanvasObject *obj = (*iter);
00257 if ( !obj->GetBin2() && obj->GetLayer() == m_target && !obj->GetIgnoreLayer() )
00258 obj->SetRelease( true );
00259 }
00260 }
00261 }
00262
00263 if ( event == a2dWalker_a2dCanvasObjectEnd && m_lastdepth > m_currentDepth )
00264 {
00265 a2dCanvasObject* canobj = (a2dCanvasObject*) object;
00266
00267
00268 m_lastdepth = m_currentDepth;
00269 }
00270
00271 if ( event == a2dWalker_a2dObjectEnd )
00272 {
00273
00274 if ( m_currentDepth <= 2 )
00275 {
00276 m_firstLevelChild = false;
00277 }
00278 }
00279
00280 if ( m_currentDepth <= m_depth && event == a2dWalker_a2dPropObjectEnd )
00281 SetStopWalking( false );
00282
00283 if ( event == a2dWalker_a2dCanvasObjectPostChild )
00284 return false;
00285
00286 return true;
00287 }
00288
00289 bool a2dBooleanWalkerHandler::GetObjectsForSurface( a2dCanvasObject* booleanobject, GroupType A_or_B )
00290 {
00291 a2dCanvasObjectList* vpath = wxNullCanvasObjectList;
00292 if (0 != wxDynamicCast( booleanobject, a2dRect ) && booleanobject->GetContourWidth() )
00293 {
00294 a2dRect* obj = wxDynamicCast( booleanobject, a2dRect );
00295 vpath = obj->GetAsCanvasVpaths();
00296 }
00297 else if (0 != wxDynamicCast( booleanobject, a2dCircle ) && booleanobject->GetContourWidth() )
00298 {
00299 a2dCircle* obj = wxDynamicCast( booleanobject, a2dCircle );
00300 vpath = obj->GetAsCanvasVpaths();
00301 }
00302 else if (0 != wxDynamicCast( booleanobject, a2dEllipse ) && booleanobject->GetContourWidth() )
00303 {
00304 a2dEllipse* obj = wxDynamicCast( booleanobject, a2dEllipse );
00305 vpath = obj->GetAsCanvasVpaths();
00306 }
00307 else if (0 != wxDynamicCast( booleanobject, a2dEllipticArc ) && booleanobject->GetContourWidth() )
00308 {
00309 a2dEllipticArc* obj = wxDynamicCast( booleanobject, a2dEllipticArc );
00310 vpath = obj->GetAsCanvasVpaths();
00311 }
00312 else if (0 != wxDynamicCast( booleanobject, a2dArc ) && booleanobject->GetContourWidth() )
00313 {
00314 a2dArc* obj = wxDynamicCast( booleanobject, a2dArc );
00315 vpath = obj->GetAsCanvasVpaths();
00316 }
00317 else if (0 != wxDynamicCast( booleanobject, a2dEndsLine ) && booleanobject->GetContourWidth() )
00318 {
00319 a2dEndsLine* obj = wxDynamicCast( booleanobject, a2dEndsLine );
00320 vpath = obj->GetAsCanvasVpaths();
00321 }
00322 else if (0 != wxDynamicCast( booleanobject, a2dSLine ) && booleanobject->GetContourWidth() )
00323 {
00324 a2dSLine* obj = wxDynamicCast( booleanobject, a2dSLine );
00325 vpath = obj->GetAsCanvasVpaths();
00326 }
00327 else if (0 != wxDynamicCast( booleanobject, a2dPolylineL ) && booleanobject->GetContourWidth() )
00328 {
00329 a2dPolylineL* obj = wxDynamicCast( booleanobject, a2dPolylineL );
00330 vpath = obj->GetAsCanvasVpaths();
00331 }
00332 else if (0 != wxDynamicCast( booleanobject, a2dSurface ))
00333 {
00334
00335 a2dSurface* obj = wxDynamicCast( booleanobject, a2dSurface );
00336
00337 obj->SetBin( true );
00338 obj->SetBin2( true );
00339 obj->SetLayer( !m_resultOnSameLayer ? m_target : m_useFirstChildLayer );
00340 }
00341 else if (0 != wxDynamicCast( booleanobject, a2dPolygonL ))
00342 {
00343 a2dPolygonL* obj = wxDynamicCast( booleanobject, a2dPolygonL );
00344 vpath = obj->GetAsCanvasVpaths();
00345 }
00346 else if (0 != wxDynamicCast( booleanobject, a2dVectorPath ))
00347 {
00348 a2dVectorPath* obj = wxDynamicCast( booleanobject, a2dVectorPath );
00349 vpath = obj->GetAsCanvasVpaths();
00350 }
00351 else if (0 != wxDynamicCast( booleanobject, a2dText ))
00352 {
00353 a2dText* obj = wxDynamicCast( booleanobject, a2dText );
00354 vpath = obj->GetAsCanvasVpaths();
00355 }
00356
00357
00358 if ( vpath != wxNullCanvasObjectList )
00359 {
00360 bool ret = VectorPathPolygonsToEngine( vpath, A_or_B );
00361 delete vpath;
00362 return ret;
00363 }
00364 return false;
00365 }
00366
00367 bool a2dBooleanWalkerHandler::GetObjectsSurface( a2dCanvasObject* booleanobject, GroupType A_or_B )
00368 {
00369 a2dCanvasObjectList* vpath = wxNullCanvasObjectList;
00370 if (0 != wxDynamicCast( booleanobject, a2dSurface ))
00371 {
00372
00373 a2dSmrtPtr<a2dSurface> poly = wxDynamicCast( booleanobject, a2dSurface );
00374 poly = wxDynamicCast( poly->Clone( a2dObject::clone_deep ), a2dSurface );
00375
00376 if ( poly && poly->GetSegments()->HasArcs() )
00377 poly->GetSegments()->ConvertToLines();
00378
00379 double tx, ty;
00380 if ( poly && poly->GetNumberOfSegments() > 2 && m_booleng->StartPolygonAdd( A_or_B ))
00381 {
00382 for( a2dVertexList::const_iterator iter = poly->GetSegments()->begin(); iter != poly->GetSegments()->end(); ++iter )
00383 {
00384 a2dLineSegment* seg = *iter;
00385 poly->GetTransformMatrix().TransformPoint( seg->m_x, seg->m_y, tx, ty );
00386 m_booleng->AddPoint( tx, ty );
00387 }
00388 m_booleng->EndPolygonAdd();
00389 }
00390 a2dListOfa2dVertexList& holes = poly->GetHoles();
00391 for( a2dListOfa2dVertexList::iterator iterp = holes.begin(); iterp != holes.end(); iterp++ )
00392 {
00393 a2dVertexListPtr vlist = (*iterp);
00394 if ( vlist->HasArcs() )
00395 vlist->ConvertToLines();
00396 if ( vlist->size() > 2 && m_booleng->StartHolePolygonAdd( A_or_B ))
00397 {
00398 for( a2dVertexList::iterator iter = vlist->begin(); iter != vlist->end(); ++iter )
00399 {
00400 a2dLineSegment* seg = *iter;
00401 poly->GetTransformMatrix().TransformPoint( seg->m_x, seg->m_y, tx, ty );
00402 m_booleng->AddPoint( tx, ty );
00403 }
00404 }
00405 m_booleng->EndPolygonAdd();
00406 }
00407 return true;
00408 }
00409 return false;
00410 }
00411
00412 bool a2dBooleanWalkerHandler::ConvertToPolygons( a2dCanvasObject* booleanobject, GroupType A_or_B )
00413 {
00414
00415
00416 a2dCanvasObjectList* vpath = wxNullCanvasObjectList;
00417
00418 if (0 != wxDynamicCast( booleanobject, a2dRect ))
00419 {
00420 a2dRect* obj = wxDynamicCast( booleanobject, a2dRect );
00421 vpath = obj->GetAsCanvasVpaths();
00422 }
00423 else if (0 != wxDynamicCast( booleanobject, a2dRectC ))
00424 {
00425 a2dRectC* obj = wxDynamicCast( booleanobject, a2dRectC );
00426 vpath = obj->GetAsCanvasVpaths();
00427 }
00428 else if (0 != wxDynamicCast( booleanobject, a2dArrow ))
00429 {
00430 a2dArrow* obj = wxDynamicCast( booleanobject, a2dArrow );
00431 vpath = obj->GetAsCanvasVpaths();
00432 }
00433 else if (0 != wxDynamicCast( booleanobject, a2dCircle ))
00434 {
00435 a2dCircle* obj = wxDynamicCast( booleanobject, a2dCircle );
00436 vpath = obj->GetAsCanvasVpaths();
00437 }
00438 else if (0 != wxDynamicCast( booleanobject, a2dEllipse ))
00439 {
00440 a2dEllipse* obj = wxDynamicCast( booleanobject, a2dEllipse );
00441 vpath = obj->GetAsCanvasVpaths();
00442 }
00443 else if (0 != wxDynamicCast( booleanobject, a2dEllipticArc ))
00444 {
00445 a2dEllipticArc* obj = wxDynamicCast( booleanobject, a2dEllipticArc );
00446 vpath = obj->GetAsCanvasVpaths();
00447 }
00448 else if (0 != wxDynamicCast( booleanobject, a2dArc ))
00449 {
00450 a2dArc* obj = wxDynamicCast( booleanobject, a2dArc );
00451 vpath = obj->GetAsCanvasVpaths();
00452 }
00453 else if (0 != wxDynamicCast( booleanobject, a2dEndsLine ) && booleanobject->GetContourWidth() )
00454 {
00455 a2dEndsLine* obj = wxDynamicCast( booleanobject, a2dEndsLine );
00456 vpath = obj->GetAsCanvasVpaths();
00457 }
00458 else if (0 != wxDynamicCast( booleanobject, a2dSLine ) && booleanobject->GetContourWidth() )
00459 {
00460 a2dSLine* obj = wxDynamicCast( booleanobject, a2dSLine );
00461 vpath = obj->GetAsCanvasVpaths();
00462 }
00463 else if (0 != wxDynamicCast( booleanobject, a2dPolylineL ) && booleanobject->GetContourWidth() )
00464 {
00465 a2dPolylineL* obj = wxDynamicCast( booleanobject, a2dPolylineL );
00466 vpath = obj->GetAsCanvasVpaths();
00467 }
00468 else if (0 != wxDynamicCast( booleanobject, a2dSurface ))
00469 {
00470
00471 a2dSmrtPtr<a2dSurface> poly = wxDynamicCast( booleanobject, a2dSurface );
00472 poly = wxDynamicCast( poly->Clone( a2dObject::clone_deep ), a2dSurface );
00473
00474 if ( poly && poly->GetSegments()->HasArcs() )
00475 poly->GetSegments()->ConvertToLines();
00476
00477 double tx, ty;
00478 if ( poly && poly->GetNumberOfSegments() > 2 && m_booleng->StartPolygonAdd( A_or_B ))
00479 {
00480 for( a2dVertexList::const_iterator iter = poly->GetSegments()->begin(); iter != poly->GetSegments()->end(); ++iter )
00481 {
00482 a2dLineSegment* seg = *iter;
00483 poly->GetTransformMatrix().TransformPoint( seg->m_x, seg->m_y, tx, ty );
00484 m_booleng->AddPoint( tx, ty );
00485 }
00486 m_booleng->EndPolygonAdd();
00487 }
00488 a2dListOfa2dVertexList& holes = poly->GetHoles();
00489 for( a2dListOfa2dVertexList::iterator iterp = holes.begin(); iterp != holes.end(); iterp++ )
00490 {
00491 a2dVertexListPtr vlist = (*iterp);
00492 if ( vlist->HasArcs() )
00493 vlist->ConvertToLines();
00494 if ( vlist->size() > 2 && m_booleng->StartHolePolygonAdd( A_or_B ))
00495 {
00496 for( a2dVertexList::iterator iter = vlist->begin(); iter != vlist->end(); ++iter )
00497 {
00498 a2dLineSegment* seg = *iter;
00499 poly->GetTransformMatrix().TransformPoint( seg->m_x, seg->m_y, tx, ty );
00500 m_booleng->AddPoint( tx, ty );
00501 }
00502 }
00503 m_booleng->EndPolygonAdd();
00504 }
00505 return true;
00506 }
00507 else if (0 != wxDynamicCast( booleanobject, a2dPolygonL ))
00508 {
00509 a2dPolygonL* obj = wxDynamicCast( booleanobject, a2dPolygonL );
00510 vpath = obj->GetAsCanvasVpaths();
00511 }
00512 else if (0 != wxDynamicCast( booleanobject, a2dVectorPath ))
00513 {
00514 a2dVectorPath* obj = wxDynamicCast( booleanobject, a2dVectorPath );
00515 vpath = obj->GetAsCanvasVpaths();
00516 }
00517 else if (0 != wxDynamicCast( booleanobject, a2dText ))
00518 {
00519 a2dText* obj = wxDynamicCast( booleanobject, a2dText );
00520 vpath = obj->GetAsCanvasVpaths();
00521 }
00522
00523
00524
00525 if ( vpath != wxNullCanvasObjectList )
00526 {
00527 bool ret = VectorPathPolygonsToEngine( vpath, A_or_B );
00528 delete vpath;
00529 return ret;
00530 }
00531 return false;
00532 }
00533
00534 bool a2dBooleanWalkerHandler::VectorPathPolygonsToEngine( a2dCanvasObjectList* vpath, GroupType A_or_B )
00535 {
00536 if ( vpath != wxNullCanvasObjectList )
00537 {
00538 a2dCanvasObjectList::iterator iter = vpath->begin();
00539 while ( iter != vpath->end() )
00540 {
00541 a2dCanvasObjectList* polylist = NULL;
00542 a2dVectorPath* obj = (a2dVectorPath*) (*iter).Get();
00543 polylist = obj->GetAsPolygons();
00544
00545 for( a2dCanvasObjectList::iterator iterp = polylist->begin(); iterp != polylist->end(); ++iterp )
00546 {
00547 a2dSmrtPtr<a2dPolylineL> polyl = wxDynamicCast( (*iterp).Get(), a2dPolylineL );
00548 if ( polyl )
00549 {
00550 a2dSmrtPtr<a2dPolygonL> poly = polyl->GetAsPolygon();
00551 if ( poly && poly->GetSegments()->HasArcs() )
00552 poly->GetSegments()->ConvertToLines();
00553
00554 if ( poly )
00555 {
00556 if ( poly->GetNumberOfSegments() > 2 && m_booleng->StartPolygonAdd( A_or_B ))
00557 {
00558 for( a2dVertexList::const_iterator iter = poly->GetSegments()->begin(); iter != poly->GetSegments()->end(); ++iter )
00559 {
00560 a2dLineSegment* seg = *iter;
00561 m_booleng->AddPoint( seg->m_x, seg->m_y );
00562 }
00563 m_booleng->EndPolygonAdd();
00564 }
00565 }
00566 }
00567 else
00568 {
00569 a2dPolygonL* poly = wxDynamicCast( (*iterp).Get(), a2dPolygonL );
00570 if ( poly && poly->GetSegments()->HasArcs() )
00571 poly->GetSegments()->ConvertToLines();
00572
00573 if ( poly && poly->GetNumberOfSegments() > 2 && m_booleng->StartPolygonAdd( A_or_B ))
00574 {
00575 for( a2dVertexList::const_iterator iter = poly->GetSegments()->begin(); iter != poly->GetSegments()->end(); ++iter )
00576 {
00577 a2dLineSegment* seg = *iter;
00578 m_booleng->AddPoint( seg->m_x, seg->m_y );
00579 }
00580 m_booleng->EndPolygonAdd();
00581 }
00582 }
00583 }
00584 delete polylist;
00585
00586 iter = vpath->erase( iter );
00587 iter = vpath->begin();
00588 }
00589 return true;
00590 }
00591 return false;
00592 }
00593
00594 bool a2dBooleanWalkerHandler::CallEngine( a2dCanvasObject* canobjToAddChildren )
00595 {
00596 bool foundfirst = false;
00597 if ( !m_foundA.empty() || !m_foundB.empty() )
00598 {
00599
00600 forEachIn( a2dCanvasObjectList, &m_foundA )
00601 {
00602 a2dCanvasObject *obj = (*iter);
00603 bool foundObjects = false;
00604 if ( m_operation == Boolean_Polygon2Surface )
00605 foundObjects = GetObjectsForSurface( obj, GROUP_A );
00606 else if ( m_operation == Boolean_Surface2Polygon )
00607 foundObjects = GetObjectsSurface( obj, GROUP_A );
00608 else
00609 foundObjects = ConvertToPolygons( obj, GROUP_A );
00610 if ( foundObjects )
00611 {
00612 if ( !foundfirst )
00613 {
00614 m_useFirstChildStyleStroke = obj->GetStroke();
00615 m_useFirstChildStyleFill = obj->GetFill();
00616 m_useFirstChildLayer = obj->GetLayer();
00617 foundfirst = true;
00618 }
00619
00620
00621
00622 wxString classname = obj->GetClassInfo()->GetClassName();
00623 if ( classname != wxT("a2dCanvasObject") && obj->GetChildObjectsCount() )
00624 {
00625 a2dCanvasObject* holdChildRes = new a2dCanvasObject();
00626 holdChildRes->SetTransformMatrix( obj->GetTransformMatrix() );
00627 holdChildRes->CreateChildObjectList()->TakeOverFrom( obj->GetChildObjectList() );
00628 canobjToAddChildren->Prepend( holdChildRes );
00629 }
00630
00631 if ( m_releaseOrignals )
00632
00633 obj->SetRelease( true );
00634
00635 }
00636 }
00637
00638 {
00639 forEachIn( a2dCanvasObjectList, &m_foundB )
00640 {
00641 a2dCanvasObject *obj = (*iter);
00642 bool foundObjects = false;
00643 if ( m_operation != Boolean_Polygon2Surface && m_operation != Boolean_Surface2Polygon )
00644 foundObjects = ConvertToPolygons( obj, GROUP_B );
00645 if ( foundObjects )
00646 {
00647 if ( !foundfirst )
00648 {
00649 m_useFirstChildStyleStroke = obj->GetStroke();
00650 m_useFirstChildStyleFill = obj->GetFill();
00651 m_useFirstChildLayer = obj->GetLayer();
00652 foundfirst = true;
00653 }
00654
00655
00656
00657 wxString classname = obj->GetClassInfo()->GetClassName();
00658 if ( classname != wxT("a2dCanvasObject") && obj->GetChildObjectsCount() )
00659 {
00660 a2dCanvasObject* holdChildRes = new a2dCanvasObject();
00661 holdChildRes->SetTransformMatrix( obj->GetTransformMatrix() );
00662 holdChildRes->CreateChildObjectList()->TakeOverFrom( obj->GetChildObjectList() );
00663 canobjToAddChildren->Prepend( holdChildRes );
00664 }
00665
00666 if ( m_releaseOrignals )
00667
00668 obj->SetRelease( true );
00669
00670 }
00671 }
00672 }
00673
00674
00675
00676 BOOL_OP boolOp = BOOL_NON;
00677 if ( m_operation == Boolean_NON )
00678 {
00679 }
00680 else if ( m_operation == Boolean_OR )
00681 boolOp = BOOL_OR;
00682 else if ( m_operation == Boolean_AND )
00683 boolOp = BOOL_AND;
00684 else if ( m_operation == Boolean_EXOR )
00685 boolOp = BOOL_EXOR;
00686 else if ( m_operation == Boolean_A_SUB_B )
00687 boolOp = BOOL_A_SUB_B;
00688 else if ( m_operation == Boolean_B_SUB_A )
00689 boolOp = BOOL_B_SUB_A;
00690 else if ( m_operation == Boolean_CORRECTION )
00691 boolOp = BOOL_CORRECTION;
00692 else if ( m_operation == Boolean_SMOOTHEN )
00693 boolOp = BOOL_SMOOTHEN;
00694 else if ( m_operation == Boolean_MAKERING )
00695 boolOp = BOOL_MAKERING;
00696 else if ( m_operation == Boolean_Polygon2Surface )
00697 {
00698
00699 boolOp = BOOL_OR;
00700 m_booleng->SetLinkHoles( false );
00701 }
00702 else if ( m_operation == Boolean_Surface2Polygon )
00703 boolOp = BOOL_OR;
00704
00705 m_booleng->Do_Operation( boolOp );
00706
00707
00708
00709 if ( m_booleng->GetLinkHoles() )
00710 {
00711 while ( m_booleng->StartPolygonGet() )
00712 {
00713 a2dVertexList* points = new a2dVertexList;
00714
00715 while ( m_booleng->PolygonHasMorePoints() )
00716 {
00717 a2dLineSegment* seg = new a2dLineSegment( m_booleng->GetPolygonXPoint(), m_booleng->GetPolygonYPoint() );
00718 points->push_back( seg );
00719 if ( m_booleng->GetHoleConnectionSegment())
00720 {
00721 seg->SetSegType(a2dLINK_SEG);
00722 }
00723 else if (m_booleng->GetHoleSegment())
00724 {
00725 seg->SetSegType(a2dHOLE_SEG);
00726 }
00727 }
00728 m_booleng->EndPolygonGet();
00729
00730 a2dPolygonL* polygon = new a2dPolygonL( points );
00731 polygon->SetLayer( !m_resultOnSameLayer ? m_target : m_useFirstChildLayer );
00732 if ( !m_resultStroke.IsNoStroke() )
00733 polygon->SetStroke( m_resultStroke );
00734 else if ( m_useFirstChildStyle )
00735 polygon->SetStroke( m_useFirstChildStyleStroke );
00736
00737 if ( !m_resultFill.IsNoFill() )
00738 polygon->SetFill( m_resultFill );
00739 else if ( m_useFirstChildStyle )
00740 polygon->SetFill( m_useFirstChildStyleFill );
00741 polygon->SetBin( true );
00742 polygon->SetBin2( true );
00743
00744
00745 canobjToAddChildren->Prepend( polygon );
00746 }
00747 }
00748 else
00749 {
00750 bool hole = false;
00751 bool normal = false;
00752 a2dSurface* surface = NULL;
00753 a2dVertexListPtr points;
00754 a2dVertexListPtr holepoints;
00755 while ( m_booleng->StartPolygonGet() )
00756 {
00757 hole = false;
00758 normal = false;
00759
00760 while ( m_booleng->PolygonHasMorePoints() )
00761 {
00762 if ( m_booleng->GetHoleConnectionSegment() )
00763 {
00764 wxFAIL_MSG( wxT( "this type should not be here" ) );
00765 }
00766 else if (m_booleng->GetHoleSegment())
00767 {
00768 if ( !hole )
00769 {
00770 hole = true;
00771 holepoints = new a2dVertexList;
00772 }
00773 a2dLineSegment* seg = new a2dLineSegment( m_booleng->GetPolygonXPoint(), m_booleng->GetPolygonYPoint() );
00774 seg->SetSegType(a2dHOLE_SEG);
00775 holepoints->push_back( seg );
00776 }
00777 else
00778 {
00779 if ( !normal )
00780 {
00781 normal = true;
00782 points = new a2dVertexList;
00783 }
00784 a2dLineSegment* seg = new a2dLineSegment( m_booleng->GetPolygonXPoint(), m_booleng->GetPolygonYPoint() );
00785 points->push_back( seg );
00786 }
00787 }
00788 m_booleng->EndPolygonGet();
00789 if ( normal )
00790 {
00791 surface = new a2dSurface( points );
00792 surface->SetLayer( !m_resultOnSameLayer ? m_target : m_useFirstChildLayer );
00793 if ( !m_resultStroke.IsNoStroke() )
00794 surface->SetStroke( m_resultStroke );
00795 else if ( m_useFirstChildStyle )
00796 surface->SetStroke( m_useFirstChildStyleStroke );
00797
00798 if ( !m_resultFill.IsNoFill() )
00799 surface->SetFill( m_resultFill );
00800 else if ( m_useFirstChildStyle )
00801 surface->SetFill( m_useFirstChildStyleFill );
00802 surface->SetBin( true );
00803 surface->SetBin2( true );
00804
00805
00806 canobjToAddChildren->Prepend( surface );
00807 }
00808 if ( hole )
00809 {
00810 wxASSERT_MSG( surface, wxT( "need surface first to place holes within" ) );
00811 surface->AddHole( holepoints );
00812 }
00813 }
00814 }
00815
00816
00817 m_foundA.clear();
00818 m_foundB.clear();
00819 canobjToAddChildren->SetBin( true );
00820 }
00821 return true;
00822 }
00823 #endif //wxART2D_USE_KBOOL