//------------------------------------------------------------------------------ void ImagePlaneProbeWidget::ElectronDensityGroupToggledSlot( bool v ) { if( updatingGUI_ ) return; UnselectAll(); ResourceHandler< bool > rh( updatingGUI_, true, false ); eldensGroup_->setChecked( v ); stepSizeSpinBox_->setEnabled( true ); emit ElectronDensityToggled( v ); }
//------------------------------------------------------------------------------ void ImagePlaneProbeWidget::GridDataGroupToggledSlot( bool v ) { if( updatingGUI_ ) return; UnselectAll(); ResourceHandler< bool > rh( updatingGUI_, true, false ); gridDataGroup_->setChecked( v ); stepSizeSpinBox_->setEnabled( false ); emit GridDataToggled( v ); }
void CTrkObjList::Select(CTrkObj* pObj,BOOL Add,CWnd* pWnd, double Zoom,int UpdateMode) { if ( !Add || !HasMultSel() ) UnselectAll(pWnd,Zoom,UpdateMode); Select(pObj,pWnd,Zoom,UpdateMode); }
void wxGenericDirCtrl::SelectPaths(const wxArrayString& paths) { if ( HasFlag(wxDIRCTRL_MULTIPLE) ) { UnselectAll(); for ( unsigned n = 0; n < paths.size(); n++ ) { SelectPath(paths[n]); } } }
// This is used by keyboard gamelist search void CGameListCtrl::OnKeyPress(wxListEvent& event) { static int lastKey = 0, sLoop = 0; int Loop = 0; for (int i = 0; i < (int)m_ISOFiles.size(); i++) { // Easy way to get game string wxListItem bleh; bleh.SetId(i); bleh.SetColumn(COLUMN_TITLE); bleh.SetMask(wxLIST_MASK_TEXT); GetItem(bleh); wxString text = bleh.GetText(); #ifdef __WXGTK__ if (text.MakeLower()[0] == event.GetKeyCode()) #else if (text.MakeUpper()[0] == event.GetKeyCode()) #endif { if (lastKey == event.GetKeyCode() && Loop < sLoop) { Loop++; if (i+1 == (int)m_ISOFiles.size()) i = -1; continue; } else if (lastKey != event.GetKeyCode()) { sLoop = 0; } lastKey = event.GetKeyCode(); sLoop++; UnselectAll(); SetItemState(i, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); EnsureVisible(i); break; } // If we get past the last game in the list, // we'll have to go back to the first one. if (i+1 == (int)m_ISOFiles.size() && sLoop > 0 && Loop > 0) i = -1; } event.Skip(); }
void CheckedListWidget::ShowContextMenu( QPoint pos ) { if( count() > 0 ) { QMenu menu; menu.addAction( tr("Select all"), this, SLOT(SelectAll()) ); menu.addAction( tr("Unselect all"), this, SLOT(UnselectAll()) ); menu.addAction( tr("Invert selection"), this, SLOT(InvertSelection()) ); menu.addSeparator(); menu.addAction( tr("Scroll to checked"), this, SLOT(ScrollToChecked()) ); menu.exec( this->mapToGlobal(pos) ); } }
Void GUIListModel::OnClick( const Point2 & ptLocalPos, KeyCode iKey, GUIEventFlag iFlags ) { // Handle context menu if ( iKey == KEYCODE_MOUSERIGHT ) { GUIWidgetModel::OnClick( ptLocalPos, iKey, iFlags ); return; } if ( iKey != KEYCODE_MOUSELEFT ) return; // Flags Bool bCapsLock = ( (iFlags & GUIEVENT_FLAG_CAPSLOCK) != 0 ); Bool bShift = ( (iFlags & GUIEVENT_FLAG_SHIFT) != 0 ); Bool bCtrl = ( (iFlags & GUIEVENT_FLAG_CTRL) != 0 ); // Pick Node UInt iNode = m_iDisplayTop + ( ptLocalPos.Y / m_iNodeHeight ); // Deal event if ( iNode >= m_arrNodes.Count() ) UnselectAll(); else if ( bShift != bCapsLock ) { if ( m_iLastSelected == INVALID_OFFSET ) { ToggleSelect( iNode ); } else { Int iInc = ( m_iLastSelected <= iNode ) ? +1 : -1; for( Int i = (Int)m_iLastSelected; i != (Int)iNode; i += iInc ) Select( (UInt)i, true ); Select( iNode, true ); } } else if ( bCtrl ) { ToggleSelect( iNode ); } else { UnselectAll(); Select( iNode, true ); } }
/*virtual*/ wxDragResult BFBackupTree::OnDragOver(wxCoord x, wxCoord y, wxDragResult def) { wxTreeItemId itemId(HitTest(wxPoint(x, y))); // clean all selections UnselectAll(); // is an item selected? if ( itemId.IsOk() ) { bool bSelect = false; // get the task behind the item BFTask* pTask = GetTaskByItem(itemId); if (pTask) { if ( pTask->GetType() == TaskDIRCOPY ) bSelect = true; } if (!bSelect) { // get the imageId of the selected item int iImageId(GetItemImage(itemId)); // identify the item if (iImageId == BFIconTable::folder || iImageId == BFIconTable::folder_open || iImageId == BFIconTable::folder_virtual || iImageId == BFIconTable::folder_virtual_open || iImageId == BFIconTable::volume_harddisk || iImageId == BFIconTable::volume_cdrom || iImageId == BFIconTable::volume_floppy || iImageId == BFIconTable::volume_removable) { bSelect = true; } } if (bSelect) { // select it if it is not if (GetSelection() != itemId) SelectItem( itemId ); } } return def; }
BOOL CcdrawDoc::SelectOrphans() { int i; BOOL bHasOrphans; UnselectAll(); // figure out if there are any orphan segments or arcs // and select them so that the will be visible to the user // We will first figure out which nodes are elements of only // one line or arc. Then, we will select the lines and arcs // that are associated with these orphaned nodes for(i=0;i<linelist.GetSize();i++) { nodelist[linelist[i].n0].IsSelected++; nodelist[linelist[i].n1].IsSelected++; } for(i=0;i<arclist.GetSize();i++) { nodelist[arclist[i].n0].IsSelected++; nodelist[arclist[i].n1].IsSelected++; } for(i=0,bHasOrphans=FALSE;i<nodelist.GetSize();i++) { if (nodelist[i].IsSelected!=1) nodelist[i].IsSelected=FALSE; else bHasOrphans=TRUE; } if(bHasOrphans) { // We _have_ orphaned nodes. Select their associated // lines and/or arcs, and give the user a message about it. for(i=0;i<linelist.GetSize();i++) { if(nodelist[linelist[i].n0].IsSelected) linelist[i].IsSelected=TRUE; if(nodelist[linelist[i].n1].IsSelected) linelist[i].IsSelected=TRUE; } for(i=0;i<arclist.GetSize();i++) { if(nodelist[arclist[i].n0].IsSelected) arclist[i].IsSelected=TRUE; if(nodelist[arclist[i].n1].IsSelected) arclist[i].IsSelected=TRUE; } } return bHasOrphans; }
BOOL CTrkObjList::OnSelector(POINT Point,UINT Flags,CWnd* pWnd, double Zoom,int UpdateMode) { BOOL Changed = FALSE; int HitCode; CTrkObj* pHitObj = GetHitObj(Point,pWnd,HitCode,Zoom); if (pHitObj == NULL) { UnselectAll(pWnd,Zoom,UpdateMode); CRect Rect; GetSelRect(Rect,Point,Flags,pWnd,Zoom); SelectInRect(Rect,pWnd,Zoom,UpdateMode); goto End; } SetObjDefaults(pHitObj); if ( !pHitObj->IsSelected() ) { if (Flags & MK_SHIFT) Select(pHitObj,TRUE,pWnd,Zoom,UpdateMode); else Select(pHitObj,FALSE,pWnd,Zoom,UpdateMode); } else { if (Flags & MK_SHIFT) { Unselect(pHitObj,pWnd,Zoom,UpdateMode); goto End; } if ( (HitCode != CTrk::HC_Middle) && (GetCountSel() != 1) ) Select(pHitObj,FALSE,pWnd,Zoom,UpdateMode); } if (GetCountSel() == 1) Changed = pHitObj->OnLButtonDown(Point,Flags,pWnd,Zoom,UpdateMode); else Changed = TrackSelObjs(Point,Flags,pWnd,Zoom,UpdateMode); End: return(Changed); }
void CMultiSelTreeCtrl::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; if (pNMTreeView->action == TVC_BYKEYBOARD) { HTREEITEM currentItem = CTreeCtrl::GetSelectedItem(); if ((currentItem != NULL) && !IsSelected(currentItem)) { UnselectAll(); SetSelectState(currentItem, TRUE); ASSERT(GetSelectedCount()); } } *pResult = 0; }
boolean StringBrowser::LeftButtonDown (Event& e) { boolean status = false; if (DoubleClicked(e)) { subject->SetValue(done[0]); status = true; } else if (uniqueSel) { if (Selections() == 0) { Select(Locate(e.x, e.y)); } else { Unselect(Selection()); if (!e.shift) { Select(Locate(e.x, e.y)); } } } else { lastdot = lastmark = Locate(e.x, e.y); if (Selected(lastdot) && e.shift) { Unselect(lastdot); do { ScrollToView(e.x, e.y); UpdateSelection(lastdot, Locate(e.x, e.y), Plain); Poll(e); } while (e.leftmouse); } else { if (!e.shift) { UnselectAll(); } Select(lastdot); do { ScrollToView(e.x, e.y); UpdateSelection(lastdot, Locate(e.x, e.y), highlight); Poll(e); } while (e.leftmouse); } } Note(e); if (singleClick) { subject->SetValue(done[0]); status = true; } return status; }
void wxTreeCtrlEx::SafeSelectItem(const wxTreeItemId& item) { if( !item ) { m_setSelection = true; UnselectAll(); m_setSelection = false; } else { const wxTreeItemId old_selection = GetSelection(); m_setSelection = true; SelectItem(item); m_setSelection = false; if (item != old_selection) EnsureVisible(item); } }
void DownloadDataViewCtrl::Clear() { slLogDebugFunc(""); UnselectAll(); std::vector<const PrDownloader::DownloadProgress*> toBeRemoved; for (const PrDownloader::DownloadProgress* p : m_DataModel->GetItemsContainer()) { toBeRemoved.push_back(p); } BaseDataViewCtrl::Clear(); for (const PrDownloader::DownloadProgress* p : toBeRemoved) { delete p; } }
// This is a little tricky. We need to delete the current selection, // while highlighting the newly dropped items, without letting them // screw each other's indices up. // We know that the newly dropped items are in a contiguous block, // which helps. void OleListCtrl::DeleteOldAndHighlightNew() { // First, get a reverse-order list of selected items, // which will be deleted. CArray <int, int> anSelectedItems; anSelectedItems.SetSize( 0, 50 ); int nA = -1; while ( ( nA = GetNextItem( nA, LVNI_SELECTED ) ) != -1 ) { anSelectedItems.Add( nA ); } UnselectAll(); // Now select the dropped items. std::vector<int>::iterator it; for ( it = m_vnNewlyDroppedItems.begin(); it != m_vnNewlyDroppedItems.end(); ++it ) { SetItemState( (*it), LVIS_SELECTED, LVIS_SELECTED ); } // Now step through the deleted items, deleting. // We track the first newly dropped item as we go. int nFirst = m_vnNewlyDroppedItems[0]; for ( nA = anSelectedItems.GetUpperBound(); nA >= 0; nA-- ) { // There should be no overlap here! ASSERT( anSelectedItems[nA] != m_vnNewlyDroppedItems[0] ); DeleteItem( anSelectedItems[nA], false ); // Track the first slot as it slides up. if ( anSelectedItems[nA] < nFirst ) nFirst--; } if ( nFirst >= 0 ) { SetItemState( nFirst, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED ); } m_vnNewlyDroppedItems.clear(); }
void CTrkObjList::CopyFromCB(CWnd* pWnd,double Zoom,int UpdateMode) { UnselectAll(pWnd,Zoom,UpdateMode); CSize Off; GetCBOff(Off); POSITION Pos = GetHeadPosCB(); while (Pos != NULL) { CTrkObj* pObj = GetNextCB(Pos); CTrkObj* pClone = pObj->SetupClone(); pClone->SetNormal(); pClone->OffsetRect(Off); Add(pClone); Select(pClone,pWnd,Zoom,UpdateMode); } }
void SelectionManager::RemoveSelection() { wxVector<unsigned int> selectedPolygons; wxVector<unsigned int> selectedSceneries; for (const auto &selectedPolygon : *m_polygonSelection) { selectedPolygons.push_back(selectedPolygon.id); } for (const auto &selectedScenery : *m_scenerySelection) { selectedSceneries.push_back(selectedScenery); m_sceneryFrame.RemoveScenery(selectedScenery); } m_canvas.RemovePolygons(selectedPolygons); m_canvas.RemoveSceneries(selectedSceneries); UnselectAll(); m_canvas.Draw(); }
/****************************************************************************** * UseColorSet */ void CCEtoODBDoc::UseColorSet(int set, BOOL newValueForBottom) { UnselectAll(FALSE); // loop layers for (int i=0; i < getMaxLayerIndex(); i++) { LayerStruct *layer = getLayerArray()[i]; if (layer == NULL) continue; // set color and show layer->setColor( LayerTypeArray[set][layer->getLayerType()].color); layer->setVisible( LayerTypeArray[set][layer->getLayerType()].show); } SetColorsetButtons(this); FitPageKeepingZoom(newValueForBottom); }
void CMultiSelTreeCtrl::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; HTREEITEM parent=m_LastParent; while( 1 ) { // If expanding/collapsing node is a parent of selected items, // unselect all. // No need to check pNMTreeView->action, since no items will // be selected under parent if expanding, and all must be // cleared while deleting // if(pNMTreeView->itemNew.hItem == parent) { UnselectAll(); break; } if(parent == NULL || parent == TVI_ROOT) break; parent=GetParentItem(parent); } // whenever we expand a folder, we have to call both p4 dirs // and p4 fstat for that subdirectory. ExpandTree is a // virtual function in depotview that does this. // if ( pNMTreeView->action == TVE_EXPAND ) ExpandTree( pNMTreeView->itemNew.hItem ); else if ( pNMTreeView->action == TVE_COLLAPSE ) CollapseTree( pNMTreeView->itemNew.hItem ); // wait at least 20 secs before autopolling for updates MainFrame()->WaitAWhileToPoll(); *pResult = 0; }
void DownloadDataViewCtrl::ClearFinished() { slLogDebugFunc(""); UnselectAll(); std::vector<const PrDownloader::DownloadProgress*> toBeRemoved; for (const PrDownloader::DownloadProgress* p : m_DataModel->GetItemsContainer()) { if (p->IsFinished()) { toBeRemoved.push_back(p); } } for (const PrDownloader::DownloadProgress* pp : toBeRemoved) { RemoveItem(*pp); auto item = itemsIndex.find(pp->name); assert(item != itemsIndex.end()); itemsIndex.erase(item); delete pp; } }
int main(int argc, char **argv) { Widget ScrollWin, Container, *IconGad; int i; Cardinal n; Arg args[MAX_ARGS]; Dimension x_size, y_size; CommonTestInit(argc, argv); n = 0; XtSetArg( args[n], XmNx, 20 ); n++; ScrollWin = XmCreateScrolledWindow(Shell1, "ScrollWin7", args, n); XtManageChild(ScrollWin); XtSetArg(args[n], XmNselectionPolicy, XmMULTIPLE_SELECT); n++; XtSetArg(args[n], XmNspatialStyle, XmNONE ); n++; Container = XmCreateContainer(ScrollWin, "Container7", args, n); XtManageChild(Container); /* Add a bunch of Icon Gadgets */ IconGad = (Widget*) XtMalloc(NUM_ELEMS * sizeof(Widget)); /* Put some pixmaps in the Container */ for (i = 0; i < NUM_PIXMAP; i++) { char IconName[20] ; XmString icon_name; Pixmap pixmap; n = 0 ; sprintf(IconName, "IconGad%d", i); icon_name = XmStringGenerate(IconName, NULL, XmCHARSET_TEXT, NULL); /* make icons from pixmap files */ pixmap = XmGetPixmap(screen, BitmapPaths[i], BlackPixelOfScreen(screen), WhitePixelOfScreen(screen)); if (!pixmap) { printf("Can't make pixmap for file %s!\n", BitmapPaths[i]); exit(1); } XtSetArg(args[n], XmNx, PIXEL_X(i) ); n++; XtSetArg(args[n], XmNy, PIXEL_Y(i) ); n++; XtSetArg(args[n], XmNlabelString, icon_name); n++; XtSetArg(args[n], XmNlargeIconPixmap, pixmap); n++; IconGad[i] = XmCreateIconGadget(Container, IconName, args, n); XtManageChild(IconGad[i]); XmStringFree(icon_name); } /* Put some labels in the Container */ for (i = NUM_PIXMAP; i < NUM_ELEMS; i++) { char LabelName[20] ; XmString label_name; n = 0 ; sprintf(LabelName, "LabelName%d", i); label_name = XmStringGenerate(LabelName, NULL, XmCHARSET_TEXT, NULL); XtSetArg(args[n], XmNx, PIXEL_X(i) ); n++; XtSetArg(args[n], XmNy, PIXEL_Y(i) ); n++; XtSetArg(args[n], XmNlabelString, label_name); n++; XtSetArg(args[n], XmNlabelType, XmSTRING); n++; IconGad[i] = XmCreateIconGadget(Container, LabelName, args, n); XtManageChild(IconGad[i]); XmStringFree(label_name); } XtRealizeWidget(Shell1); /* Find out the default size for X and Y */ n = 0; XtSetArg( args[n], XmNwidth, &x_size ); n++; XtSetArg( args[n], XmNheight, &y_size ); n++; XtGetValues( ScrollWin, args, n ); /************************* * Assertions begin */ /* Assertions 1 and 2 */ n = 0; XtSetArg( args[n], XmNwidth, 175 ); n++; XtSetValues( ScrollWin, args, n ); CommonPause(); RestoreXY( ScrollWin, x_size, y_size ); UnselectAll( Container ); /* Assertions 3 and 4 */ n = 0; XtSetArg( args[n], XmNwidth, 400 ); n++; XtSetValues( ScrollWin, args, n ); CommonPause(); RestoreXY( ScrollWin, x_size, y_size ); UnselectAll( Container ); /* Assertions 5 and 6 */ n = 0; XtSetArg( args[n], XmNheight, 400 ); n++; XtSetValues( ScrollWin, args, n ); CommonPause(); RestoreXY( ScrollWin, x_size, y_size ); UnselectAll( Container ); /* Assertions 7 and 8 */ CommonPause(); XtAppMainLoop(app_context); for ( i=0; i < NUM_ELEMS; i++ ) XtDestroyWidget( IconGad[i] ); XtDestroyWidget( Container ); XtDestroyWidget( ScrollWin ); XtFree( (char *)IconGad ); }
void CcdrawDoc::FancyEnforcePSLG(double tol) { /* need to enforce: 1) no duplicate point; 2) no intersections between line segments, lines and arcs, or arcs; 3) no duplicate block labels; 4) no overlapping lines or arcs. can do this by cleaning out the various lists, and rebuilding them using the ``add'' functions that ensure that things come out right. */ CArray< CNode, CNode&> newnodelist; CArray< CSegment, CSegment&> newlinelist; CArray< CArcSegment, CArcSegment&> newarclist; CArray< CBlockLabel, CBlockLabel&> newblocklist; int i,k; CComplex p0,p1; double d; bLinehook=ImportDXF; // kludge to stop the program from giving a crash if // the user tries to exit during a dxf import. CcdrawView *pView; POSITION pos; pos=GetFirstViewPosition(); pView=(CcdrawView *)GetNextView(pos); FirstDraw=TRUE; // pView->lua_zoomnatural(); dxf_line_hook(); pView->EditAction=4; newnodelist.RemoveAll(); newlinelist.RemoveAll(); newarclist.RemoveAll(); newblocklist.RemoveAll(); for(i=0;i<nodelist.GetSize();i++) newnodelist.Add(nodelist[i]); for(i=0;i<linelist.GetSize();i++) newlinelist.Add(linelist[i]); for(i=0;i<arclist.GetSize();i++) newarclist.Add(arclist[i]); for(i=0;i<blocklist.GetSize();i++) newblocklist.Add(blocklist[i]); nodelist.RemoveAll(); linelist.RemoveAll(); arclist.RemoveAll(); blocklist.RemoveAll(); pView->InvalidateRect(NULL); dxf_line_hook(); // find out what tolerance is so that there are not nodes right on // top of each other; if(tol==0){ if (newnodelist.GetSize()<2) d=1.e-08; else{ p0=newnodelist[0].CC(); p1=p0; for(i=1;i<newnodelist.GetSize();i++) { if(newnodelist[i].x<p0.re) p0.re=newnodelist[i].x; if(newnodelist[i].x>p1.re) p1.re=newnodelist[i].x; if(newnodelist[i].y<p0.im) p0.im=newnodelist[i].y; if(newnodelist[i].y>p1.im) p1.im=newnodelist[i].y; } d=abs(p1-p0)*CLOSE_ENOUGH; } } else d=tol; // put in all of the lines; for(i=0;i<newlinelist.GetSize();i++) { // Add in endpoints of the proposed line; AddNode(newnodelist[newlinelist[i].n0],d); AddNode(newnodelist[newlinelist[i].n1],d); // Add in the proposed line itself; p0=newnodelist[newlinelist[i].n0].CC(); p1=newnodelist[newlinelist[i].n1].CC(); if(AddSegment(p0,p1,newlinelist[i],d)==TRUE) { pView->DrawPSLG(); if(dxf_line_hook()){ bLinehook=FALSE; return; } } } // put in all of the arcs; for(i=0;i<newarclist.GetSize();i++) { // Add in endpoints of the proposed line; AddNode(newnodelist[newarclist[i].n0],d); AddNode(newnodelist[newarclist[i].n1],d); // Add in the proposed arc inself; p0=newnodelist[newarclist[i].n0].CC(); p1=newnodelist[newarclist[i].n1].CC(); if(AddArcSegment(p0,p1,newarclist[i],d)==TRUE) { pView->DrawPSLG(); if(dxf_line_hook()){ bLinehook=FALSE; return; } } } UnselectAll(); // do one last check to eliminate shallow arcs that // link up the same two points as a line segment; for(i=0;i<arclist.GetSize();i++) { if (arclist[i].ArcLength<=22.5) { for(k=0;k<linelist.GetSize();k++) { if ((arclist[i].n0==linelist[k].n0) && (arclist[i].n1==linelist[k].n1)) arclist[i].IsSelected=TRUE; if ((arclist[i].n1==linelist[k].n0) && (arclist[i].n0==linelist[k].n1)) arclist[i].IsSelected=TRUE; if (arclist[i].IsSelected) k=(int) linelist.GetSize(); } } } DeleteSelectedArcSegments(); // put in all of the block labels; for(i=0;i<newblocklist.GetSize();i++) AddBlockLabel(newblocklist[i],d); if(SelectOrphans()) { CString msg; msg ="There are lines or arcs with \"Orphaned\" end points.\n"; msg+="The lines or arcs could be glitches in the DXF import\n"; msg+="import, so they should be examined manually.\n"; msg+="These points and lines will be shown as selected.\n"; msg+="To redisplay the orphaned points and lines, select\n"; msg+="View|Show Orphans off of the main menu."; MsgBox(msg); } bLinehook=FALSE; return; }
BOOL CcdrawDoc::AddArcSegment(CComplex p0, CComplex p1, CArcSegment &asegm, double tol) { int i,j,k; CSegment segm; CArcSegment newarc; CComplex c,p[2]; CArray< CComplex, CComplex&> newnodes; double R,d,dmin,t; asegm.n0=ClosestNode(p0.re,p0.im); asegm.n1=ClosestNode(p1.re,p1.im); newnodes.RemoveAll(); // don't add if line is degenerate if (asegm.n0==asegm.n1) return FALSE; // don't add if the arc is already in the list; for(i=0;i<arclist.GetSize();i++){ if ((arclist[i].n0==asegm.n0) && (arclist[i].n1==asegm.n1) && (fabs(arclist[i].ArcLength-asegm.ArcLength)<1.e-02)) return FALSE; // arcs are ``the same'' if start and end points are the same, and if // the arc lengths are relatively close (but a lot farther than // machine precision... } // add proposed arc to the linelist asegm.IsSelected=FALSE; // check to see if there are intersections for(i=0;i<linelist.GetSize();i++) { j=GetLineArcIntersection(linelist[i],asegm,p); if(j>0) for(k=0;k<j;k++) newnodes.Add(p[k]); } for(i=0;i<arclist.GetSize();i++) { j=GetArcArcIntersection(asegm,arclist[i],p); if(j>0) for(k=0;k<j;k++) newnodes.Add(p[k]); } // add nodes at intersections if (tol==0) { if (nodelist.GetSize()<2) t=1.e-08; else{ CComplex p0,p1; p0=nodelist[0].CC(); p1=p0; for(i=1;i<nodelist.GetSize();i++) { if(nodelist[i].x<p0.re) p0.re=nodelist[i].x; if(nodelist[i].x>p1.re) p1.re=nodelist[i].x; if(nodelist[i].y<p0.im) p0.im=nodelist[i].y; if(nodelist[i].y>p1.im) p1.im=nodelist[i].y; } t=abs(p1-p0)*CLOSE_ENOUGH; } } else t=tol; for(i=0;i<newnodes.GetSize();i++) AddNode(newnodes[i].re,newnodes[i].im,t); // add proposed arc segment; arclist.Add(asegm); // check to see if proposed arc passes through other points; // if so, delete arc and create arcs that link intermediate points; // does this by recursive use of AddArcSegment; UnselectAll(); GetCircle(asegm,c,R); if (tol==0) dmin=fabs(R*PI*asegm.ArcLength/180.)*1.e-05; else dmin=tol; k=(int) arclist.GetSize()-1; for(i=0;i<nodelist.GetSize();i++) { if( (i!=asegm.n0) && (i!=asegm.n1) ) { d=ShortestDistanceFromArc(CComplex(nodelist[i].x,nodelist[i].y), arclist[k]); if (d<dmin){ CComplex a0,a1,a2; a0.Set(nodelist[asegm.n0].x,nodelist[asegm.n0].y); a1.Set(nodelist[asegm.n1].x,nodelist[asegm.n1].y); a2.Set(nodelist[i].x,nodelist[i].y); arclist[k].ToggleSelect(); DeleteSelectedArcSegments(); newarc=asegm; newarc.n1=i; newarc.ArcLength=arg((a2-c)/(a0-c))*180./PI; AddArcSegment(newarc,dmin); newarc=asegm; newarc.n0=i; newarc.ArcLength=arg((a1-c)/(a2-c))*180./PI; AddArcSegment(newarc,dmin); i=(int) nodelist.GetSize(); } } } return TRUE; }
BOOL CcdrawDoc::AddSegment(CComplex p0, CComplex p1, CSegment &segm, double tol) { int i,j,k,n0,n1; double xi,yi,t; CComplex p[2]; CArray< CComplex, CComplex&> newnodes; newnodes.RemoveAll(); n0=ClosestNode(p0.re,p0.im); n1=ClosestNode(p1.re,p1.im); // don't add if line is degenerate if (n0==n1) return FALSE; // don't add if the line is already in the list; for(i=0;i<linelist.GetSize();i++){ if ((linelist[i].n0==n0) && (linelist[i].n1==n1)) return FALSE; if ((linelist[i].n0==n1) && (linelist[i].n1==n0)) return FALSE; } segm.IsSelected=FALSE; segm.n0=n0; segm.n1=n1; // check to see if there are intersections with segments for(i=0;i<linelist.GetSize();i++) if(GetIntersection(n0,n1,i,&xi,&yi)==TRUE) newnodes.Add(CComplex(xi,yi)); // check to see if there are intersections with arcs for(i=0;i<arclist.GetSize();i++){ j=GetLineArcIntersection(segm,arclist[i],p); if (j>0) for(k=0;k<j;k++) newnodes.Add(p[k]); } // add nodes at intersections if(tol==0) { if (nodelist.GetSize()<2) t=1.e-08; else{ CComplex p0,p1; p0=nodelist[0].CC(); p1=p0; for(i=1;i<nodelist.GetSize();i++) { if(nodelist[i].x<p0.re) p0.re=nodelist[i].x; if(nodelist[i].x>p1.re) p1.re=nodelist[i].x; if(nodelist[i].y<p0.im) p0.im=nodelist[i].y; if(nodelist[i].y>p1.im) p1.im=nodelist[i].y; } t=abs(p1-p0)*CLOSE_ENOUGH; } } else t=tol; for(i=0;i<newnodes.GetSize();i++) AddNode(newnodes[i].re,newnodes[i].im,t); // Add proposed line segment linelist.Add(segm); // check to see if proposed line passes through other points; // if so, delete line and create lines that link intermediate points; // does this by recursive use of AddSegment; double d,dmin; UnselectAll(); if (tol==0) dmin=abs(nodelist[n1].CC()-nodelist[n0].CC())*1.e-05; else dmin=tol; k=(int) linelist.GetSize()-1; for(i=0;i<nodelist.GetSize();i++) { if( (i!=n0) && (i!=n1) ) { d=ShortestDistance(nodelist[i].x,nodelist[i].y,k); // catch a special case... if (abs(nodelist[i].CC()-nodelist[n0].CC())<dmin) d=2.*dmin; if (abs(nodelist[i].CC()-nodelist[n1].CC())<dmin) d=2.*dmin; if (d<dmin){ linelist[k].ToggleSelect(); DeleteSelectedSegments(); AddSegment(n0,i,&segm,dmin); AddSegment(i,n1,&segm,dmin); i=(int) nodelist.GetSize(); } } } return TRUE; }
void CcdrawDoc::EnforcePSLG(double tol) { /* need to enforce: 1) no duplicate point; 2) no intersections between line segments, lines and arcs, or arcs; 3) no duplicate block labels; 4) no overlapping lines or arcs. can do this by cleaning out the various lists, and rebuilding them using the ``add'' functions that ensure that things come out right. */ CArray< CNode, CNode&> newnodelist; CArray< CSegment, CSegment&> newlinelist; CArray< CArcSegment, CArcSegment&> newarclist; CArray< CBlockLabel, CBlockLabel&> newblocklist; int i; CComplex p0,p1; double d; newnodelist.RemoveAll(); newlinelist.RemoveAll(); newarclist.RemoveAll(); newblocklist.RemoveAll(); for(i=0;i<nodelist.GetSize();i++) newnodelist.Add(nodelist[i]); for(i=0;i<linelist.GetSize();i++) newlinelist.Add(linelist[i]); for(i=0;i<arclist.GetSize();i++) newarclist.Add(arclist[i]); for(i=0;i<blocklist.GetSize();i++) newblocklist.Add(blocklist[i]); nodelist.RemoveAll(); linelist.RemoveAll(); arclist.RemoveAll(); blocklist.RemoveAll(); // find out what tolerance is so that there are not nodes right on // top of each other; if(tol==0){ if (newnodelist.GetSize()<2) d=1.e-08; else{ p0=newnodelist[0].CC(); p1=p0; for(i=1;i<newnodelist.GetSize();i++) { if(newnodelist[i].x<p0.re) p0.re=newnodelist[i].x; if(newnodelist[i].x>p1.re) p1.re=newnodelist[i].x; if(newnodelist[i].y<p0.im) p0.im=newnodelist[i].y; if(newnodelist[i].y>p1.im) p1.im=newnodelist[i].y; } d=abs(p1-p0)*CLOSE_ENOUGH; } } else d=tol; // put in all of the nodes; for(i=0;i<newnodelist.GetSize();i++) AddNode(newnodelist[i],d); // put in all of the lines; for(i=0;i<newlinelist.GetSize();i++) { p0.Set(newnodelist[newlinelist[i].n0].x,newnodelist[newlinelist[i].n0].y); p1.Set(newnodelist[newlinelist[i].n1].x,newnodelist[newlinelist[i].n1].y); AddSegment(p0,p1,newlinelist[i]); } // put in all of the arcs; for(i=0;i<newarclist.GetSize();i++) { p0.Set(newnodelist[newarclist[i].n0].x,newnodelist[newarclist[i].n0].y); p1.Set(newnodelist[newarclist[i].n1].x,newnodelist[newarclist[i].n1].y); AddArcSegment(p0,p1,newarclist[i]); } // put in all of the block labels; for(i=0;i<newblocklist.GetSize();i++) AddBlockLabel(newblocklist[i],d); UnselectAll(); return; }
void CGameListCtrl::OnRightClick(wxMouseEvent& event) { // Focus the clicked item. int flags; long item = HitTest(event.GetPosition(), flags); if (item != wxNOT_FOUND) { if (GetItemState(item, wxLIST_STATE_SELECTED) != wxLIST_STATE_SELECTED) { UnselectAll(); SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); } SetItemState(item, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED); } if (GetSelectedItemCount() == 1) { const GameListItem *selected_iso = GetSelectedISO(); if (selected_iso) { wxMenu* popupMenu = new wxMenu; popupMenu->Append(IDM_PROPERTIES, _("&Properties")); popupMenu->Append(IDM_GAMEWIKI, _("&Wiki")); popupMenu->AppendSeparator(); if (selected_iso->GetPlatform() != GameListItem::GAMECUBE_DISC) { popupMenu->Append(IDM_OPENSAVEFOLDER, _("Open Wii &save folder")); popupMenu->Append(IDM_EXPORTSAVE, _("Export Wii save (Experimental)")); } popupMenu->Append(IDM_OPENCONTAININGFOLDER, _("Open &containing folder")); popupMenu->AppendCheckItem(IDM_SETDEFAULTGCM, _("Set as &default ISO")); // First we have to decide a starting value when we append it if(selected_iso->GetFileName() == SConfig::GetInstance(). m_LocalCoreStartupParameter.m_strDefaultGCM) popupMenu->FindItem(IDM_SETDEFAULTGCM)->Check(); popupMenu->AppendSeparator(); popupMenu->Append(IDM_DELETEGCM, _("&Delete ISO...")); if (selected_iso->GetPlatform() != GameListItem::WII_WAD) { if (selected_iso->IsCompressed()) popupMenu->Append(IDM_COMPRESSGCM, _("Decompress ISO...")); else if (selected_iso->GetFileName().substr(selected_iso->GetFileName().find_last_of(".")) != ".ciso" && selected_iso->GetFileName().substr(selected_iso->GetFileName().find_last_of(".")) != ".wbfs") popupMenu->Append(IDM_COMPRESSGCM, _("Compress ISO...")); } else popupMenu->Append(IDM_LIST_INSTALLWAD, _("Install to Wii Menu")); PopupMenu(popupMenu); } } else if (GetSelectedItemCount() > 1) { wxMenu* popupMenu = new wxMenu; popupMenu->Append(IDM_DELETEGCM, _("&Delete selected ISOs...")); popupMenu->AppendSeparator(); popupMenu->Append(IDM_MULTICOMPRESSGCM, _("Compress selected ISOs...")); popupMenu->Append(IDM_MULTIDECOMPRESSGCM, _("Decompress selected ISOs...")); PopupMenu(popupMenu); } }
void CGameListCtrl::OnRightClick(wxMouseEvent& event) { // Focus the clicked item. int flags; long item = HitTest(event.GetPosition(), flags); if (item != wxNOT_FOUND) { if (GetItemState(item, wxLIST_STATE_SELECTED) != wxLIST_STATE_SELECTED) { UnselectAll(); SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); } SetItemState(item, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED); } if (GetSelectedItemCount() == 1) { const GameListItem* selected_iso = GetSelectedISO(); if (selected_iso) { wxMenu popupMenu; DiscIO::IVolume::EPlatform platform = selected_iso->GetPlatform(); if (platform != DiscIO::IVolume::ELF_DOL) { popupMenu.Append(IDM_PROPERTIES, _("&Properties")); popupMenu.Append(IDM_GAME_WIKI, _("&Wiki")); popupMenu.AppendSeparator(); } if (platform == DiscIO::IVolume::WII_DISC || platform == DiscIO::IVolume::WII_WAD) { popupMenu.Append(IDM_OPEN_SAVE_FOLDER, _("Open Wii &save folder")); popupMenu.Append(IDM_EXPORT_SAVE, _("Export Wii save (Experimental)")); } popupMenu.Append(IDM_OPEN_CONTAINING_FOLDER, _("Open &containing folder")); if (platform != DiscIO::IVolume::ELF_DOL) popupMenu.AppendCheckItem(IDM_SET_DEFAULT_ISO, _("Set as &default ISO")); // First we have to decide a starting value when we append it if (platform == SConfig::GetInstance().m_strDefaultISO) popupMenu.FindItem(IDM_SET_DEFAULT_ISO)->Check(); popupMenu.AppendSeparator(); popupMenu.Append(IDM_DELETE_ISO, _("&Delete File...")); if (platform == DiscIO::IVolume::GAMECUBE_DISC || platform == DiscIO::IVolume::WII_DISC) { if (selected_iso->GetBlobType() == DiscIO::BlobType::GCZ) popupMenu.Append(IDM_COMPRESS_ISO, _("Decompress ISO...")); else if (selected_iso->GetBlobType() == DiscIO::BlobType::PLAIN) popupMenu.Append(IDM_COMPRESS_ISO, _("Compress ISO...")); wxMenuItem* changeDiscItem = popupMenu.Append(IDM_LIST_CHANGE_DISC, _("Change &Disc")); changeDiscItem->Enable(Core::IsRunning()); } if (platform == DiscIO::IVolume::WII_WAD) popupMenu.Append(IDM_LIST_INSTALL_WAD, _("Install to Wii Menu")); PopupMenu(&popupMenu); } } else if (GetSelectedItemCount() > 1) { wxMenu popupMenu; popupMenu.Append(IDM_DELETE_ISO, _("&Delete selected ISOs...")); popupMenu.AppendSeparator(); popupMenu.Append(IDM_MULTI_COMPRESS_ISO, _("Compress selected ISOs...")); popupMenu.Append(IDM_MULTI_DECOMPRESS_ISO, _("Decompress selected ISOs...")); PopupMenu(&popupMenu); } }
void CMultiSelTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { MainFrame()->SetGotUserInput( ); if (nChar == VK_RETURN || nChar == VK_APPS) return; if (nChar == VK_TAB && m_CtrlDown) // Ctrl+TAB switches to opposite pane { BOOL bShift = m_ShiftDown; m_CtrlDown= m_ShiftDown= FALSE; // clear these because we may miss the Up m_PendingKeyedDeselect = FALSE; // in the other pane MainFrame()->SwitchPanes(DYNAMIC_DOWNCAST(CView, GetParent()), bShift); return; } if( nChar == VK_CONTROL ) m_CtrlDown= TRUE; else if( nChar == VK_SHIFT ) { m_ShiftDown= TRUE; if( m_SelectionSet.GetSize() > 0 ) { m_AnchorItem= m_LastSelect; m_PendingKeyedDeselect= TRUE; } } if( m_ShiftDown && m_SelectionSet.GetSize() > 0 ) { // Try to range select, and scroll the tree only as necessary // to ensure that the last item selected is visible switch( nChar ) { case VK_DOWN: ExpandSelection( -1 ); break; case VK_UP: ExpandSelection( 1 ); break; case VK_END: ExpandSelection( - (int) GetCount() ); break; case VK_HOME: ExpandSelection( (int) GetCount() ); break; case VK_PGDN: ExpandSelection( - (int) GetVisibleCount() +1 ); break; case VK_PGUP: ExpandSelection( (int) GetVisibleCount() -1 ); break; default: break; } } else if( m_CtrlDown || m_SelectionSet.GetSize() == 0) { // Scroll the tree, but do not fool with the selection set // or move a focus rect around switch( nChar ) { case VK_DOWN: ScrollTree( -1 ); break; case VK_UP: ScrollTree( 1 ); break; case VK_END: ScrollTree( - (int) GetCount() ); break; case VK_HOME: ScrollTree( GetCount() ); break; case VK_PGDN: ScrollTree( - (int) GetVisibleCount() +1 ); break; case VK_PGUP: ScrollTree( GetVisibleCount() -1 ); break; default: break; } } else { // Deselect all, reposition at m_LastSelect + offset, reselect the new // item, and ensure visible HTREEITEM item= m_LastSelect; ASSERT( item != NULL ); HTREEITEM newItem; UnselectAll(); #if 0 HTREEITEM lastItem; int i, count; #endif switch( nChar ) { case VK_END: ScrollTree( - (int) GetCount() ); newItem= GetNextItem(TVI_ROOT, TVGN_LASTVISIBLE); break; case VK_HOME: ScrollTree( GetCount() ); newItem= GetNextItem(TVI_ROOT, TVGN_ROOT ); break; #if 0 // This code was removed to fix job004105 - removing it causes the DepotView to behave like a normal TreeView when page-up and page-down are pressed case VK_PGDN: count=GetVisibleCount() - 1; newItem= GetFirstVisible(); // First, find the last visible item on the screen for( i=0; i< count; i++) { lastItem= newItem; newItem= GetNextVisible(newItem ); if( newItem == NULL ) { newItem= lastItem; break; } } // If current item is the last one on the screen, move down // a page beyond the end of current page if( newItem == item ) { for( i=0; i< count; i++) { lastItem= newItem; newItem= GetNextVisible( newItem ); if( newItem==NULL) { newItem= lastItem; break; } } } break; case VK_PGUP: if( item == GetFirstVisible() ) { count=GetVisibleCount() - 1; newItem= GetFirstVisible(); for( i=0; i< count; i++) { lastItem= newItem; newItem= GetPrevVisible( newItem ); if( newItem==NULL) { newItem= lastItem; break; } } } else newItem= GetFirstVisible(); break; #endif default: newItem= NULL; break; } // If something went wrong, like hitting top or bottom, // use our saved copy of m_LastSelect if( newItem == NULL ) newItem= item; if(newItem != NULL ) { SetSelectState( newItem, TRUE ); EnsureVisible( newItem ); // Redraw w/out erase to avoid slow video update RedrawWindow( NULL, NULL, RDW_UPDATENOW ); } } if (!m_CtrlDown && !m_ShiftDown) CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags); }
boolean StringBrowser::HandleChar (char c) { int index = Selection(); int i; switch (c) { case SBFirstString: ScrollTo(0); break; case SBLastString: ScrollTo(strcount-1); break; case SBScrollDown: ScrollBy(1); break; case SBScrollUp: ScrollBy(-1); break; case SBSelectAll: if (!uniqueSel) { SelectAll(); } break; case SBUnselectAll: case SBUnselectAllAlt: UnselectAll(); break; case SBSelectPreviousString: UnselectAll(); --index; index = Math::max(0, Math::min(index, strcount-1)); Select(index); ScrollTo(index); break; case SBSelectNextString: UnselectAll(); ++index; index = Math::max(0, Math::min(index, strcount-1)); Select(index); ScrollTo(index); break; case SBSelectTopString: UnselectAll(); index = Math::max(0, Locate(0, ymax)); Select(index); break; case SBSelectBottomString: UnselectAll(); index = Math::min(Locate(0, 0), strcount-1); Select(index); break; case SBPageDown: ScrollBy((ymax+1) / lineheight); break; case SBPageUp: ScrollBy(-(ymax+1) / lineheight); break; case SBHalfPageDown: ScrollBy((ymax+1) / lineheight / 2); break; case SBHalfPageUp: ScrollBy(-(ymax+1) / lineheight / 2); break; default: for (i = 0; done[i] != '\0'; i++) { if (c == done[i]) { subject->SetValue(c); return true; } } break; } return false; }
// Call triangle to order segments on the boundary properly BOOL ChdrawDoc::FunnyOnWritePoly() { FILE *fp; int i,j,k,l,t,n,n0,n1,n2; double z,R,dL; CComplex a0,a1,a2,c; CComplex b0,b1,b2; char instring[1024]; CString s; CArray< CNode, CNode&> nodelst; CArray< CSegment, CSegment&> linelst; CArray< CArcSegment, CArcSegment&> arclst; CArray< CBlockLabel, CBlockLabel&> blocklst; CArray< CPeriodicBoundary, CPeriodicBoundary&> pbclst; CArray< CCommonPoint, CCommonPoint& >ptlst; CNode node; CSegment segm; CPeriodicBoundary pbc; CCommonPoint pt; nodelst.RemoveAll(); linelst.RemoveAll(); pbclst.RemoveAll(); ptlst.RemoveAll(); UpdateUndo(); // calculate length used to kludge fine meshing near input node points for (i=0,z=0;i<linelist.GetSize();i++) { a0.Set(nodelist[linelist[i].n0].x,nodelist[linelist[i].n0].y); a1.Set(nodelist[linelist[i].n1].x,nodelist[linelist[i].n1].y); z += (abs(a1-a0)/((double) linelist.GetSize())); } dL=z/LineFraction; // copy node list as it is; for(i=0;i<nodelist.GetSize();i++) nodelst.Add(nodelist[i]); // discretize input segments for(i=0;i<linelist.GetSize();i++) { // abuse the IsSelected flag to carry a notation // of which line or arc in the input geometry a // particular segment is associated with segm=linelist[i]; segm.IsSelected=i; a0.Set(nodelist[linelist[i].n0].x,nodelist[linelist[i].n0].y); a1.Set(nodelist[linelist[i].n1].x,nodelist[linelist[i].n1].y); if (linelist[i].MaxSideLength==-1) k=1; else{ z=abs(a1-a0); k=(int) ceil(z/linelist[i].MaxSideLength); } if (k==1) // default condition where discretization on line is not specified { if ((abs(a1-a0)<(3.*dL)) || (!theApp.d_SmartMesh)) linelst.Add(segm); // line is too short to add extra points else{ // add extra points at a distance of dL from the ends of the line. // this forces Triangle to finely mesh near corners for(j=0;j<3;j++) { if(j==0) { a2=a0+dL*(a1-a0)/abs(a1-a0); node.x=a2.re; node.y=a2.im; l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=linelist[i].n0; segm.n1=l; linelst.Add(segm); } if(j==1) { a2=a1+dL*(a0-a1)/abs(a1-a0); node.x=a2.re; node.y=a2.im; l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=l-1; segm.n1=l; linelst.Add(segm); } if(j==2) { l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=linelist[i].n1; linelst.Add(segm); } } } } else{ for(j=0;j<k;j++) { a2=a0+(a1-a0)*((double) (j+1))/((double) k); node.x=a2.re; node.y=a2.im; if(j==0){ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=linelist[i].n0; segm.n1=l; linelst.Add(segm); } else if(j==(k-1)) { l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=linelist[i].n1; linelst.Add(segm); } else{ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=l-1; segm.n1=l; linelst.Add(segm); } } } } // discretize input arc segments for(i=0;i<arclist.GetSize();i++) { segm.IsSelected=i+(int) linelist.GetSize(); a2.Set(nodelist[arclist[i].n0].x,nodelist[arclist[i].n0].y); k=(int) ceil(arclist[i].ArcLength/arclist[i].MaxSideLength); segm.BoundaryMarker=arclist[i].BoundaryMarker; segm.InConductor=arclist[i].InConductor; GetCircle(arclist[i],c,R); a1=exp(I*arclist[i].ArcLength*PI/(((double) k)*180.)); if(k==1){ segm.n0=arclist[i].n0; segm.n1=arclist[i].n1; linelst.Add(segm); } else for(j=0;j<k;j++) { a2=(a2-c)*a1+c; node.x=a2.re; node.y=a2.im; if(j==0){ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=arclist[i].n0; segm.n1=l; linelst.Add(segm); } else if(j==(k-1)) { l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=arclist[i].n1; linelst.Add(segm); } else{ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=l-1; segm.n1=l; linelst.Add(segm); } } } // create correct output filename; CString pn = GetPathName(); CString plyname=pn.Left(pn.ReverseFind('.')) + ".poly"; // check to see if we are ready to write a datafile; if ((fp=fopen(plyname,"wt"))==NULL){ MsgBox("Couldn't write to specified .poly file"); Undo(); UnselectAll(); return FALSE; } // write out node list fprintf(fp,"%i 2 0 1\n",nodelst.GetSize()); for(i=0;i<nodelst.GetSize();i++) { fprintf(fp,"%i %.17g %.17g %i\n", i,nodelst[i].x,nodelst[i].y,0); } // write out segment list fprintf(fp,"%i 1\n",linelst.GetSize()); for(i=0;i<linelst.GetSize();i++) { t=-(linelst[i].IsSelected+2); fprintf(fp,"%i %i %i %i\n",i,linelst[i].n0,linelst[i].n1,t); } // write out list of holes; for(i=0,j=0;i<blocklist.GetSize();i++) if(blocklist[i].BlockType=="<No Mesh>") j++; fprintf(fp,"%i\n",j); for(i=0,k=0;i<blocklist.GetSize();i++) if(blocklist[i].BlockType=="<No Mesh>") { fprintf(fp,"%i %.17g %.17g\n",k,blocklist[i].x,blocklist[i].y); k++; } // figure out a good default mesh size for block labels where // mesh size isn't explicitly specified CComplex xx,yy; double DefaultMeshSize; if (nodelst.GetSize()>1) { xx=nodelst[0].CC(); yy=xx; for(k=0;k<nodelst.GetSize();k++) { if (nodelst[k].x<Re(xx)) xx.re=nodelst[k].x; if (nodelst[k].y<Im(xx)) xx.im=nodelst[k].y; if (nodelst[k].x>Re(yy)) yy.re=nodelst[k].x; if (nodelst[k].y>Im(yy)) yy.im=nodelst[k].y; } DefaultMeshSize=pow((double)(abs(yy - xx) / BoundingBoxFraction), (double)2); if (!theApp.d_SmartMesh) DefaultMeshSize=abs(yy-xx); } else DefaultMeshSize=-1; // write out regional attributes fprintf(fp,"%i\n",blocklist.GetSize()-j); for(i=0,k=0;i<blocklist.GetSize();i++) if(blocklist[i].BlockType!="<No Mesh>") { fprintf(fp,"%i %.17g %.17g ",k,blocklist[i].x,blocklist[i].y); fprintf(fp,"%i ",k+1); if ((blocklist[i].MaxArea>0) && (blocklist[i].MaxArea<DefaultMeshSize)) fprintf(fp,"%.17g\n",blocklist[i].MaxArea); else fprintf(fp,"%.17g\n",DefaultMeshSize); k++; } fclose(fp); //call triangle CString rootname="\"" + pn.Left(pn.ReverseFind('.')) + "\""; char CommandLine[512]; sprintf(CommandLine,"\"%striangle.exe\" -p -P -q%f -e -A -a -z -Q -I %s", BinDir,MinAngle,rootname); STARTUPINFO StartupInfo = {0}; PROCESS_INFORMATION ProcessInfo; StartupInfo.cb = sizeof(STARTUPINFO); StartupInfo.dwFlags = STARTF_USESHOWWINDOW; StartupInfo.wShowWindow = SW_SHOWNOACTIVATE|SW_MINIMIZE; if (CreateProcess(NULL,CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)){ if(bLinehook==FALSE) WaitForSingleObject(ProcessInfo.hProcess, INFINITE); else{ DWORD ExitCode; hProc=ProcessInfo.hProcess; do{ GetExitCodeProcess(ProcessInfo.hProcess,&ExitCode); ((CFemmApp *)AfxGetApp())->line_hook(lua,NULL); Sleep(1); } while(ExitCode==STILL_ACTIVE); hProc=NULL; } } else { MsgBox("Couldn't spawn triangle.exe"); Undo(); UnselectAll(); return FALSE; } DWORD ExitCode; GetExitCodeProcess( ProcessInfo.hProcess, // handle to the process &ExitCode // address to receive termination status ); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); if (ExitCode!=0) { MsgBox("Call to triangle was unsuccessful"); Undo(); UnselectAll(); return FALSE; } //#endif // So far, so good. Now, read back in the .edge file // to make sure the points in the segments and arc // segments are ordered in a consistent way so that // the (anti)periodic boundary conditions can be applied. //read meshlines; plyname=pn.Left(pn.ReverseFind('.')) + ".edge"; if((fp=fopen(plyname,"rt"))==NULL){ MsgBox("Call to triangle was unsuccessful"); Undo(); UnselectAll(); return FALSE; } fgets(instring,1024,fp); sscanf(instring,"%i",&k); UnselectAll(); // abuse IsSelected again to keep a // tally of how many subsegments each // entity is sliced into. ptlst.SetSize(linelist.GetSize()+arclist.GetSize()); for(i=0;i<ptlst.GetSize();i++) ptlst[i].t=0; for(i=0;i<k;i++) { fgets(instring,1024,fp); sscanf(instring,"%i %i %i %i",&l,&n0,&n1,&j); if(j!=0) { j=-(j+2); // convert back to the `right' numbering // store a reference line that we can use to // determine whether or not this is a // boundary segment w/out re-running triangle. if (ptlst[j].t==0) { ptlst[j].t=1; if(n0<n1){ ptlst[j].x=n0; ptlst[j].y=n1; } else{ ptlst[j].x=n1; ptlst[j].y=n0; } } if(j<linelist.GetSize()) { // deal with segments linelist[j].IsSelected++; if((linelist[j].n0==n1) || (linelist[j].n1==n0)) { t=linelist[j].n0; linelist[j].n0=linelist[j].n1; linelist[j].n1=t; } } else{ // deal with arc segments; // Can't just flip the point order with // impunity in the arc segments, so we flip // a marker which denotes which side the // normal is on. j=j-(int) linelist.GetSize(); arclist[j].IsSelected++; if((arclist[j].n0==n1) || (arclist[j].n1==n0)) arclist[j].NormalDirection=FALSE; if((arclist[j].n0==n0) || (arclist[j].n1==n1)) arclist[j].NormalDirection=TRUE; } } } fclose(fp); // figure out which segments / arcsegments are on the // boundary and force an appropriate mesh density on // these based on how many divisions are in the first // trial meshing of the domain. // paw through the element list to find out how many // elements each reference segment appears in. If a // segment is on the boundary, it ought to appear in just // one element. Otherwise, it appears in two. plyname=pn.Left(pn.ReverseFind('.')) + ".ele"; if((fp=fopen(plyname,"rt"))==NULL){ MsgBox("Call to triangle was unsuccessful"); Undo(); UnselectAll(); return FALSE; } fgets(instring,1024,fp); sscanf(instring,"%i",&k); for(i=0;i<k;i++) { fgets(instring,1024,fp); sscanf(instring,"%i %i %i %i",&j,&n0,&n1,&n2); // Sort out the three nodes... if (n0>n1) { n=n0; n0=n1; n1=n; } if (n1>n2) { n=n1; n1=n2; n2=n; } if (n0>n1) { n=n0; n0=n1; n1=n; } // now, check to see if any of the test segments // are sides of this node... for(j=0;j<ptlst.GetSize();j++) { if ((n0==ptlst[j].x) && (n1==ptlst[j].y)) ptlst[j].t--; if ((n0==ptlst[j].x) && (n2==ptlst[j].y)) ptlst[j].t--; if ((n1==ptlst[j].x) && (n2==ptlst[j].y)) ptlst[j].t--; } } fclose(fp); // impose "new" mesh constraints on bdry arcs and segments.... for(i=0;i<linelist.GetSize();i++) { if (ptlst[i].t==0) linelist[i].MaxSideLength= LineLength(i)/((double) linelist[i].IsSelected); } for(i=0;i<arclist.GetSize();i++) { if (ptlst[i+linelist.GetSize()].t==0){ // alter maxsidelength, but do it in such // a way that it carries only 4 significant // digits. There's no use in carrying double // precision here, because it looks crappy // when you open up the arc segment to see // its properties. char kludge[32]; arclist[i].MaxSideLength= arclist[i].ArcLength/((double) arclist[i].IsSelected); sprintf(kludge,"%.1e",arclist[i].MaxSideLength); sscanf(kludge,"%lf",&arclist[i].MaxSideLength); } } ptlst.RemoveAll(); // want to impose explicit discretization only on // the boundary arcs and segments. After the meshing // is done, spacing on boundary segments should be // restored to the value that was there before meshing // was called, but the arc segments should keep the // "new" MaxSideLength--this is used in other places // and must always be consistent with the the mesh. // Now, do a shitload of checking to make sure that // the PBCs haven't been defined by the user // in a messed up way. // First, search through defined bc's for periodic ones; for(i=0;i<lineproplist.GetSize();i++) { if ((lineproplist[i].BdryFormat==4) || (lineproplist[i].BdryFormat==5)){ pbc.BdryName=lineproplist[i].BdryName; pbc.BdryFormat=lineproplist[i].BdryFormat-4; // 0 for pbc, 1 for apbc pbclst.Add(pbc); } } for(i=0;i<linelist.GetSize();i++) { for(j=0;j<pbclst.GetSize();j++) { if (pbclst[j].BdryName==linelist[i].BoundaryMarker) { // A pbc or apbc can only be applied to 2 segs // at a time. If it is applied to multiple segs // at the same time, flag it and kick it out. if (pbclst[j].nseg==2) { MsgBox("An (anti)periodic BC is assigned to more than two segments"); Undo(); UnselectAll(); return FALSE; } pbclst[j].seg[pbclst[j].nseg]=i; pbclst[j].nseg++; } } } for(i=0;i<arclist.GetSize();i++) { for(j=0;j<pbclst.GetSize();j++) { if (pbclst[j].BdryName==arclist[i].BoundaryMarker) { // A pbc or apbc can only be applied to 2 arcs // at a time. If it is applied to multiple arcs // at the same time, flag it and kick it out. if (pbclst[j].narc==2) { MsgBox("An (anti)periodic BC is assigned to more than two arcs"); Undo(); UnselectAll(); return FALSE; } pbclst[j].seg[pbclst[j].narc]=i; pbclst[j].narc++; } } } j=0; while(j<pbclst.GetSize()) { // check for a bc that is a mix of arcs and segments. // this is an error, and it should get flagged. if ((pbclst[j].nseg>0) && (pbclst[j].narc>0)) { MsgBox("Can't mix arcs and segments for (anti)periodic BCs"); Undo(); UnselectAll(); return FALSE; } // remove any periodic BC's that aren't actually in play if((pbclst[j].nseg<2) && (pbclst[j].narc<2)) pbclst.RemoveAt(j); else j++; } for(j=0;j<pbclst.GetSize();j++) { // check to see if adjoining entries are applied // to objects of compatible size/shape, and // reconcile meshing on the objects. // for segments: if(pbclst[j].nseg>0){ // make sure that lines are pretty much the same length if(fabs(LineLength(pbclst[j].seg[0]) -LineLength(pbclst[j].seg[1]))>1.e-06) { MsgBox("(anti)periodic BCs applied to dissimilar segments"); Undo(); UnselectAll(); return FALSE; } // make sure that both lines have the same spacing double len1,len2,len; len1=linelist[pbclst[j].seg[0]].MaxSideLength; len2=linelist[pbclst[j].seg[1]].MaxSideLength; if(len1<=0) len1=len2; if(len2<=0) len2=len1; len=min(len1,len2); linelist[pbclst[j].seg[0]].MaxSideLength=len; linelist[pbclst[j].seg[1]].MaxSideLength=len; } // for arc segments: if(pbclst[j].narc>0){ // make sure that arcs are pretty much the // same arc length if(fabs(arclist[pbclst[j].seg[0]].ArcLength -arclist[pbclst[j].seg[1]].ArcLength)>1.e-06) { MsgBox("(anti)periodic BCs applied to dissimilar arc segments"); Undo(); UnselectAll(); return FALSE; } // make sure that both lines have the same spacing double len1,len2,len; len1=arclist[pbclst[j].seg[0]].MaxSideLength; len2=arclist[pbclst[j].seg[1]].MaxSideLength; len=min(len1,len2); arclist[pbclst[j].seg[0]].MaxSideLength=len; arclist[pbclst[j].seg[1]].MaxSideLength=len; } } // write out new poly and write out adjacent // boundary nodes in a separate .pbc file. // kludge things a bit and use IsSelected to denote // whether or not a line or arc has already been processed. UnselectAll(); nodelst.RemoveAll(); linelst.RemoveAll(); // first, add in existing nodes for(n=0;n<nodelist.GetSize();n++) nodelst.Add(nodelist[n]); for(n=0;n<pbclst.GetSize();n++) { if (pbclst[n].nseg!=0) // if this pbc is a line segment... { int s0,s1; CNode node0,node1; s0=pbclst[n].seg[0]; s1=pbclst[n].seg[1]; linelist[s0].IsSelected=TRUE; linelist[s1].IsSelected=TRUE; // make is so that first point on first line // maps to first point on second line... t=linelist[s1].n1; linelist[s1].n1=linelist[s1].n0; linelist[s1].n0=t; // store number of sub-segments in k if (linelist[s0].MaxSideLength==-1) k=1; else{ a0=nodelist[linelist[s0].n0].CC(); a1=nodelist[linelist[s0].n1].CC(); b0=nodelist[linelist[s1].n0].CC(); b1=nodelist[linelist[s1].n1].CC(); z=abs(a1-a0); k=(int) ceil(z/linelist[s0].MaxSideLength); } // add segment end points to the list; pt.x=linelist[s0].n0; pt.y=linelist[s1].n0; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); pt.x=linelist[s0].n1; pt.y=linelist[s1].n1; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); if (k==1){ // catch the case in which the line // doesn't get subdivided. linelst.Add(linelist[s0]); linelst.Add(linelist[s1]); } else{ segm=linelist[s0]; for(j=0;j<k;j++) { a2=a0+(a1-a0)*((double) (j+1))/((double) k); b2=b0+(b1-b0)*((double) (j+1))/((double) k); node0.x=a2.re; node0.y=a2.im; node1.x=b2.re; node1.y=b2.im; if(j==0){ l=(int) nodelst.GetSize(); nodelst.Add(node0); segm.n0=linelist[s0].n0; segm.n1=l; linelst.Add(segm); pt.x=l; l=(int) nodelst.GetSize(); nodelst.Add(node1); segm.n0=linelist[s1].n0; segm.n1=l; linelst.Add(segm); pt.y=l; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); } else if(j==(k-1)) { // last subdivision--no ptlst // entry associated with this one. l=(int) nodelst.GetSize()-2; segm.n0=l; segm.n1=linelist[s0].n1; linelst.Add(segm); l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=linelist[s1].n1; linelst.Add(segm); } else{ l=(int) nodelst.GetSize(); nodelst.Add(node0); nodelst.Add(node1); segm.n0=l-2; segm.n1=l; linelst.Add(segm); segm.n0=l-1; segm.n1=l+1; linelst.Add(segm); pt.x=l; pt.y=l+1; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); } } } } else{ // if this pbc is an arc segment... int s0,s1; int p0[2],p1[2]; CNode node0,node1; CComplex bgn0,bgn1,c0,c1,d0,d1; double r0,r1; s0=pbclst[n].seg[0]; s1=pbclst[n].seg[1]; arclist[s0].IsSelected=TRUE; arclist[s1].IsSelected=TRUE; k=(int) ceil(arclist[s0].ArcLength/arclist[s0].MaxSideLength); segm.BoundaryMarker=arclist[s0].BoundaryMarker; segm.InConductor=arclist[s0].InConductor; GetCircle(arclist[s0],c0,r0); GetCircle(arclist[s1],c1,r1); if (arclist[s0].NormalDirection==0){ bgn0=nodelist[arclist[s0].n0].CC(); d0=exp(I*arclist[s0].ArcLength*PI/(((double) k)*180.)); p0[0]=arclist[s0].n0; p0[1]=arclist[s0].n1; } else{ bgn0=nodelist[arclist[s0].n1].CC(); d0=exp(-I*arclist[s0].ArcLength*PI/(((double) k)*180.)); p0[0]=arclist[s0].n1; p0[1]=arclist[s0].n0; } if (arclist[s1].NormalDirection!=0){ bgn1=nodelist[arclist[s1].n0].CC(); d1=exp(I*arclist[s1].ArcLength*PI/(((double) k)*180.)); p1[0]=arclist[s1].n0; p1[1]=arclist[s1].n1; } else{ bgn1=nodelist[arclist[s1].n1].CC(); d1=exp(-I*arclist[s1].ArcLength*PI/(((double) k)*180.)); p1[0]=arclist[s1].n1; p1[1]=arclist[s1].n0; } // add arc segment end points to the list; pt.x=p0[0]; pt.y=p1[0]; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); pt.x=p0[1]; pt.y=p1[1]; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); if (k==1){ // catch the case in which the line // doesn't get subdivided. segm.n0=p0[0]; segm.n1=p0[1]; linelst.Add(segm); segm.n0=p1[0]; segm.n1=p1[1]; linelst.Add(segm); } else{ for(j=0;j<k;j++) { bgn0=(bgn0-c0)*d0+c0; node0.x=bgn0.re; node0.y=bgn0.im; bgn1=(bgn1-c1)*d1+c1; node1.x=bgn1.re; node1.y=bgn1.im; if(j==0){ l=(int) nodelst.GetSize(); nodelst.Add(node0); segm.n0=p0[0]; segm.n1=l; linelst.Add(segm); pt.x=l; l=(int) nodelst.GetSize(); nodelst.Add(node1); segm.n0=p1[0]; segm.n1=l; linelst.Add(segm); pt.y=l; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); } else if(j==(k-1)) { // last subdivision--no ptlst // entry associated with this one. l=(int) nodelst.GetSize()-2; segm.n0=l; segm.n1=p0[1]; linelst.Add(segm); l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=p1[1]; linelst.Add(segm); } else{ l=(int) nodelst.GetSize(); nodelst.Add(node0); nodelst.Add(node1); segm.n0=l-2; segm.n1=l; linelst.Add(segm); segm.n0=l-1; segm.n1=l+1; linelst.Add(segm); pt.x=l; pt.y=l+1; pt.t=pbclst[n].BdryFormat; ptlst.Add(pt); } } } } } // Then, do the rest of the lines and arcs in the // "normal" way and write .poly file. // discretize input segments for(i=0;i<linelist.GetSize();i++) if(linelist[i].IsSelected==FALSE){ a0.Set(nodelist[linelist[i].n0].x,nodelist[linelist[i].n0].y); a1.Set(nodelist[linelist[i].n1].x,nodelist[linelist[i].n1].y); if (linelist[i].MaxSideLength==-1) k=1; else{ z=abs(a1-a0); k=(int) ceil(z/linelist[i].MaxSideLength); } segm=linelist[i]; if (k==1) // default condition where discretization on line is not specified { if ((abs(a1-a0)<(3.*dL)) || (!theApp.d_SmartMesh)) linelst.Add(segm); // line is too short to add extra points else{ // add extra points at a distance of dL from the ends of the line. // this forces Triangle to finely mesh near corners for(j=0;j<3;j++) { if(j==0) { a2=a0+dL*(a1-a0)/abs(a1-a0); node.x=a2.re; node.y=a2.im; l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=linelist[i].n0; segm.n1=l; linelst.Add(segm); } if(j==1) { a2=a1+dL*(a0-a1)/abs(a1-a0); node.x=a2.re; node.y=a2.im; l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=l-1; segm.n1=l; linelst.Add(segm); } if(j==2) { l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=linelist[i].n1; linelst.Add(segm); } } } } else{ for(j=0;j<k;j++) { a2=a0+(a1-a0)*((double) (j+1))/((double) k); node.x=a2.re; node.y=a2.im; if(j==0){ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=linelist[i].n0; segm.n1=l; linelst.Add(segm); } else if(j==(k-1)) { l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=linelist[i].n1; linelst.Add(segm); } else{ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=l-1; segm.n1=l; linelst.Add(segm); } } } } // discretize input arc segments for(i=0;i<arclist.GetSize();i++) if(arclist[i].IsSelected==FALSE){ a2.Set(nodelist[arclist[i].n0].x,nodelist[arclist[i].n0].y); k=(int) ceil(arclist[i].ArcLength/arclist[i].MaxSideLength); segm.BoundaryMarker=arclist[i].BoundaryMarker; segm.InConductor =arclist[i].InConductor; GetCircle(arclist[i],c,R); a1=exp(I*arclist[i].ArcLength*PI/(((double) k)*180.)); if(k==1){ segm.n0=arclist[i].n0; segm.n1=arclist[i].n1; linelst.Add(segm); } else for(j=0;j<k;j++) { a2=(a2-c)*a1+c; node.x=a2.re; node.y=a2.im; if(j==0){ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=arclist[i].n0; segm.n1=l; linelst.Add(segm); } else if(j==(k-1)) { l=(int) nodelst.GetSize()-1; segm.n0=l; segm.n1=arclist[i].n1; linelst.Add(segm); } else{ l=(int) nodelst.GetSize(); nodelst.Add(node); segm.n0=l-1; segm.n1=l; linelst.Add(segm); } } } // create correct output filename; pn = GetPathName(); plyname=pn.Left(pn.ReverseFind('.')) + ".poly"; // check to see if we are ready to write a datafile; if ((fp=fopen(plyname,"wt"))==NULL){ MsgBox("Couldn't write to specified .poly file"); Undo(); UnselectAll(); return FALSE; } // write out node list fprintf(fp,"%i 2 0 1\n",nodelst.GetSize()); for(i=0;i<nodelst.GetSize();i++) { // include boundary marker; for(j=0,t=0;j<nodeproplist.GetSize();j++) if(nodeproplist[j].PointName==nodelst[i].BoundaryMarker) t=j+2; // include conductor number; for(j=0;j<circproplist.GetSize();j++) if(circproplist[j].CircName==nodelst[i].InConductor) t+=((j+1)*0x10000); fprintf(fp,"%i %.17g %.17g %i\n",i,nodelst[i].x,nodelst[i].y,t); } // write out segment list fprintf(fp,"%i 1\n",linelst.GetSize()); for(i=0;i<linelst.GetSize();i++) { // include boundary marker; for(j=0,t=0;j<lineproplist.GetSize();j++) if(lineproplist[j].BdryName==linelst[i].BoundaryMarker) t=-(j+2); // include conductor number; for(j=0;j<circproplist.GetSize();j++) if(circproplist[j].CircName==linelst[i].InConductor) t-=((j+1)*0x10000); fprintf(fp,"%i %i %i %i\n",i,linelst[i].n0,linelst[i].n1,t); } // write out list of holes; for(i=0,j=0;i<blocklist.GetSize();i++) if(blocklist[i].BlockType=="<No Mesh>") j++; fprintf(fp,"%i\n",j); for(i=0,k=0;i<blocklist.GetSize();i++) if(blocklist[i].BlockType=="<No Mesh>") { fprintf(fp,"%i %.17g %.17g\n",k,blocklist[i].x,blocklist[i].y); k++; } // write out regional attributes fprintf(fp,"%i\n",blocklist.GetSize()-j); for(i=0,k=0;i<blocklist.GetSize();i++) if(blocklist[i].BlockType!="<No Mesh>") { fprintf(fp,"%i %.17g %.17g ",k,blocklist[i].x,blocklist[i].y); fprintf(fp,"%i ",k+1); if ((blocklist[i].MaxArea>0) && (blocklist[i].MaxArea<DefaultMeshSize)) fprintf(fp,"%.17g\n",blocklist[i].MaxArea); else fprintf(fp,"%.17g\n",DefaultMeshSize); k++; } fclose(fp); // Make sure to prune out any duplications in the ptlst for(k=0;k<ptlst.GetSize();k++) ptlst[k].Order(); k=0; while((k+1) < ptlst.GetSize()) { j=k+1; while(j < ptlst.GetSize()) { if((ptlst[k].x==ptlst[j].x) && (ptlst[k].y==ptlst[j].y)) ptlst.RemoveAt(j); else j++; } k++; } // used to have a check to eliminate the case where a point // and its companion are the same point--actually, this shouldn't // be a problem just to let the algorithm deal with this // as usual. // One last error check--each point must have only one companion point. // however, it would be possible to screw up in the definition of the BCs // so that this isn't the case. Look through the points to try and catch // this one. /* // let's let this check go away for a minute... for(k=0,n=FALSE;(k+1)<ptlst.GetSize();k++) { for(j=k+1;j<ptlst.GetSize();j++) { if(ptlst[k].x==ptlst[j].x) n=TRUE; if(ptlst[k].y==ptlst[j].y) n=TRUE; if(ptlst[k].x==ptlst[j].y) n=TRUE; if(ptlst[k].y==ptlst[j].x) n=TRUE; } } if (n==TRUE){ MsgBox("Nonphysical (anti)periodic boundary assignments"); Undo(); UnselectAll(); return FALSE; } */ // write out a pbc file containing a list of linked nodes plyname=pn.Left(pn.ReverseFind('.')) + ".pbc"; if ((fp=fopen(plyname,"wt"))==NULL){ MsgBox("Couldn't write to specified .pbc file"); Undo(); UnselectAll(); return FALSE; } fprintf(fp,"%i\n",ptlst.GetSize()); for(k=0;k<ptlst.GetSize();k++) fprintf(fp,"%i %i %i %i\n",k,ptlst[k].x,ptlst[k].y,ptlst[k].t); fclose(fp); // call triangle with -Y flag. rootname="\"" + pn.Left(pn.ReverseFind('.')) + "\""; sprintf(CommandLine,"\"%striangle.exe\" -p -P -q%f -e -A -a -z -Q -I -Y %s", BinDir,MinAngle,rootname); StartupInfo.cb = sizeof(STARTUPINFO); StartupInfo.dwFlags = STARTF_USESHOWWINDOW; StartupInfo.wShowWindow = SW_SHOWNOACTIVATE|SW_MINIMIZE; if (CreateProcess(NULL,CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)){ if(bLinehook==FALSE) WaitForSingleObject(ProcessInfo.hProcess, INFINITE); else{ DWORD ExitCode; hProc=ProcessInfo.hProcess; do{ GetExitCodeProcess(ProcessInfo.hProcess,&ExitCode); ((CFemmApp *)AfxGetApp())->line_hook(lua,NULL); Sleep(1); } while(ExitCode==STILL_ACTIVE); hProc=NULL; } } else { MsgBox("Couldn't spawn triangle.exe"); Undo(); UnselectAll(); return FALSE; } GetExitCodeProcess( ProcessInfo.hProcess, // handle to the process &ExitCode // address to receive termination status ); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); if (ExitCode!=0) { MsgBox("Call to triangle was unsuccessful"); Undo(); UnselectAll(); return FALSE; } UnselectAll(); // Now restore boundary segment discretizations that have // been mucked up in the process... for(i=0;i<linelist.GetSize();i++) linelist[i]=undolinelist[i]; // and save the latest version of the document to make sure // any changes to arc discretization get propagated into // the solution description.... OnSaveDocument(pn); return TRUE; }